Hi Guys,
I need to extract a the configuration (query) of a group distribution group / security group.
Can anyone help me to findout?
- Products
- Solutions
- Resources
- Trials
- Support
- Partners
- Communities
Hi Guys,
I need to extract a the configuration (query) of a group distribution group / security group.
Can anyone help me to findout?
I wrote a script that extracts a Dynamic Group's query and runs a little parity check to ensure that the expected group membership matches the current group membership. I modified it to show the LDAP query that is stored in the Dynamic Group. I tested it with every scenario that I could think of, but it's possible that I missed something, so please don't be too concerned if a specific Dynamic Group does not "Pass":
*EDIT Had to fix the report a bit, wasn't showing multiple queries configured in the same Dynamic Group.
#$MaximumFunctionCount = 10000 #Running this might be necessary in environments with large Dynamic Group memberships Import-Module ActiveRolesManagementShell -DisableNameChecking #This function will filter out found members according to the current rules of the Dynamic Group and the "Built-in Policy - Dynamic Groups" policy function evaluateMembership($member, $excludeDeprovisionedUsers, $includeOnlyMailEnabledFlag, $groupType) { if(($excludeDeprovisionedUsers -eq $TRUE) -and ($member.edsvaDeprovisionStatus -ne $NULL)) #Check to see if the Dynamic Group is set to exclude Deprovisioned members and if the member is Deprovisioned { return $FALSE } if(($includeOnlyMailEnabledFlag -eq '1') -and ($groupType -eq 'Distribution') -and ($member.msExchRecipientTypeDetails -eq $NULL)) #Check to see if the "Built-in Policy - Dynamic Groups" is configured to only include mail-enabled objects in a distribution group, check to see if if the Dynamic Group is a distribution group, and if the member is mail-enabled { return $FALSE } else { return $TRUE } } #Main function. Will take in one or more group names. To check all Dynamic Groups, use: DGChecker (Get-QADGroup -Dynamic $TRUE -Proxy) function DGChecker($groups) { [xml]$edsaAPEListXML = (Get-QADObject '84c1a76b-2a6b-4f4b-837a-22d2ccac777a' -Proxy -IncludedProperties edsaAPEListXML).edsaAPEListXML #Retrieving "Built-in Policy - Dynamic Groups" if($edsaAPEListXML) { foreach($parameter in $edsaAPEListXML.APEList.APE.parameter) { if($parameter.id -eq '71') { $includeOnlyMailEnabledFlag = $parameter.value #Checking to see if "Include only mail-enabled users in dynamic distribution groups" is checked } } } foreach($group in $groups) { $dynamicGroup = get-qadobject $group -DontUseDefaultIncludedProperties -IncludedProperties member,name,groupType,accountNameHistory $actualMembers = $dynamicGroup.member $groupType = $dynamicGroup.groupType $accountnamehistory = $DynamicGroup.accountNameHistory $excludeDeprovisionedUsers = $TRUE $expectedMembers = New-Object -TypeName "System.Collections.ArrayList" $expectedMembersTemp = New-Object -TypeName "System.Collections.ArrayList" $excludedMembers = New-Object -TypeName "System.Collections.ArrayList" $expectedMembersShortList = New-Object -TypeName "System.Collections.ArrayList" $expectedMembersShortListUnique = New-Object -TypeName "System.Collections.ArrayList" $searchRoot = New-Object -TypeName "System.Collections.ArrayList" $ldapFilter = New-Object -TypeName "System.Collections.ArrayList" if(!$accountnamehistory) { return "The target object is not an Active Roles Dynamic Group or the account used to run this script does not have access to the accountNameHistory attribute." } elseif($accountnamehistory.Contains('[IDU]')) { $excludeDeprovisionedUsers = $FALSE } $correctedAccountNameHistory = $accountnamehistory.Replace('&','&') $splitData = $correctedAccountNameHistory.Split('"') foreach($entry in $splitData) { if($entry.StartsWith('[0x')) { $conditionsList = $entry $conditionArray = ($conditionsList.Split('][')) $splitConditionArray = $conditionArray.Split(';',3) for($index = 0; $index -lt $splitConditionArray.count; $index++) { if($splitConditionArray[$index] -eq '0x1') #Parse out "Include by query" { $includeQueryScope = $splitConditionArray[$index+1] $includeQueryLDAPFilter = $splitConditionArray[$index+2] if($includeQueryScope -and $includeQueryLDAPFilter) { $includeQuery = Get-QADObject -DontUseDefaultIncludedProperties -SizeLimit 0 -SearchRoot $IncludeQueryScope -LdapFilter $IncludeQueryLDAPFilter -IncludedProperties edsvaDeprovisionStatus,msExchRecipientTypeDetails -proxy $searchRoot.Add($includeQueryScope) | Out-Null $ldapFilter.Add($includeQueryLDAPFilter) | Out-Null foreach($object in $includeQuery) { if(evaluateMembership $object $excludeDeprovisionedUsers $includeOnlyMailEnabledFlag $groupType) { $expectedMembers.Add($object.DN) | Out-Null } } } } if($splitConditionArray[$index] -eq '0x2') #Parse out "Exclude by query" { $ExcludeQueryScope = $splitConditionArray[$index+1] $ExcludeQueryLDAPFilter = $splitConditionArray[$index+2] if($ExcludeQueryScope -and $ExcludeQueryLDAPFilter) { $ExcludeQuery = Get-QADObject -DontUseDefaultIncludedProperties -SizeLimit 0 -SearchRoot $ExcludeQueryScope -LdapFilter $ExcludeQueryLDAPFilter $searchRoot.Add($ExcludeQueryScope) | Out-Null $ldapFilter.Add($ExcludeQueryLDAPFilter) | Out-Null foreach($object in $ExcludeQuery) { $excludedMembers.Add($object.DN) | Out-Null } } } if($splitConditionArray[$index] -eq '0x3') #Parse out "Include explicitly" { $IncludeExplicitlyScope = $splitConditionArray[$index+1] if($IncludeExplicitlyScope) { $IncludeExplicitly = Get-QADObject $IncludeExplicitlyScope -DontUseDefaultIncludedProperties -IncludedProperties edsvaDeprovisionStatus,msExchRecipientTypeDetails -proxy $searchRoot.Add($IncludeExplicitlyScope) | Out-Null $ldapFilter.Add("Include explicitly") | Out-Null foreach($object in $IncludeExplicitly) { if(evaluateMembership $object $excludeDeprovisionedUsers $includeOnlyMailEnabledFlag $groupType) { $expectedMembers.Add($object.DN) | Out-Null } } } } if($splitConditionArray[$index] -eq '0x4') #Parse out "Exclude explicitly" { $ExcludeExplicitlyScope = $splitConditionArray[$index+1] if($ExcludeExplicitlyScope) { $ExcludeExplicitly = Get-QADObject $ExcludeExplicitlyScope -SizeLimit 0 -DontUseDefaultIncludedProperties $searchRoot.Add($ExcludeExplicitlyScope) | Out-Null $ldapFilter.Add("Exclude explicitly") | Out-Null foreach($object in $ExcludeExplicitly) { $excludedMembers.Add($object.DN) | Out-Null } } } if($splitConditionArray[$index] -eq '0x5') #Parse out "Include group members" { $IncludeGroupScope= $splitConditionArray[$index+1] if($IncludeGroupScope) { $IncludeGroup = Get-QADObject -SearchRoot $IncludeGroupScope -SizeLimit 0 -AttributeScopeQuery 'member' -DontUseDefaultIncludedProperties -IncludedProperties edsvaDeprovisionStatus,msExchRecipientTypeDetails -proxy $searchRoot.Add($IncludeGroupScope) | Out-Null $ldapFilter.Add("Include group members") | Out-Null foreach($object in $IncludeGroup) { if(evaluateMembership $object $excludeDeprovisionedUsers $includeOnlyMailEnabledFlag $groupType) { $expectedMembers.Add($object.DN) | Out-Null } } } } if($splitConditionArray[$index] -eq '0x6') #Parse out "Exclude group members" { $excludeGroupScope= $splitConditionArray[$index+1] if($ExcludeGroupScope) { $excludeGroup = Get-QADObject -SearchRoot $excludeGroupScope -SizeLimit 0 -AttributeScopeQuery 'member' -DontUseDefaultIncludedProperties $searchRoot.Add($excludeGroupScope) | Out-Null $ldapFilter.Add("Exclude group members") | Out-Null foreach($object in $excludeGroup) { $excludedMembers.Add($object.DN) | Out-Null } } } } if($excludedMembers -and $expectedMembers) #Check for any exclusions { $comparisonShortList = Compare-Object $expectedMembers $excludedMembers foreach($item in $comparisonShortList) { if($item.SideIndicator -eq '<=') { $expectedMembersShortList.Add($item.InputObject) | Out-Null } } } elseif($expectedMembers) { foreach($object in $expectedMembers) { $expectedMembersShortList.add($object) | Out-Null } } $expectedMembersShortListUnique = $expectedMembersShortList | Sort-Object -Unique #Ensure that members are only present once } } $results = @() $obj = New-Object PSObject $obj | Add-Member -MemberType NoteProperty -Name "Group Name" -Value $group for($i=1;$i -le $searchRoot.count;$i++) { $obj | Add-Member -MemberType NoteProperty -Name "Search Root $i" -Value (Get-QADObject $searchRoot[($i-1)]).DN $obj | Add-Member -MemberType NoteProperty -Name "LDAP Query $i" -Value $ldapFilter[($i-1)] } $obj | Add-Member -MemberType NoteProperty -Name "Actual Members" -Value ($actualMembers | Sort-Object -Descending) $obj | Add-Member -MemberType NoteProperty -Name "Actual Member Count" -Value $actualMembers.Count $obj | Add-Member -MemberType NoteProperty -Name "Computed Members" -Value ($expectedMembersShortListUnique | Sort-Object -Descending) $obj | Add-Member -MemberType NoteProperty -Name "Computed Members Count" -Value $expectedMembersShortListUnique.Count If($actualMembers -and $expectedMembersShortListUnique) { If(!(Compare-Object $actualMembers $expectedMembersShortListUnique)) { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "PASS" } else { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "FAIL" } } elseif(($actualMembers -eq $NULL) -and ($expectedMembersShortListUnique -eq $NULL)) { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "PASS" } else { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "FAIL" } $results += $obj $resultsReport += $results } $resultsReport } $report = DGChecker (Get-QADGroup -Dynamic $TRUE -Proxy) $report
I wrote a script that extracts a Dynamic Group's query and runs a little parity check to ensure that the expected group membership matches the current group membership. I modified it to show the LDAP query that is stored in the Dynamic Group. I tested it with every scenario that I could think of, but it's possible that I missed something, so please don't be too concerned if a specific Dynamic Group does not "Pass":
*EDIT Had to fix the report a bit, wasn't showing multiple queries configured in the same Dynamic Group.
#$MaximumFunctionCount = 10000 #Running this might be necessary in environments with large Dynamic Group memberships Import-Module ActiveRolesManagementShell -DisableNameChecking #This function will filter out found members according to the current rules of the Dynamic Group and the "Built-in Policy - Dynamic Groups" policy function evaluateMembership($member, $excludeDeprovisionedUsers, $includeOnlyMailEnabledFlag, $groupType) { if(($excludeDeprovisionedUsers -eq $TRUE) -and ($member.edsvaDeprovisionStatus -ne $NULL)) #Check to see if the Dynamic Group is set to exclude Deprovisioned members and if the member is Deprovisioned { return $FALSE } if(($includeOnlyMailEnabledFlag -eq '1') -and ($groupType -eq 'Distribution') -and ($member.msExchRecipientTypeDetails -eq $NULL)) #Check to see if the "Built-in Policy - Dynamic Groups" is configured to only include mail-enabled objects in a distribution group, check to see if if the Dynamic Group is a distribution group, and if the member is mail-enabled { return $FALSE } else { return $TRUE } } #Main function. Will take in one or more group names. To check all Dynamic Groups, use: DGChecker (Get-QADGroup -Dynamic $TRUE -Proxy) function DGChecker($groups) { [xml]$edsaAPEListXML = (Get-QADObject '84c1a76b-2a6b-4f4b-837a-22d2ccac777a' -Proxy -IncludedProperties edsaAPEListXML).edsaAPEListXML #Retrieving "Built-in Policy - Dynamic Groups" if($edsaAPEListXML) { foreach($parameter in $edsaAPEListXML.APEList.APE.parameter) { if($parameter.id -eq '71') { $includeOnlyMailEnabledFlag = $parameter.value #Checking to see if "Include only mail-enabled users in dynamic distribution groups" is checked } } } foreach($group in $groups) { $dynamicGroup = get-qadobject $group -DontUseDefaultIncludedProperties -IncludedProperties member,name,groupType,accountNameHistory $actualMembers = $dynamicGroup.member $groupType = $dynamicGroup.groupType $accountnamehistory = $DynamicGroup.accountNameHistory $excludeDeprovisionedUsers = $TRUE $expectedMembers = New-Object -TypeName "System.Collections.ArrayList" $expectedMembersTemp = New-Object -TypeName "System.Collections.ArrayList" $excludedMembers = New-Object -TypeName "System.Collections.ArrayList" $expectedMembersShortList = New-Object -TypeName "System.Collections.ArrayList" $expectedMembersShortListUnique = New-Object -TypeName "System.Collections.ArrayList" $searchRoot = New-Object -TypeName "System.Collections.ArrayList" $ldapFilter = New-Object -TypeName "System.Collections.ArrayList" if(!$accountnamehistory) { return "The target object is not an Active Roles Dynamic Group or the account used to run this script does not have access to the accountNameHistory attribute." } elseif($accountnamehistory.Contains('[IDU]')) { $excludeDeprovisionedUsers = $FALSE } $correctedAccountNameHistory = $accountnamehistory.Replace('&','&') $splitData = $correctedAccountNameHistory.Split('"') foreach($entry in $splitData) { if($entry.StartsWith('[0x')) { $conditionsList = $entry $conditionArray = ($conditionsList.Split('][')) $splitConditionArray = $conditionArray.Split(';',3) for($index = 0; $index -lt $splitConditionArray.count; $index++) { if($splitConditionArray[$index] -eq '0x1') #Parse out "Include by query" { $includeQueryScope = $splitConditionArray[$index+1] $includeQueryLDAPFilter = $splitConditionArray[$index+2] if($includeQueryScope -and $includeQueryLDAPFilter) { $includeQuery = Get-QADObject -DontUseDefaultIncludedProperties -SizeLimit 0 -SearchRoot $IncludeQueryScope -LdapFilter $IncludeQueryLDAPFilter -IncludedProperties edsvaDeprovisionStatus,msExchRecipientTypeDetails -proxy $searchRoot.Add($includeQueryScope) | Out-Null $ldapFilter.Add($includeQueryLDAPFilter) | Out-Null foreach($object in $includeQuery) { if(evaluateMembership $object $excludeDeprovisionedUsers $includeOnlyMailEnabledFlag $groupType) { $expectedMembers.Add($object.DN) | Out-Null } } } } if($splitConditionArray[$index] -eq '0x2') #Parse out "Exclude by query" { $ExcludeQueryScope = $splitConditionArray[$index+1] $ExcludeQueryLDAPFilter = $splitConditionArray[$index+2] if($ExcludeQueryScope -and $ExcludeQueryLDAPFilter) { $ExcludeQuery = Get-QADObject -DontUseDefaultIncludedProperties -SizeLimit 0 -SearchRoot $ExcludeQueryScope -LdapFilter $ExcludeQueryLDAPFilter $searchRoot.Add($ExcludeQueryScope) | Out-Null $ldapFilter.Add($ExcludeQueryLDAPFilter) | Out-Null foreach($object in $ExcludeQuery) { $excludedMembers.Add($object.DN) | Out-Null } } } if($splitConditionArray[$index] -eq '0x3') #Parse out "Include explicitly" { $IncludeExplicitlyScope = $splitConditionArray[$index+1] if($IncludeExplicitlyScope) { $IncludeExplicitly = Get-QADObject $IncludeExplicitlyScope -DontUseDefaultIncludedProperties -IncludedProperties edsvaDeprovisionStatus,msExchRecipientTypeDetails -proxy $searchRoot.Add($IncludeExplicitlyScope) | Out-Null $ldapFilter.Add("Include explicitly") | Out-Null foreach($object in $IncludeExplicitly) { if(evaluateMembership $object $excludeDeprovisionedUsers $includeOnlyMailEnabledFlag $groupType) { $expectedMembers.Add($object.DN) | Out-Null } } } } if($splitConditionArray[$index] -eq '0x4') #Parse out "Exclude explicitly" { $ExcludeExplicitlyScope = $splitConditionArray[$index+1] if($ExcludeExplicitlyScope) { $ExcludeExplicitly = Get-QADObject $ExcludeExplicitlyScope -SizeLimit 0 -DontUseDefaultIncludedProperties $searchRoot.Add($ExcludeExplicitlyScope) | Out-Null $ldapFilter.Add("Exclude explicitly") | Out-Null foreach($object in $ExcludeExplicitly) { $excludedMembers.Add($object.DN) | Out-Null } } } if($splitConditionArray[$index] -eq '0x5') #Parse out "Include group members" { $IncludeGroupScope= $splitConditionArray[$index+1] if($IncludeGroupScope) { $IncludeGroup = Get-QADObject -SearchRoot $IncludeGroupScope -SizeLimit 0 -AttributeScopeQuery 'member' -DontUseDefaultIncludedProperties -IncludedProperties edsvaDeprovisionStatus,msExchRecipientTypeDetails -proxy $searchRoot.Add($IncludeGroupScope) | Out-Null $ldapFilter.Add("Include group members") | Out-Null foreach($object in $IncludeGroup) { if(evaluateMembership $object $excludeDeprovisionedUsers $includeOnlyMailEnabledFlag $groupType) { $expectedMembers.Add($object.DN) | Out-Null } } } } if($splitConditionArray[$index] -eq '0x6') #Parse out "Exclude group members" { $excludeGroupScope= $splitConditionArray[$index+1] if($ExcludeGroupScope) { $excludeGroup = Get-QADObject -SearchRoot $excludeGroupScope -SizeLimit 0 -AttributeScopeQuery 'member' -DontUseDefaultIncludedProperties $searchRoot.Add($excludeGroupScope) | Out-Null $ldapFilter.Add("Exclude group members") | Out-Null foreach($object in $excludeGroup) { $excludedMembers.Add($object.DN) | Out-Null } } } } if($excludedMembers -and $expectedMembers) #Check for any exclusions { $comparisonShortList = Compare-Object $expectedMembers $excludedMembers foreach($item in $comparisonShortList) { if($item.SideIndicator -eq '<=') { $expectedMembersShortList.Add($item.InputObject) | Out-Null } } } elseif($expectedMembers) { foreach($object in $expectedMembers) { $expectedMembersShortList.add($object) | Out-Null } } $expectedMembersShortListUnique = $expectedMembersShortList | Sort-Object -Unique #Ensure that members are only present once } } $results = @() $obj = New-Object PSObject $obj | Add-Member -MemberType NoteProperty -Name "Group Name" -Value $group for($i=1;$i -le $searchRoot.count;$i++) { $obj | Add-Member -MemberType NoteProperty -Name "Search Root $i" -Value (Get-QADObject $searchRoot[($i-1)]).DN $obj | Add-Member -MemberType NoteProperty -Name "LDAP Query $i" -Value $ldapFilter[($i-1)] } $obj | Add-Member -MemberType NoteProperty -Name "Actual Members" -Value ($actualMembers | Sort-Object -Descending) $obj | Add-Member -MemberType NoteProperty -Name "Actual Member Count" -Value $actualMembers.Count $obj | Add-Member -MemberType NoteProperty -Name "Computed Members" -Value ($expectedMembersShortListUnique | Sort-Object -Descending) $obj | Add-Member -MemberType NoteProperty -Name "Computed Members Count" -Value $expectedMembersShortListUnique.Count If($actualMembers -and $expectedMembersShortListUnique) { If(!(Compare-Object $actualMembers $expectedMembersShortListUnique)) { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "PASS" } else { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "FAIL" } } elseif(($actualMembers -eq $NULL) -and ($expectedMembersShortListUnique -eq $NULL)) { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "PASS" } else { $obj | Add-Member -MemberType NoteProperty -Name "Dynamic Group Results" -Value "FAIL" } $results += $obj $resultsReport += $results } $resultsReport } $report = DGChecker (Get-QADGroup -Dynamic $TRUE -Proxy) $report