Website-Icon Frankys Web

Active Directory Shadow Groups aktualisieren

Manche Active Directory Features lassen sich nicht auf Organisationseinheiten sondern nur auf AD-Gruppen festlegen. Ein Beispiel dafür sind Fine Grained Password Policies. Will man solche Features trotzdem auf alle Benutzer einer Organisationseinheit anwenden, erstellt man einfach eine Gruppe mit allen Benutzern welche in der OU gespeichert werden. Diese Gruppe wird auch Schattengruppe (Shadow Group) genannt. Hier mal ein Beispiel:

Es macht allerdings wenig Sinn diese Gruppenmitgliedschaften manuell zu pflegen, denn so laufen schnell die Mitglieder der Shadow Groups auseinander und bilden nicht mehr die tatsächlichen Benutzer innerhalb der Organisationseinheit wieder.

Hier kann man sich aber von einem kleinen PowerShell Script helfen lassen, welches beispielsweise als geplanter Task jede Stunde ausgeführt wird und die Shadow Gruppen aktualisiert.

Das folgende Script kann dabei helfen:

# Syntax:
# <distinguishedName of OU> = <AD Group Name>

$OUtoGroupList = @{
    "OU=OU1,OU=Benutzer,DC=frankysweblab,DC=de" = "ShadowGroup_OU1"
    "OU=OU2,OU=Benutzer,DC=frankysweblab,DC=de" = "ShadowGroup_OU2"
}

$OUtoGroupList.GetEnumerator() | ForEach-Object {
	$Group =  $_.value
	$OU = $_.key
	try {
		write-output "---> Processing OU $OU"
		$Users = Get-ADUser -Filter * -SearchBase $OU | select DistinguishedName
		$GroupMembers = Get-ADGroup $Group | Get-ADGroupMember | select DistinguishedName
		$CompareGroupMembership = Compare-Object -ReferenceObject $GroupMembers.DistinguishedName -DifferenceObject $users.DistinguishedName
	} catch {}

	
	if ($Users -and $CompareGroupMembership) {
		#Update group membership if OU contains users
		$UsersToAdd = $CompareGroupMembership | where {$_.SideIndicator -eq "=>"}
		foreach ($UsertoAdd in $UsersToAdd) {
			$UserDN = $UsertoAdd.InputObject
			write-output " Add user $user to group $group"
			Add-ADGroupMember -Identity $Group -Members $UserDN -confirm:$false
		}
	
		#Remove stalled users from group
		$UsersToRemove = $CompareGroupMembership | where {$_.SideIndicator -eq "<="}
		foreach ($UserToRemove in $UsersToRemove) {
			$UserDN = $UserToRemove.InputObject
			write-output " Remove user $UserDN from group $group"
			Remove-ADGroupMember -Identity $Group -Members $UserDN -confirm:$false
		}
	}
	elseif ($Users -and !$CompareGroupMembership) {
		#Add all users from OU to Group (if group was empty)
		write-output " Add all users to group $Group, group was empty"
		$Users | ForEach-Object { Add-ADGroupMember -Identity $Group -Members $_ }
	}
	elseif (!$Users) {
		#If no users in OU, delete all members from group
		write-output " No Users in OU $OU found, delete all members from group $Group"
		Get-ADGroup $Group | Set-ADGroup -clear member
	}
}

In den ersten Zeilen wird festgelegt welche Shadow Group zu welcher OU gehört. Die Shadow Group muss dabei nicht in der gleichen OU gespeichert werden, sondern kann auch in einer separaten OU angelegt werden. Wichtig ist, dass die Gruppen vorher erstellt werden, denn das Script legt diese nicht an.

Beim Ausführen aktualisiert das Script die angegebenen Shadow Groups und fügt fehlende Benutzer zur Gruppe hinzu oder entfernt diese, wenn die Benutzerkonten in eine andere OU verschoben wurden.

Das Script kann auch bei GitHub runtergeladen werden:

Die mobile Version verlassen