Reputation: 115
I have the below snippet in PowerShell that is returning me the information I need for local administrators on a remote PC. I am trying to convert this code into c#, but have been having very little luck with it.
$ADMINS = get-wmiobject -computername $computername -Credential $Credential -query "select * from win32_groupuser where GroupComponent=""Win32_Group.Domain='$computername',Name='administrators'""" | % {$_.partcomponent}
I am able to get a basic wmi query working in c# as seen below : Method
public IEnumerable<CimInstance> WmiQuerier(CimSession session , string wmiquery)
{
try
{
string Namespace = @"root\cimv2";
IEnumerable<CimInstance> CimInstances = new List<CimInstance>();
CimInstances = session.QueryInstances(Namespace, "WQL", wmiquery);
//IEnumerable<CimInstance> CimInstances2 = CimInstances.SelectMany()
return CimInstances;
}
catch (Exception ex )
{
Console.WriteLine(ex.Message);
throw;
}
TEST
[Test]
public void CimQuery()
{
string querystring = "SELECT * FROM win32_groupuser";
Wmi wmi = new Wmi();
NetworkCredential mynetcred = new NetworkCredential("Domain\\User", "Password%");
CimCredential mycimCred = wmi.ConvertCred(mynetcred);
CimSession mySession = wmi.WmiConnection(testcomp, mycimCred);
IEnumerable<CimInstance> querierResults = wmi.WmiQuerier(mySession, querystring).Take(5).ToList();
Assert.IsInstanceOf<IEnumerable<CimInstance>>(querierResults);
}
}
However, When I attempt to add in any kind of Where clause like I have in the powershell code, (See my attempt below )
"SELECT * FROM win32_groupuser Where GroupComponent = \"Win32_Group.Domain='MachineName',Name='administrators' \""
I get the error
Microsoft.Management.Infrastructure.CimException: 'The WS-Management service cannot process the request. The WQL query is invalid. '
What am I doing incorrectly in my WQL string?
Upvotes: 5
Views: 1168
Reputation: 5084
Here's a query that works. I know one thing...that the syntax of the WQL is extremely sensitive and unforgiving...especially regarding spaces and quote nesting. Funny enough, it's fine with uppercase/lowercase:
using System.Management;
//....
var domainName = "YourDomainName";
var groupName = "Administrators";
var wql = string.Format
(
@"select partcomponent from win32_groupuser where groupcomponent='Win32_Group.Domain=""{0}"",Name=""{1}""'",
domainName,
groupName
);
foreach ( var thing in new ManagementObjectSearcher( wql ).Get( ) )
{
foreach ( var property in thing.Properties )
{
//--> And then, if you want the account object...
var path = new ManagementPath( property.Value as string );
var account = new ManagementObject( path );
foreach ( var acctProp in account.Properties )
{
Console.WriteLine( $"{acctProp.Name}={acctProp.Value}" );
}
}
}
Edit: Just for yucks, I added code to get the referenced Win32_Account object...since the value of partcomponent
is a qualified reference to that account object.
Upvotes: 1
Reputation: 4883
It isn't clear on your example why it is failing since you do not have the WHERE
clause set. My best guess is that some characters are not being escaped like they should.
You can also use ORMi library to give your problem an indirect solution. You can do it this way:
WMIHelper helper = new WMIHelper("root\\CimV2");
var users = helper.Query("SELECT * FROM Win32_GroupUser").ToList().Where(u => u.Contains("Win32_Group.Domain='MachineName',Name='administrators'"));
Upvotes: 0