Scripts/ExternalSources/ADGroupMembership.ps1
<# .SYNOPSIS Read group memberships from Active Directory, add to Neo4j .DESCRIPTION Read group memberships from Active Directory, add to Neo4j * Assumes all AD related prefixes are AD (default) * Uses SID to assign memberships * Only assigns memberships for enabled Users * Also creates ManagedBy relationships This is invoked by Connect-TheDots .FUNCTIONALITY Dots #> [cmdletbinding()] param( ) # Dot source so module import is available in this scope if($Script:TestMode) { Write-Verbose "Using mock functions from $ModuleRoot/Mock/Mocks.ps1" . "$ModuleRoot/Mock/Mocks.ps1" } else { . Import-RequiredModule ActiveDirectory -ErrorAction Stop } $Groups = Get-ADGroup -Properties ManagedBy, MemberOf -Filter * | Select-Object DistinguishedName, SID, Name, ManagedBy, MemberOf $Users = Get-ADUser -Properties MemberOf -Filter 'enabled -eq $true' | Select-Object DistinguishedName, SID, MemberOf $SIDMap = @{} $TypeMap = @{} foreach($Group in $Groups){ $SIDMap.Add($Group.DistinguishedName, $Group.SID.Value) $TypeMap.Add($Group.DistinguishedName, 'Group') } foreach($User in $Users){ $SIDMap.Add($User.DistinguishedName, $User.SID.Value) $TypeMap.Add($User.DistinguishedName, 'User') } $GroupUserMemberMap = @{} foreach($User in $Users) { $UserSID = $User.SID.Value foreach($Group in $User.MemberOf) { $GroupSID = $SIDMap[$Group] if(-not $GroupUserMemberMap.ContainsKey($GroupSID)) { $GroupUserMemberMap.Add($GroupSID, $(New-Object System.Collections.ArrayList )) [void]$GroupUserMemberMap[$GroupSID].Add($UserSID) } else { [void]$GroupUserMemberMap[$GroupSID].Add($UserSid) } } } $GroupGroupMemberMap = @{} foreach($Member in $Groups) { $MemberSID = $Member.SID.Value foreach($Group in $Member.MemberOf) { $GroupSID = $SIDMap[$Group] if(-not $GroupGroupMemberMap.ContainsKey($GroupSID)) { $GroupGroupMemberMap.Add($GroupSID, $(New-Object System.Collections.ArrayList )) [void]$GroupGroupMemberMap[$GroupSID].Add($MemberSID) } else { [void]$GroupGroupMemberMap[$GroupSID].Add($MemberSID) } } } Invoke-Neo4jQuery -Query "MATCH ()-[r:MemberOf]->() DELETE r" $TotalCount = $GroupUserMemberMap.count $Count = 0 Foreach($Group in $GroupUserMemberMap.Keys) { Write-Progress -Activity "Updating Neo4j" -Status "Relating memberof for group $($Group.SID)" -PercentComplete (($Count / $TotalCount)*100) $Count++ Invoke-Neo4jQuery -Query " MATCH (g:Group {ADSID: {group}}) MATCH (a:User) WHERE a.ADSID IN {members} CREATE (a)-[:MemberOf]->(g) " -Parameters @{ group = $Group members = $GroupUserMemberMap[$Group] } } $TotalCount = $GroupGroupMemberMap.count $Count = 0 Foreach($Group in $GroupGroupMemberMap.Keys) { Write-Progress -Activity "Updating Neo4j" -Status "Relating memberof for group $($Group.SID)" -PercentComplete (($Count / $TotalCount)*100) $Count++ Invoke-Neo4jQuery -Query " MATCH (g:Group {ADSID: {group}}) MATCH (a:Group) WHERE a.ADSID IN {members} CREATE (a)-[:MemberOf]->(g) " -Parameters @{ group = $Group members = $GroupGroupMemberMap[$Group] } } Invoke-Neo4jQuery -Query "MATCH ()-[r:ManagedBy]->() DELETE r" # Managedby for groups $TotalCount = $Groups.count $Count = 0 Foreach($Group in $Groups.where({$_.ManagedBy -and $SIDMap.ContainsKey( $_.managedby ) -and $TypeMap.ContainsKey($_.managedby)})) { Write-Progress -Activity "Updating Neo4j" -Status "Relating managedby for group $($Group.SID.value)" -PercentComplete (($Count / $TotalCount)*100) $Count++ $SID = $null $SID = $SIDMap[$Group.ManagedBy] if($SID){ New-Neo4jRelationship -LeftLabel Group -LeftHash @{ADSID = $Group.SID.Value} -RightLabel $TypeMap[$Group.ManagedBy] -RightHash @{ADSID = $SID} -Type ManagedBy } } |