// Spludlow Software // Copyright © Samuel P. Ludlow 2020 All Rights Reserved // Distributed under the terms of the GNU General Public License version 3 // Distributed WITHOUT ANY WARRANTY; without implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE // https://www.spludlow.co.uk/LICENCE.TXT // The Spludlow logo is a registered trademark of Samuel P. Ludlow and may not be used without permission // v1.14 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Data; using System.Management; using System.DirectoryServices; using System.DirectoryServices.ActiveDirectory; namespace Spludlow { public static class ManagementObjects { private static Dictionary CimTypeLookup; static ManagementObjects() { CimTypeLookup = new Dictionary(); string[] typeLookupText = new string[] { "SInt16 Int16", "SInt32 Int32", "Real32 Single", "Real64 Double", "String String", "Boolean Boolean", "Object Object", "SInt8 SByte", "UInt8 Byte", "UInt16 UInt16", "UInt32 UInt32", "SInt64 Int64", "UInt64 UInt64", "DateTime DateTime", "Reference Int16", "Char16 Char", }; foreach (string line in typeLookupText) { string[] parts = Spludlow.Text.Split(line, '\t', true); CimTypeLookup.Add((CimType)Enum.Parse(typeof(CimType), parts[0]), Type.GetType("System." + parts[1])); } } public static string[] UsefulClasses = new string[] { "Win32_ComputerSystem", "Win32_Processor", "Win32_OperatingSystem", "Win32_DiskDrive", "Win32_DiskPartition", "Win32_LogicalDisk", "Win32_Process" }; // "Win32_Service" Access Denied public static DataSet Query() { return Query(UsefulClasses); } public static DataSet Query(string host) { return Query(host, UsefulClasses, false); } public static DataSet Query(string[] manObjClasses) { return Query(null, manObjClasses, false); } public static DataSet Query(string host, string[] manObjClasses, bool swivelTable) { ManagementScope managementScope = null; if (host != null) { throw new ApplicationException("ManagementObjects, Query; Remote host not supported. Never got this working, down to DCOM permissions I belive. Wanted to make it work to a host not runnig Spludlow Framework"); //ManagementPath managementPath = new ManagementPath(); //managementPath.NamespacePath = @"root\cimv2"; //managementPath.Server = host; //managementScope = new ManagementScope(managementPath); //managementScope.Options.EnablePrivileges = true; //managementScope.Options.Impersonation = ImpersonationLevel.Impersonate; //managementScope.Options.Username = ""; //managementScope.Options.Password = ""; //managementScope.Options.Authority = "ntdlmdomain:" + "domain"; //managementScope = new ManagementScope("\\\\" + host + "\\root\\cimv2"); //managementScope.Options.EnablePrivileges = true; //managementScope.Options.Impersonation = ImpersonationLevel.Impersonate; //managementScope.Connect(); } DataSet dataSet = new DataSet(); DataTable typeTable = Spludlow.Data.TextTable.ReadText(new string[] { "Class Property TypeName", "String* String* String", }); typeTable.TableName = "DataTypes"; dataSet.Tables.Add(typeTable); foreach (string manObjClass in manObjClasses) { ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM " + manObjClass); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, objectQuery)) { using (ManagementObjectCollection results = searcher.Get()) { DataTable resultsTable = new DataTable(manObjClass); foreach (ManagementObject resultObject in results) { foreach (PropertyData prop in resultObject.Properties) { DataRow typeRow = typeTable.Rows.Find(new object[] { manObjClass, prop.Name }); if (typeRow == null) { string propTypeName = Enum.GetName(typeof(CimType), prop.Type); typeTable.Rows.Add(manObjClass, prop.Name, propTypeName); resultsTable.Columns.Add(prop.Name, typeof(string)); } } } foreach (ManagementObject resultObject in results) { DataRow row = resultsTable.NewRow(); foreach (PropertyData prop in resultObject.Properties) { if (prop.Value != null) row[prop.Name] = prop.Value.ToString(); } resultsTable.Rows.Add(row); } if (swivelTable == true) resultsTable = Spludlow.Data.ADO.Swivel(resultsTable); dataSet.Tables.Add(resultsTable); } } } return dataSet; } public static string[] ListCimTypes() { return Enum.GetNames(typeof(CimType)); } public static DataSet TypedQuery(string host, string[] manObjClasses, bool swivelTable) { ManagementScope managementScope = null; if (host != null) { throw new ApplicationException("ManagementObjects, Query; Remote host not supported. Never got this working, down to DCOM permissions I belive. Wanted to make it work to a host not runnig Spludlow Framework"); //ManagementPath managementPath = new ManagementPath(); //managementPath.NamespacePath = @"root\cimv2"; //managementPath.Server = host; //managementScope = new ManagementScope(managementPath); //managementScope.Options.EnablePrivileges = true; //managementScope.Options.Impersonation = ImpersonationLevel.Impersonate; //managementScope.Options.Username = ""; //managementScope.Options.Password = ""; //managementScope.Options.Authority = "ntdlmdomain:" + "domain"; //managementScope = new ManagementScope("\\\\" + host + "\\root\\cimv2"); //managementScope.Options.EnablePrivileges = true; //managementScope.Options.Impersonation = ImpersonationLevel.Impersonate; //managementScope.Connect(); } DataSet dataSet = new DataSet(); DataTable typeTable = Spludlow.Data.TextTable.ReadText(new string[] { "Class Property TypeName Type", "String* String* String Type", }); typeTable.TableName = "DataTypes"; dataSet.Tables.Add(typeTable); foreach (string manObjClass in manObjClasses) { ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM " + manObjClass); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, objectQuery)) { using (ManagementObjectCollection results = searcher.Get()) { // First pass to get schema foreach (ManagementObject resultObject in results) { foreach (PropertyData prop in resultObject.Properties) { DataRow typeRow = typeTable.Rows.Find(new object[] { manObjClass, prop.Name }); if (typeRow == null && prop.Value != null) { Type type = prop.Value.GetType(); typeTable.Rows.Add(manObjClass, prop.Name, type.Name, type); } } } // Make results table DataTable resultsTable = new DataTable(manObjClass); foreach (DataRow typeRow in typeTable.Select("Class = '" + manObjClass + "'")) resultsTable.Columns.Add((string)typeRow["Property"], (Type)typeRow["Type"]); // Second passs to get data foreach (ManagementObject resultObject in results) { DataRow row = resultsTable.NewRow(); foreach (PropertyData prop in resultObject.Properties) { if (prop.Value != null) row[prop.Name] = prop.Value; } resultsTable.Rows.Add(row); resultObject.Dispose(); } if (swivelTable == true) resultsTable = Spludlow.Data.ADO.Swivel(resultsTable); dataSet.Tables.Add(resultsTable); } } } return dataSet; } public static object[][] Query(string manObjClass, string[] propertyNames) { return Query(manObjClass, propertyNames, null); } public static object[][] Query(string manObjClass, string[] propertyNames, string where) { StringBuilder command = new StringBuilder(); foreach (string propertyName in propertyNames) { if (command.Length != 0) command.Append(", "); command.Append(propertyName); } command.Insert(0, "SELECT "); command.Append(" FROM "); command.Append(manObjClass); if (where != null) { command.Append(" WHERE ("); command.Append(where); command.Append(")"); } string commandText = command.ToString(); List results = new List(); ObjectQuery objectQuery = new ObjectQuery(commandText); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(objectQuery)) { using (ManagementObjectCollection managementResults = searcher.Get()) { foreach (ManagementObject resultObject in managementResults) { object[] result = new object[propertyNames.Length]; for (int index = 0; index < result.Length; ++index) result[index] = resultObject[propertyNames[index]]; results.Add(result); resultObject.Dispose(); } } } return results.ToArray(); } public static object[] Query(string manObjClass, string propertyName) { List results = new List(); string commandText = "SELECT " + propertyName + " FROM " + manObjClass; ObjectQuery objectQuery = new ObjectQuery(commandText); using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(objectQuery)) { using (ManagementObjectCollection managementResults = searcher.Get()) { if (managementResults.Count == 0) throw new ApplicationException("ManagementObject Query; No rows found:\t" + commandText); foreach (ManagementObject resultObject in managementResults) { results.Add(resultObject[propertyName]); resultObject.Dispose(); } } } return results.ToArray(); } // From Win32_ComputerSystem // In a Workgroup; domain will also be set. Workgroup=WORKGROUP Domain=WORKGROUP // In a Domain; workgroup will be null. Workgroup=NULL Domain=dnsformat.domainname // These 2 methods will return null for whatever it's not in, and use the NetBIOS format for the domain name public static string SystemWorkgroup() { return (string)Spludlow.ManagementObjects.Query("Win32_ComputerSystem", "Workgroup")[0]; } public static string SystemDomain() { string dnsDomain = SystemDnsDomain(); if (dnsDomain == null) return null; return Spludlow.ManagementObjects.NetBiosDomainName(dnsDomain); } public static string SystemDnsDomain() { string workgroup = SystemWorkgroup(); if (workgroup != null) return null; return (string)Spludlow.ManagementObjects.Query("Win32_ComputerSystem", "Domain")[0]; } public static string NetBiosDomainName(string dnsDomainName) { DirectoryEntry rootDSE = new DirectoryEntry("LDAP://" + dnsDomainName + "/RootDSE"); string configurationNamingContext = (string)rootDSE.Properties["configurationNamingContext"][0]; DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=Partitions," + configurationNamingContext); DirectorySearcher directorySearcher = new DirectorySearcher(searchRoot); directorySearcher.SearchScope = SearchScope.OneLevel; directorySearcher.PropertiesToLoad.Add("netbiosname"); directorySearcher.Filter = "(&(objectcategory=Crossref)(dnsRoot=" + dnsDomainName + ")(netBIOSName=*))"; SearchResult result = directorySearcher.FindOne(); if (result == null) throw new ApplicationException("Can not find NetBIOS Domain Name: " + dnsDomainName); return (string)result.Properties["netbiosname"][0]; } } }