Getting "Invalid query" ManagementException - c#

I am trying to get system information of the machine which is in domain.
Below is my code for that.
ConnectionOptions opt = new ConnectionOptions();
opt.Authentication = System.Management.AuthenticationLevel.Packet;
opt.Impersonation = ImpersonationLevel.Impersonate;
opt.EnablePrivileges = true;
opt.Username = strUserName;
opt.Password = strPassword;
ManagementPath p = new ManagementPath("\\\\" + strServerName + "\\root\\cimv2");
ManagementScope scope = new ManagementScope(p, opt);
ObjectQuery query = new ObjectQuery("SELECT Architecture FROM Win32_Processor");
ManagementObjectSearcher search = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection results = search.Get();
ManagementObjectCollection.ManagementObjectEnumerator e = results.GetEnumerator();
e.MoveNext();
ushort arch = (ushort)e.Current["Architecture"];
I am getting exception of invalid query on e.MoveNext() line.This code is running perfectly fine for almost all machine but in some machine it is giving such an exception. I don't know why this exception occur and how to solve it?

Related

WMI to retrieve website physical path in c#

I've created this VBScript WMI script:
On Error Resume Next
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
Set objWMIService = GetObject("winmgmts:\\localhost\root\MicrosoftIISv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM IIsWebVirtualDirSetting", _
"WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
WScript.Echo "Path: " & objItem.Path
WScript.Echo
Next
Which returns the physical path (C:\inetpub\wwwroot\webapplication1) to all the applications in IIS.
Now I'm trying to use C# to populate a combobox with those values:
public static ArrayList Test2()
{
ArrayList WebSiteListArray = new ArrayList();
ConnectionOptions connection = new ConnectionOptions();
ManagementScope scope =
new ManagementScope(#"\\" + "localhost" + #"\root\MicrosoftIISV2",
connection);
scope.Connect();
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope,
new ObjectQuery("SELECT * FROM IIsWebVirtualDirSetting"), null);
ManagementObjectCollection webSites = searcher.Get();
foreach (ManagementObject webSite in webSites)
{
WebSiteListArray.Add(webSite.Path);
}
return WebSiteListArray;
}
But the output is the virtual path:
(`IIsWebVirtualDirSetting.Name="W3SVC/1/ROOT/webapplication1"`)
What needs to be changed in my query?
Note: I need to support IIS6 and .NET 4.0
Finally got it...
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\MicrosoftIISv2",
"SELECT * FROM IIsWebVirtualDirSetting");
foreach (ManagementObject queryObj in searcher.Get())
{
result.Add(queryObj["Path"]);
}
I prefer like this:
Connect at my local network server SOMEREMOTESERVER:
ConnectionOptions connection = new ConnectionOptions();
connection.Authentication = System.Management.AuthenticationLevel.PacketPrivacy;
ManagementScope scope =
new ManagementScope(#"\\SOMEREMOTESERVER\root\MicrosoftIISV2",
connection);
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM IISWebServerSetting");
var collection = new ManagementObjectSearcher(scope, query).Get();
foreach (ManagementObject item in collection)
{
var value = item.Properties["ServerBindings"].Value;
if (value is Array)
{
foreach (ManagementBaseObject a in value as Array)
{
Console.WriteLine(a["Hostname"]);
}
}
ManagementObject maObjPath = new ManagementObject(item.Scope,
new ManagementPath(
string.Format("IISWebVirtualDirSetting='{0}/root'", item["Name"])),
null);
PropertyDataCollection properties = maObjPath.Properties;
Console.WriteLine(properties["path"].Value);
Console.WriteLine(item["ServerComment"]);
Console.WriteLine(item["Name"]);
Console.WriteLine();
Console.WriteLine();
Console.WriteLine();
}

C# - How to get list of USERs/GROUPs having access to shared folder on a Remote Machine

I wanted to write a code in C# to list all the users/groups having access (Read/Write/Full) to a shared folder on a server.
For Example: I have a shared folder \servername\MyData. Now I wanted to list the users/groups who have access to this folder.
This should get you pointed in the right direction, I can't test it atm but should be something similar.
private bool CheckAccess(DirectoryInfo directory)
{
// Get the collection of authorization rules that apply to the current directory
AuthorizationRuleCollection acl = directory.GetAccessControl().GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
foreach (var rule in acl)
{
// do something here
}
}
private DataTable GetSharedFolderAccessRule()
{
DataTable DT = new DataTable();
try
{
DT.Columns.Add("ShareName");
DT.Columns.Add("Caption");
DT.Columns.Add("Path");
DT.Columns.Add("Domain");
DT.Columns.Add("User");
DT.Columns.Add("AccessMask");
DT.Columns.Add("AceType");
ManagementScope Scope = new ManagementScope(#"\\.\root\cimv2");
Scope.Connect();
ObjectQuery Query = new ObjectQuery("SELECT * FROM Win32_LogicalShareSecuritySetting");
ManagementObjectSearcher Searcher = new ManagementObjectSearcher(Scope, Query);
ManagementObjectCollection QueryCollection = Searcher.Get();
foreach (ManagementObject SharedFolder in QueryCollection)
{
{
String ShareName = (String) SharedFolder["Name"];
String Caption = (String)SharedFolder["Caption"];
String LocalPath = String.Empty;
ManagementObjectSearcher Win32Share = new ManagementObjectSearcher("SELECT Path FROM Win32_share WHERE Name = '" + ShareName + "'");
foreach (ManagementObject ShareData in Win32Share.Get())
{
LocalPath = (String) ShareData["Path"];
}
ManagementBaseObject Method = SharedFolder.InvokeMethod("GetSecurityDescriptor", null, new InvokeMethodOptions());
ManagementBaseObject Descriptor = (ManagementBaseObject)Method["Descriptor"];
ManagementBaseObject[] DACL = (ManagementBaseObject[])Descriptor["DACL"];
foreach (ManagementBaseObject ACE in DACL)
{
ManagementBaseObject Trustee = (ManagementBaseObject)ACE["Trustee"];
DataRow Row = DT.NewRow();
Row["ShareName"] = ShareName;
Row["Caption"] = Caption;
Row["Path"] = LocalPath;
Row["Domain"] = (String) Trustee["Domain"];
Row["User"] = (String) Trustee["Name"];
Row["AccessMask"] = (UInt32) ACE["AccessMask"];
Row["AceType"] = (UInt32)ACE["AceType"];
DT.Rows.Add(Row);
DT.AcceptChanges();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace, ex.Message);
}
return DT;
}

Control Microsoft NLB with WMI c#

I try to control NLB with WMI.
WqlObjectQuery wql = new WqlObjectQuery (#"SELECT * FROM MicrosoftNLB_Node");
ManagementObjectSearcher search = new ManagementObjectSearcher(wql);
foreach (var obj in search.Get())
{
MessageBox.Show(obj.ToString());
}
I get a error message "Invalid class"
Try this:
ManagementObjectSearcher search = new ManagementObjectSearcher(
#"root\MicrosoftNLB",
#"SELECT * FROM MicrosoftNLB_Node");
foreach (var obj in search.Get())
{
MessageBox.Show(obj.ToString());
}
The MicrosoftNLB_Node class it's part of the Root\MicrosoftNLB namespace, So it seems which you are not setting the namespace before to connect to the WMi service.
try this
ManagementObjectSearcher search = new ManagementObjectSearcher(#"root\MicrosoftNLB",wql);

how to access romote windows service with Related ObjectQuery

I want to control (start and stop) a windows service which is in the remote machine. I can connect that machine but I can't access to windows service. Here is my code.
Can you help me?
ConnectionOptions oConn = new ConnectionOptions();
oConn.Username = "****";
oConn.Password = "****";
ManagementScope managementScope = new ManagementScope(#"\\***.***.***.***\root\CIMV2", oConn);
managementScope.Connect();
RelatedObjectQuery roq = new RelatedObjectQuery("Win32_Service.Name='KanAktarim'");
ManagementObjectSearcher moSearcher = new ManagementObjectSearcher(managementScope, roq);
ManagementObjectCollection mbCollection = moSearcher.Get();
ManagementObjectSearcher moSearcher = new ManagementObjectSearcher();
moSearcher.Scope = managementScope;
moSearcher.Query = new ObjectQuery("SELECT * FROM win32_Service WHERE Name ='KanAktarim'");
ManagementObjectCollection mbCollection = moSearcher.Get();
foreach (ManagementObject oReturn in mbCollection)
{
ManagementBaseObject outParams = oReturn.InvokeMethod("StartService", null, null);
ManagementBaseObject outParams = oReturn.InvokeMethod("StopService", null, null);
string a = outParams["ReturnValue"].ToString();
string state = oReturn.Properties["State"].Value.ToString().Trim();
}

Determine operating system and processor type in C#

I want to check what type of operating system i use and what kind of processor. this should be check on run time. i tried using
System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")
and
System.OperatingSystem osInfo2 = System.Environment.OSVersion;
Console.WriteLine(osInfo2.ToString());
but it's just the enviroment that VS is running on.
I was told to use WMI to check it but i can't find out how.
can someone help me with that?
Retrieving OS info:
var wmi =
new ManagementObjectSearcher( "select * from Win32_OperatingSystem" )
.Get()
.Cast<ManagementObject>()
.First();
OS.Name = ((string)wmi["Caption"]).Trim();
OS.Version = (string)wmi["Version"];
OS.MaxProcessCount = (uint)wmi["MaxNumberOfProcesses"];
OS.MaxProcessRAM = (ulong)wmi["MaxProcessMemorySize"];
OS.Architecture = (string)wmi["OSArchitecture"];
OS.SerialNumber = (string)wmi["SerialNumber"];
OS.Build = ((string)wmi["BuildNumber"]).ToUint();
Retrieving CPU info:
var cpu =
new ManagementObjectSearcher( "select * from Win32_Processor" )
.Get()
.Cast<ManagementObject>()
.First();
CPU.ID = (string)cpu["ProcessorId"];
CPU.Socket = (string)cpu["SocketDesignation"];
CPU.Name = (string)cpu["Name"];
CPU.Description = (string)cpu["Caption"];
CPU.AddressWidth = (ushort)cpu["AddressWidth"];
CPU.DataWidth = (ushort)cpu["DataWidth"];
CPU.Architecture = (CPU.CpuArchitecture)(ushort)cpu["Architecture"];
CPU.SpeedMHz = (uint)cpu["MaxClockSpeed"];
CPU.BusSpeedMHz = (uint)cpu["ExtClock"];
CPU.L2Cache = (uint)cpu["L2CacheSize"] * (ulong)1024;
CPU.L3Cache = (uint)cpu["L3CacheSize"] * (ulong)1024;
CPU.Cores = (uint)cpu["NumberOfCores"];
CPU.Threads = (uint)cpu["NumberOfLogicalProcessors"];
CPU.Name =
CPU.Name
.Replace( "(TM)", "™" )
.Replace( "(tm)", "™" )
.Replace( "(R)", "®" )
.Replace( "(r)", "®" )
.Replace( "(C)", "©" )
.Replace( "(c)", "©" )
.Replace( " ", " " )
.Replace( " ", " " );
Yes WMI is the best way to do this kind of stuff
You can use this to retrieve OS informations :
ManagementObjectSearcher objMOS = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_OperatingSystem");
To determine the operating system use this code:
string OPSystemVersion = Environment.OSVersion.ToString();
To determine the CPU name and type first add System.Management reference to your project, then you can use this code:
public static string SendBackProcessorName()
{
ManagementObjectSearcher mosProcessor = new ManagementObjectSearcher("SELECT * FROM Win32_Processor");
string Procname = null;
foreach (ManagementObject moProcessor in mosProcessor.Get())
{
if (moProcessor["name"] != null)
{
Procname = moProcessor["name"].ToString();
}
}
return Procname;
}
Look at the ManagementClass class:
http://msdn.microsoft.com/en-us/library/system.management.managementclass.aspx
var mgmt = new ManagementClass("Win32_OperatingSystem");
foreach (ManagementObject mgmtObj in mgmt.GetInstances())
{
// Just get first value.
return mgmtObj[info.Information].ToString().Trim();
}

Categories