Question

I've configured winrm on all my desktops via GPO, so I can now use the invoke-command cmdlet to run commands locally on remote machines. When I run net localgroup administrators on my local machine this works and gives me what I want. The problem is I cannot do anything with this data. I cannot pipe out the results to a variable so I can lets say remove specific accounts.

Is there a built in cmdlet that will let me do the same as net localgroup administrators ?

Was it helpful?

Solution

While it's possible to run net localgroup groupname and parse its output, it isn't a very PoSh way of doing this. I'd recommend using the WinNT provider instead:

$computers = 'HostA', 'HostB', 'HostC', ...
$groupname = 'Administrators'

$computers | % {
  $group = [ADSI]("WinNT://$_/$groupname,group")
  $group.PSBase.Invoke('Members') | % {
    $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)
  }
}

If you want to use Invoke-Command you could do something like this:

$computers = 'HostA', 'HostB', 'HostC', ...
$groupname = 'Administrators'

Invoke-Command -Computer $computers -ScriptBlock {
  $group = [ADSI]("WinNT://$env:COMPUTERNAME/$($args[0]),group")
  $group.PSBase.Invoke('Members') | % {
    $_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)
  }
} -ArgumentList $groupname

OTHER TIPS

You can parse the names from the output.

Here's an example using V4:

(net localgroup administrators).where({$_ -match '-{79}'},'skipuntil') -notmatch '-{79}|The command completed'

Using any version of PowerShell you can simply do the following for whichever machine you want to check:

get-wmiobject -class Win32_Group -computer <computername>(, <computer2> ...)

That will give you the local user accounts. This also gives you ManagementObjects you can use to delete groups if you want, or using PSv3 and newer additional cmdlets are installed on Windows Server (run get-module -list) you can use that may be easier (but still use WMI over WinRM).

I want to build on @Ansgar Wiechers's answer. For my purposes, getting the name of each user was not enough; I had to get the user's domain so that I could see whether the user account was a local account or a domain account.

Instead of calling PSBase.Invoke('Members'), I simply called Members(). To get the path of each user, I casted the object using [ADSI] and then got the Path property. This was the code that I ended up using to get the members of the local Administrators group on the local machine:

([ADSI]"WinNT://localhost/Administrators,group").Members() | % { ([ADSI]$_).Path.Substring(8) }

For multiple computers, it would look like this:

$computers = 'HostA', 'HostB', 'HostC', ...
$computers | % {
    ([ADSI]"WinNT://$_/Administrators,group").Members() | % {
        ([ADSI]$_).Path.Substring(8)
    }
}

In the end, I extended my script to query all of the computers in my domain, list the local administrators on each computer, and export all of the results to an XML file:

Import-Module ActiveDirectory
Get-ADComputer -Filter { enabled -eq $true } | % {
    $result = New-Object PSObject
    Add-Member -InputObject $result -MemberType NoteProperty -Name "Name" -Value $_.Name
    $local_administrators = ([ADSI]"WinNT://$($_.Name)/Administrators,group").Members() | % { ([ADSI]$_).Path.Substring(8) }
    Add-Member -InputObject $result -MemberType NoteProperty -Name "Local Administrators" -Value $local_administrators
    $result
} | Export-Clixml "Local Administrators on Machines in the Domain.xml"

You have to install the Remote Server Administration Tools in order to do Import-Module ActiveDirectory. For Windows 7 SP1, you can go to https://www.microsoft.com/en-us/download/details.aspx?id=7887 to download and install the tools and then go to Add or Remove Windows Features to enable them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top