- Add a domain user or group to local administrators with PowerShell - Wed, Mar 19 2014
- Create a list of local administrators with PowerShell - Wed, Mar 5 2014
- Remotely query user profile information with PowerShell - Tue, Nov 26 2013
Systems admins are frequently asked to generate a list of the users/groups who are in the local administrators group. Whereas some people use the net localgroup command to query the members, others use little VB scripts. Since this is a frequent activity for a Windows Administrator, I came up with a PowerShell script that can serve the purpose in an easy way.
The script that I am going to describe helps you query a given number of servers and generate a report in CSV format. This script handles conditions such as server offline and query failures, which it also includes in the CSV. Along with the Group member name, the script also informs you what kind of object it is (user or group) and whether it is a domain object or a local object. For domain objects, the script can also tell which domain (NetBIOS name) the object belongs to.
Script description
The good thing with this script is that it can query any local group on a remote computer. By default, it queries the Administrators group; however, if you want to generate a report for the Remote Desktop Users group, you can do that by passing the group name to the LocalGroupNameparameter of the script.
The code below is the key for the script. As you can see, I am using ADSI WinNT provider to query the group membership of a local group on a remote computer. Using the object returned from the query, I invoke a method that returns the members of the queried group.
$group = [ADSI]"WinNT://$Computer/$LocalGroupName" $members = @($group.Invoke("Members"))
After I retrieve the list of members in the group, I loop through each member and query their details, such as name, class information, and ADS path. Below is the code that queries this information.
$MemberName = $member.GetType().Invokemember("Name","GetProperty",$null,$member,$null) $MemberType = $member.GetType().Invokemember("Class","GetProperty",$null,$member,$null) $MemberPath = $member.GetType().Invokemember("ADSPath","GetProperty",$null,$member,$null)
I used a few regex statements against the ADS path to retrieve domain information for each object. Based on the regex output, the report shows whether each returned object is a domain-level object or a local object. If you want to learn more about regular expressions in PowerShell, several resources are available on the Internet. I referred to the PowerShell cook book to build the regex I used in the script.
The remaining code part of the script is mostly straightforward. Throughout the script, I used Add-Content cmdlets to write the data into a CSV file with comma (,) separation. I feel that is the best way to format the data if you want to import it into Excel to format it further.
PowerShell script
<# .Synopsis Gets membership information of local groups in remote computer .Description This script by default queries the membership details of local administrators group on remote computers. It has a provision to query any local group in remote server, not just administrators group. .Parameter ComputerName Computer Name(s) which you want to query for local group information .Parameter LocalGroupName Name of the local group which you want to query for membership information. It queries 'Administrators' group when this parameter is not specified .Parameter OutputDir Name of the folder where you want to place the output file. It creates the output file in c:\temp folder this parameter is not used. .Example Get-LocalGroupMembers.ps1 -ComputerName srvmem1, srvmem2 Queries the local administrators group membership and writes the details to c:\temp\localGroupMembers.CSV .Example Get-LocalGroupMembers.ps1 -ComputerName (get-content c:\temp\servers.txt) .Example Get-LocalGroupMembers.ps1 -ComputerName srvmem1, srvmem2 .Notes Author : Sitaram Pamarthi WebSite: http://techibee.com #> [CmdletBinding()] Param( [Parameter( ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [string[]] $ComputerName = $env:ComputerName, [Parameter()] [string] $LocalGroupName = "Administrators", [Parameter()] [string] $OutputDir = "c:\temp" ) Begin { $OutputFile = Join-Path $OutputDir "LocalGroupMembers.csv" Write-Verbose "Script will write the output to $OutputFile folder" Add-Content -Path $OutPutFile -Value "ComputerName, LocalGroupName, Status, MemberType, MemberDomain, MemberName" } Process { ForEach($Computer in $ComputerName) { Write-host "Working on $Computer" If(!(Test-Connection -ComputerName $Computer -Count 1 -Quiet)) { Write-Verbose "$Computer is offline. Proceeding with next computer" Add-Content -Path $OutputFile -Value "$Computer,$LocalGroupName,Offline" Continue } else { Write-Verbose "Working on $computer" try { $group = [ADSI]"WinNT://$Computer/$LocalGroupName" $members = @($group.Invoke("Members")) Write-Verbose "Successfully queries the members of $computer" if(!$members) { Add-Content -Path $OutputFile -Value "$Computer,$LocalGroupName,NoMembersFound" Write-Verbose "No members found in the group" continue } } catch { Write-Verbose "Failed to query the members of $computer" Add-Content -Path $OutputFile -Value "$Computer,,FailedToQuery" Continue } foreach($member in $members) { try { $MemberName = $member.GetType().Invokemember("Name","GetProperty",$null,$member,$null) $MemberType = $member.GetType().Invokemember("Class","GetProperty",$null,$member,$null) $MemberPath = $member.GetType().Invokemember("ADSPath","GetProperty",$null,$member,$null) $MemberDomain = $null if($MemberPath -match "^Winnt\:\/\/(?<domainName>\S+)\/(?<CompName>\S+)\/") { if($MemberType -eq "User") { $MemberType = "LocalUser" } elseif($MemberType -eq "Group"){ $MemberType = "LocalGroup" } $MemberDomain = $matches["CompName"] } elseif($MemberPath -match "^WinNT\:\/\/(?<domainname>\S+)/") { if($MemberType -eq "User") { $MemberType = "DomainUser" } elseif($MemberType -eq "Group"){ $MemberType = "DomainGroup" } $MemberDomain = $matches["domainname"] } else { $MemberType = "Unknown" $MemberDomain = "Unknown" } Add-Content -Path $OutPutFile -Value "$Computer, $LocalGroupName, SUCCESS, $MemberType, $MemberDomain, $MemberName" } catch { Write-Verbose "failed to query details of a member. Details $_" Add-Content -Path $OutputFile -Value "$Computer,,FailedQueryMember" } } } } } End {}
Script usage
Get local administrator group details for a remote server/desktop and generate output in the c:\temp folder:
Get-LocalGroupMembers.ps1 -ComputerName SRVMEM1
Get local administrator group details for a list of computers in a text file and save the output in the c:\local folder:
Get-LocalGroupMembers.ps1 -ComputerName (Get-Content c:\temp\servers.txt) -OutputDir c:\local
Get Remote Desktop Users group membership details for a list of computers:
Get-LocalGroupMembers.ps1 -ComputerName (Get-Content c:\temp\servers.txt) -LocalGroupName “Remote Desktop Users”
Script output
When you run the script, the output will be similar to the following.
Console output of the PowerShell script
And below is the output CSV report in Excel generated from the above execution. In this output, AD is the NetBIOS name of my test domain.
List of the local administrators in Excel
I was having issues getting the script to read a list of computer names from a text file, inspired by Erik’s complaint above I came up with a way to read the computer objects from AD directly into the script. This also allowed the script to work properly for me!
Get-ADComputer -filter * | select-object Name | Foreach-Object {.\Get-LocalGroupMembers.ps1 -ComputerName $_.Name}
Thanks to Sitaram, hope my variant here helps someone else as well.
EXTRACT GROUP MEMBERS DETAILS USING POWERSHELL
=============================
To get from Same domain
Get-ADGroupMember “domain admins.contoso.com” | select-object name >>groupdetails.csv
Get-ADGroupMember “domain admins” | select-object name >>groupdetails.csv
To Get from another trusted domain
Get-ADGroupMember “Remote Admin” -Server “eu.contoso.com” | select-object name,objectclass >>groupdetails1.csv
I left for Ole, but if anyone can assist I would greatly appreciate it. I will post the same here so sorry for duplicate:
I see you got it working so I am hoping you can help me. I can run the script as is and it lists what I need for MY computer, but I have a CSV file I want to use, but cannot figure out what to put where in the script.
Can you tell me what to put and where in the existing code? For this example assume I have c:\list\computers.csv and it looks like
computer1
computer2
Thank you in advance
It is working good. Thanks a lot
Hello Thajudeen,
The script does not find my pc administrator accounts and makes me an empty file.
can you give me the script that you used with your Setup?
Thanks .
Excellent post. it worked for me what i need.
Hi Sitaram!
Thanks for this very helpful post.
However, when I run the below script on powershell, it only gets the local group accounts on the server itself.
The output that I’m trying to get is all local administrator accounts of all servers or computer s connected to a domain controller. Which will be recorded to “localGroupMembers.CSV” file. Is this possible to retrieve?
Hoping for your prompt response.
Thanks in advance.
This was exactly what I was looking for and worked perfectly. However, does anyone know how to get the status of the account (i.e. enabled, disabled)?
Hello, this script will be very useful to me, but I get errors I don’t understand. I have taken the script exactly as it is shown above.
I get this result:
PS D:\ServerAdmins\Audit> .\Get-LocalGroupMembers.ps1 -ComputerName (get-content D:\ServerAdmins\Audit\servers.txt
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:37 char:7
+ Param(
+ ~
Missing ‘)’ in function parameter list.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:39 char:70
+ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ValueFromPipelineByPropertyName=$true
+ ~
Missing closing ‘)’ in expression.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:40 char:33
+ Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â )]
+ ~
Unexpected token ‘)’ in expression or statement.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:41 char:4
+ )
+ ~
Unexpected token ‘)’ in expression or statement.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:45 char:20
+ Â Â Â Â [Parameter()]
+ ~
An expression was expected after ‘(‘.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:49 char:20
+ Â Â Â Â [Parameter()]
+ ~
An expression was expected after ‘(‘.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:52 char:1
+ )
+ ~
Unexpected token ‘)’ in expression or statement.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:62 char:27
+ Â Â Â Â ForEach($Computer in $ComputerName) {
+ ~~
Unexpected token ‘in’ in expression or statement.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:62 char:26
+ Â Â Â Â ForEach($Computer in $ComputerName) {
+ ~
Missing closing ‘)’ in expression.
At D:\ServerAdmins\Audit\Get-LocalGroupMembers.ps1:61 char:9
+ Process {
+ ~
Missing closing ‘}’ in statement block or type definition.
Not all parse errors were reported. Correct the reported errors and try again.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList
PS D:\ServerAdmins\Audit>
Any thoughts?
Hi Bro,
This is really helpful to achieve the Local Admin Group members details. Really appropriated and Hats of to you !!
Hi Sitaram,
Thank you for this script.
How can I modify this script to give me report for all localgroups and not just the administrators without specifying each group?
Is it possible to also list the members of the domain groups in the output as well?
look at this:
https://bestitsm.wordpress.com/2018/06/11/list-members-of-local-administrators-group-in-all-domain-computers/
Hi Guys,
No Doubt this script is awesome & fulfilling our needs.
But can someone help me to get Group Description Details whether it is local or domain but i need group details to be printed in excel output in a different cell of excel.
Thanks in Advance
Hi,
Thanks for the awesome post. Is there a way to get the nested groups and users?
@john
Since this post has been published in 2014, new cmdlets have been created.
Get-LocalGroupMember is one of them.
You can combine the result with the Get-ADGroupMember cmdlet which has a -Recursive parameter.
Here is a concrete example:
If you want to run this script against all computers of your domain, instead of providing the computer list you can use the following:
Working perfectly !
Thanks for your support
Is there any way to have it pull all groups instead of just Administrators group?