Skip to content

Instantly share code, notes, and snippets.

@meoso
Last active May 4, 2021 20:24
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save meoso/301f2e94306dcf2d3714c26ca5518932 to your computer and use it in GitHub Desktop.
Save meoso/301f2e94306dcf2d3714c26ca5518932 to your computer and use it in GitHub Desktop.
$OU="OU=TheOUName,DC=yourdomain,DC=com"
$ShadowGroup="CN=ShadowGroupName,OU=TheOUName,DC=yourdomain,DC=com"
Import-Module ActiveDirectory
(Get-ADGroup -Identity $ShadowGroup -properties members).Members | Get-ADUser | Where-Object {$_.distinguishedName –NotMatch $OU} | ForEach-Object {Remove-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup –Confirm:$false}
Get-ADUser –SearchBase $OU –SearchScope OneLevel –LDAPFilter "(!memberOf=$ShadowGroup)" | ForEach-Object {Add-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup}
$OU="OU=TheOUName,DC=yourdomain,DC=com"
$ShadowGroup="CN=ShadowGroupName,OU=TheOUName,DC=yourdomain,DC=com"
$WhatIf=$true #set $true for testing and $false for action
Import-Module ActiveDirectory
Write-Host "Removing non-existent members"
#$RemoveMembers = (Get-ADGroupMember -Identity $ShadowGroup | Where-Object {$_.distinguishedName -NotMatch $OU}) #Fails for more than 5000
$RemoveMembers = ((Get-ADGroup -Identity $ShadowGroup -properties members).Members | Get-ADUser | Where-Object {$_.distinguishedName -NotMatch $OU}) #workaround for 5000 limit
$RemoveMembers | ForEach-Object {Write-Host -NoNewline $_.SamAccountName ": " ; Remove-ADPrincipalGroupMembership -Identity $_ -MemberOf $ShadowGroup -Confirm:$false -WhatIf:$WhatIf -Verbose}
Write-Host "Adding members"
$AddMembers=(Get-ADUser -SearchBase $OU -SearchScope OneLevel -LDAPFilter "(!memberOf=$ShadowGroup)")
$AddMembers | ForEach-Object {Write-Host -NoNewline $_.SamAccountName ": " ; Add-ADPrincipalGroupMembership -Identity $_ -MemberOf $ShadowGroup -WhatIf:$WhatIf -Verbose}
# Emailing
if ($RemoveMembers -or $AddMembers) {
$adminEmailAddr="admin1@yourdomain.com","admin2@yourdomain.com"
$smtpServer="mailserver.yourdomain.com"
$from = "$env:COMPUTERNAME <noreply@yourdomain.com>"
$subject = "Automated script: ShadowGroup: "+($ShadowGroup -split ',*..=')[1]
$body="The following shadows applied between: <br>"
$body+="OU: $OU <br>"
$body+="Group: $ShadowGroup <br><br>"
if ($WhatIf) { $body+="TESTING ONLY<br><br>"}
foreach ($rm in $RemoveMembers) {
$sName=$rm.SamAccountName
$body+="Removed $sName <br>"
}
if ($RemoveMembers) {$body+="<br>"}
foreach ($am in $AddMembers) {
$sName=$am.SamAccountName
$body+="Added $sName <br>"
}
$body+="<br>"
Write-host "Emailing $adminEmailAddr"
$textEncoding = [System.Text.Encoding]::UTF8
try {
Send-Mailmessage -smtpServer $smtpServer -from $from -to $adminEmailAddr -subject $subject -body $body -bodyasHTML -priority High -Encoding $textEncoding -ErrorAction Stop -ErrorVariable err
} catch {
write-host "Error: Failed to email $adminEmailAddr via $smtpServer"
} finally {
if ($err.Count -eq 0) {
write-host "Successfully emailed $adminEmailAddr"
}
}
} else {
Write-Host "Nothing to email."
}
@meoso
Copy link
Author

meoso commented Mar 27, 2018

contains an important bug fix: required -properties members in the Get-ADGroup cmdlet
ref: https://ss64.com/ps/get-adgroup.html

@meoso
Copy link
Author

meoso commented May 4, 2021

shadow groups for computers work identically, just replace Get-ADUser with Get-ADComputer (2 places) :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment