Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

Get Local Admin Group Members in a New Old Way

Posted on April 2, 2013

Yesterday I posted a quick article on getting the age of the local administrator account password. It seemed appropropriate to follow up on a quick and dirty way to list all members of the local administrator group. Normally, I would turn to WMI (and have written about this in the past). But WMI is relatively slow for this task and even using the new CIM cmdlets in PowerShell 3.0 don't improve performance. Instead I'm going to return to an old school technique using the NET command.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!
PS C:\> net localgroup administrators
Alias name     administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
Administrator
GLOBOMANTICS\Domain Admins
localadmin
The command completed successfully.

It is very easy to see members. To query a remote computer all I need to do is wrap this in Invoke-Command and use PowerShell remoting.

PS C:\> invoke-command {net localgroup administrators} -comp chi-fp01
Alias name     administrators
Comment        Administrators have complete and unrestricted access to the computer/domain

Members

-------------------------------------------------------------------------------
Administrator
GLOBOMANTICS\Chicago IT
GLOBOMANTICS\Domain Admins
The command completed successfully.

Yes, there is some overhead for remoting but overall performance is pretty decent. And if you already have an established PSSession, even better. For quick and dirty one-liner it doesn't get much better. Well, maybe it can.

I have no problem using legacy tools when they still get the job done and this certainly qualifies. To make it more PowerShell friendly though, let's clean up the output by filtering out blanks, that last line and skipping the "header" lines.

PS C:\> invoke-command {
>> net localgroup administrators | 
>> where {$_ -AND $_ -notmatch "command completed successfully"} | 
>> select -skip 4
>> } -computer chi-fp01
>>
Administrator
GLOBOMANTICS\Chicago IT
GLOBOMANTICS\Domain Admins

Boom. Now I only get the member names. Let's go one more level and write an object to the pipeline and be better at handling output from multiple computers. I came up with a scriptblock like this:

$members = net localgroup administrators | 
 where {$_ -AND $_ -notmatch "command completed successfully"} | 
 select -skip 4
New-Object PSObject -Property @{
 Computername = $env:COMPUTERNAME
 Group = "Administrators"
 Members=$members
 }

This will create a simple object with a properties for the computername, group name and members. Here's how I can use it with Invoke-Command.

invoke-command {
$members = net localgroup administrators | 
 where {$_ -AND $_ -notmatch "command completed successfully"} | 
 select -skip 4
New-Object PSObject -Property @{
 Computername = $env:COMPUTERNAME
 Group = "Administrators"
 Members=$members
 }
} -computer chi-fp01,chi-win8-01,chi-ex01 -HideComputerName | 
Select * -ExcludeProperty RunspaceID

get-netlocalgroupNow I have objects that I can export to XML, convert to HTML or send to a file. But since I've come this far, I might as well take a few more minutes and turn this into a reusable tool.

Function Get-NetLocalGroup {
[cmdletbinding()]

Param(
[Parameter(Position=0)]
[ValidateNotNullorEmpty()]
[object[]]$Computername=$env:computername,
[ValidateNotNullorEmpty()]
[string]$Group = "Administrators",
[switch]$Asjob
)

Write-Verbose "Getting members of local group $Group"

#define the scriptblock
$sb = {
 Param([string]$Name = "Administrators")
$members = net localgroup $Name | 
 where {$_ -AND $_ -notmatch "command completed successfully"} | 
 select -skip 4
New-Object PSObject -Property @{
 Computername = $env:COMPUTERNAME
 Group = $Name
 Members=$members
 }
} #end scriptblock

#define a parameter hash table for splatting
$paramhash = @{
 Scriptblock = $sb
 HideComputername=$True
 ArgumentList=$Group
 }

if ($Computername[0] -is [management.automation.runspaces.pssession]) {
    $paramhash.Add("Session",$Computername)
}
else {
    $paramhash.Add("Computername",$Computername)
}

if ($asjob) {
    Write-Verbose "Running as job"
    $paramhash.Add("AsJob",$True)
}

#run the command
Invoke-Command @paramhash | Select * -ExcludeProperty RunspaceID

} #end Get-NetLocalGroup

This function lets me specify a group of computers or PSSessions as well as the local group name. Today I may need to know who belongs to the local administrator's group but tomorrow it might be Remote Desktop Users.

PS C:\> Get-NetLocalGroup -Group "remote desktop users" -Computername $sessions

Group        : remote desktop users
Computername : CHI-FP01
Members      : 

Group        : remote desktop users
Computername : CHI-WIN8-01
Members      : 

Computername : CHI-EX01
Members      : 
Group        : remote desktop users

Group        : remote desktop users
Computername : CHI-DC01
Members      : jfrost

Sometimes even old school tools can still be a part of your admin toolkit.

 


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

5 thoughts on “Get Local Admin Group Members in a New Old Way”

  1. Mike Shepard says:
    April 2, 2013 at 10:48 am

    Even if I’d be tempted to resort to other means to get this information, I think the approach (legacy cmdline app -> objects) is an extremely valuable technique. And by “hiding” it in a script you leave the opportunity to switch the implementation out. Very nice!

  2. Other (@dvsmark) says:
    April 2, 2013 at 4:37 pm

    I like it. I should get to work.

  3. Peter Kriegel says:
    April 4, 2013 at 6:46 am

    Again a very good post!
    I Like to go with the WMI / CIM approach under use of the well known SID of the Administrators Group (S-1-5-32-544) because we have International Computer setups.
    net localgroup depends on the Name of the group.
    The German Administrators group name is “Administratoren” and the Spanish is Adminitradores (or so) 😉

    By use of the well known SID you do not have problems with different Names and it works worldwide!
    See: http://support.microsoft.com/kb/243330/en-us

    Greets:
    Peter Kriegel
    http://www.admin-source.de

  4. Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, Exchange, SystemCenter and more – #23 - TechCenter - Blog - TechCenter – Dell Community
  5. Pingback: Microsoft Most Valuable Professional (MVP) – Best Posts of the Week around Windows Server, Exchange, SystemCenter and more – #23 - Dell TechCenter - TechCenter - Dell Community

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d