Created
May 27, 2016 23:12
-
-
Save JustinGrote/24ba4b4711592b8387fe4d527c529b0d to your computer and use it in GitHub Desktop.
Get-AllLocalGroupAdmins - Get Active Computers in AD and return the local Administrator group membership. Report as Excel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -version 5.0 | |
<# | |
.SYNOPSIS | |
Finds active computers in AD and collects a list of their group memberships | |
#> | |
param ( | |
#Path to output the resulting Excel Report | |
[String]$Path = "LocalAdminGroupReport-$(get-date -format yyyyhhmmss).xlsx", | |
#Use fancy CIM Method. Only works if winrm remote management is enabled | |
[Switch]$CIM, | |
#Get all the members of groups and include them in the results rather than the group names | |
[Switch]$ExpandGroups | |
) | |
#region Prerequisites | |
$PrerequisiteModules = "poshrsjob","importexcel" | |
$CurrentUserModulePath = "$home\Documents\WindowsPowerShell\Modules\" | |
install-module $PrerequisiteModules -scope currentuser -Confirm:$false -ErrorAction stop | |
$PrerequisiteModules | foreach { | |
import-module "$CurrentUserModulePath\$PSItem" -erroraction stop | |
} | |
#endregion Prerequisites | |
#region Includes | |
Function Get-RemoteGroupMembership | |
{ | |
<# | |
.SYNOPSIS | |
Gather list of all assigned users in all local groups on a computer. | |
.DESCRIPTION | |
Gather list of all assigned users in all local groups on a computer. | |
.PARAMETER ComputerName | |
Specifies the target computer for data query. | |
.PARAMETER IncludeEmptyGroups | |
Include local groups without any user membership. | |
.PARAMETER ThrottleLimit | |
Specifies the maximum number of systems to inventory simultaneously | |
.PARAMETER Timeout | |
Specifies the maximum time in second command can run in background before terminating this thread. | |
.PARAMETER ShowProgress | |
Show progress bar information | |
.EXAMPLE | |
PS > (Get-RemoteGroupMembership -verbose).GroupMembership | |
<output> | |
Description | |
----------- | |
List all group membership of the local machine. | |
.NOTES | |
Author: Zachary Loeber | |
Site: http://www.the-little-things.net/ | |
Requires: Powershell 2.0 | |
Version History | |
1.0.0 - 09/09/2013 | |
- Initial release | |
#> | |
[CmdletBinding()] | |
param | |
( | |
[string] | |
$ComputerName, | |
[Parameter(HelpMessage="Include empty groups in results")] | |
[switch] | |
$IncludeEmptyGroups, | |
[Parameter(HelpMessage="Set this if you want the function to prompt for alternate credentials")] | |
[switch] | |
$PromptForCredential, | |
[Parameter(HelpMessage="Set this if you want to provide your own alternate credentials")] | |
[System.Management.Automation.Credential()] | |
$Credential = [System.Management.Automation.PSCredential]::Empty | |
) | |
PROCESS | |
{ | |
# This is the actual code called for each computer | |
Write-Verbose -Message ("Local Group Membership: WMI Query to $computername") | |
$WMIHast = @{ | |
ComputerName = $ComputerName | |
ErrorAction = 'Stop' | |
} | |
# General variables | |
$GroupMembership = @() | |
$PSDateTime = Get-Date | |
# Modify this variable to change your default set of display properties | |
$defaultProperties = @('ComputerName','GroupMembership') | |
$wmi_groups = Get-WmiObject @WMIHast -Class win32_group -filter "SID = 'S-1-5-32-544'" | |
foreach ($group in $wmi_groups) | |
{ | |
$Query = "SELECT * FROM Win32_GroupUser WHERE GroupComponent = `"Win32_Group.Domain='$($group.domain)',Name='$($group.name)'`"" | |
$wmi_users = Get-WmiObject @WMIHast -query $Query -Verbose | |
if (($wmi_users -eq $null) -and ($IncludeEmptyGroups)) | |
{ | |
[PSCustomObject][Ordered]@{ | |
'Computername' = $ComputerName | |
'Group' = $group.Name | |
'GroupMember' = '' | |
'MemberType' = '' | |
} | |
} | |
else | |
{ | |
foreach ($user in $wmi_users.partcomponent) | |
{ | |
if ($user -match 'Win32_UserAccount') | |
{ | |
$Type = 'User' | |
} | |
elseif ($user -match 'Win32_Group') | |
{ | |
$Type = 'Group' | |
} | |
elseif ($user -match 'Win32_SystemAccount') | |
{ | |
$Type = 'SystemAccount' | |
} | |
else | |
{ | |
$Type = 'Other' | |
} | |
#Output the result | |
[pscustomobject][ordered]@{ | |
'ComputerName' = $ComputerName | |
'Group' = $group.Name | |
'GroupMember' = (($user.replace("Domain="," , ").replace(",Name=","\").replace("\\",",").replace('"','').split(","))[2]).trim() | |
'Type' = $Type | |
} | |
} | |
} | |
} | |
} | |
} | |
#endregion Includes | |
#region Main | |
$activeServerList = get-adcomputer -Properties lastlogondate -filter {operatingsystem -like "*Server*" -and enabled -eq $true} | | |
where lastlogondate -gt (get-date).adddays(-30) | | |
sort lastlogondate -Descending | | |
select -expandproperty dnshostname | |
$batchID = "GetRemoteGroups-" + $(new-guid).guid | |
$localGroupMemberships = $activeServerList | start-rsjob -FunctionsToLoad "Get-RemoteGroupMembership" -batch $batchID { | |
$ComputerName = $PSItem | |
write-verbose "Getting Administrator Group Members of $ComputerName" | |
if ($USING:CIM) { | |
try { | |
get-ciminstance -computername $ComputerName -classname win32_group -filter "Name = 'administrators'" -ErrorAction Stop | | |
get-cimassociatedinstance -association win32_groupuser -ErrorAction Stop | |
} catch { | |
$PSItem | |
#write-warning "$ComputerName`: Failed to collect local admin information. Error: $PSItem" | |
} | |
} else { | |
Get-RemoteGroupMembership -ComputerName $ComputerName | where | |
} #else | |
} | | |
wait-rsjob -ShowProgress | | |
receive-rsjob | |
$localGroupMemberships | export-excel -path $Path -WorkSheetname "Local Admins" -TableName "LocalAdmins" | |
remove-rsjob -batch $batchID -force | |
#Get the SID of the group using .NET function | |
$localGroupMemberships | where type -match "Group" | select -ExpandProperty GroupMember -unique | foreach { | |
$groupDomain = ($PSItem -split '\\')[0] | |
$groupName = ($PSItem -split '\\')[1] | |
$groupSID = (new-object System.Security.Principal.NTAccount($groupDomain, $groupName)).translate([System.Security.Principal.SecurityIdentifier]).value | |
#Generate the group membership entries | |
(get-adgroupmember $groupSID -recursive -ErrorAction stop) | foreach { | |
[PSCustomObject]@{ | |
Domain = $groupDomain | |
Name = $groupName | |
SID = $groupSID | |
Member = $PSItem.samaccountname | |
MemberDisplayName = $PSItem.name | |
} | |
} | |
} | export-excel -path $Path -WorkSheetname "AD Groups" -TableName "ADGroups" | |
#endregion Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment