🧼 Cleanup: Invalid SID Members in Local Groups (Windows Server Maintenance)
Overview
This PowerShell script scans all local groups for orphaned (invalid) SIDs — entries left behind after a user or service account has been deleted. These show as raw SIDs (e.g., S-1-5-21-...
) in group membership.
We use NinjaOne to deploy this as a recurring cleanup task across servers.
🔧 What It Does
- Enumerates all local groups
- Identifies broken/unresolvable SID entries
- Removes only invalid entries
- Outputs all actions to NinjaOne
🛠PowerShell Script
PowerShell Script
$badEntries = @()
$localGroups = Get-LocalGroup | Select-Object -ExpandProperty Name
foreach ($groupName in $localGroups) {
Write-Output "`nProcessing group: $groupName"
$badSIDs = @()
$output = powershell -Command "Get-LocalGroupMember -Group '$groupName'" 2>&1
foreach ($line in $output) {
if ($line -match "SID '([^']+)'") {
$badSIDs += $matches[1]
}
}
if ($badSIDs.Count -gt 0) {
$group = [ADSI]"WinNT://./$groupName,group"
foreach ($sid in $badSIDs | Select-Object -Unique) {
$path = "WinNT://$sid"
try {
$group.Remove($path)
Write-Output "Removed: $sid from $groupName"
$badEntries += [PSCustomObject]@{ Group = $groupName; SID = $sid; Status = "Removed" }
} catch {
Write-Warning "Failed to remove: $sid from $groupName"
$badEntries += [PSCustomObject]@{ Group = $groupName; SID = $sid; Status = "Failed" }
}
}
} else {
Write-Output "No orphaned SIDs found in $groupName"
}
}
$badEntries | Format-Table
🧪 Example Output
Processing group: Administrators Removed: S-1-5-21-...-6274 from Administrators Processing group: Users Removed: S-1-5-21-...-6835 from Users Removed: S-1-5-21-...-13465 from Users
🔒 Safety
- Only removes entries matching
S-1-5-21-*
- Only removes if the SID causes an error in
Get-LocalGroupMember
- Leaves all valid users/groups untouched