S Grzybowski
S Grzybowski

Reputation: 115

C# Equivalent of this powershell snippet

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

Answers (2)

Clay
Clay

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

NicoRiff
NicoRiff

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

Related Questions