Public/Expand-ADDynamicGroup.ps1
Function Expand-ADDynamicGroup { <# .SYNOPSIS Expand dynamic security group definition to describe actions to take .DESCRIPTION Expand dynamic security group definition to describe actions to take Takes the output of Get-ADDynamicGroup and expands this into an array of actions with the following properties: Group # The target group we will take this action on Account # The account we will act on for this target group Action # The action we will take on thie target group and account pair Type # If IncludeType parameter is specified, whether the account is a group or a user Definition # The raw input we parsed from Get-ADDynamicGroup .FUNCTIONALITY Active Directory .PARAMETER InputObject Dynamic group definition generated by Get-ADDynamicGroup .PARAMETER IncludeType If specified, parse the AD type for each AD account to be added or removed from the target group .EXAMPLE Get-ADDynamicGroup $Yaml | Expand-ADDynamicGroup .EXAMPLE Get-ADDynamicGroup $Yaml | Expand-ADDynamicGroup -IncludeType .LINK Get-ADDynamicGroup .LINK Invoke-ADGrouper .LINK about_ADGrouper #> [cmdletbinding()] param( [parameter(ValueFromPipeline= $True)] [PSTypeName('adgrouper.group')] [psobject[]]$InputObject, [switch]$IncludeType ) begin { function Get-Params { param($Target, $Account) $Props = Get-PropertyOrder $Account $ThisRecurse = if($Props -contains 'Recurse') {$Account.Recurse} else {$Target.Recurse} $ThisExpand = if($Props -contains 'Expand') {$Account.Expand} else {$Target.Expand} @{ Identity = $Account.Account Recurse = $ThisRecurse Expand = $ThisExpand } } } process { Write-Verbose "Expanding $($InputObject | Out-String)" foreach($Group in $InputObject) { $Excludes = New-Object System.Collections.ArrayList $Includes = New-Object System.Collections.ArrayList foreach($ADObject in @( $Group.Exclude | Where {$_.Account})) { $Type = $null $Type = Get-ADObjectClass -sAMAccountName $ADObject.Account if($Type) { $Params = Get-Params -Target $Group -Account $ADObject Write-Verbose "Expanding removal of $($ADObject.account) with type [$Type] and expand [$($Group.Expand)]" [void]$Excludes.AddRange( @(Expand-Account @Params -Type $Type ) ) } else { Write-Warning "No type found for $($ADObject.Account) exclude, skipping" } } foreach($ADObject in @( $Group.Include | Where {$_.Account})) { $Type = $null $Type = Get-ADObjectClass -sAMAccountName $ADObject.Account if($Type) { $Params = Get-Params -Target $Group -Account $ADObject Write-Verbose "Expanding inclusion of $($ADObject.account) with type [$Type], expand [$($Params.Expand)], recurse [$($Params.Recurse)]" [void]$Includes.AddRange( @(Expand-Account @Params -Type $Type) ) } else { Write-Warning "No type found for $($ADObject.Account) include, skipping" } } foreach($Query in @( $Group.IncludeQuery | Where {$_}) ) { $DiscoveredAccounts = $null [string[]]$DiscoveredAccounts = Get-ADSIObject -Query $Query | Select -ExpandProperty sAMAccountName | Where {$_} if($DiscoveredAccounts.count -gt 0) { Write-Verbose "Including $($DiscoveredAccounts.count) accounts from query [$Query]" [void]$Includes.AddRange( $DiscoveredAccounts ) } else { Write-Verbose "No accounts found for IncludeQuery [$Query]" } } foreach($Query in @( $Group.ExcludeQuery | Where {$_}) ) { $DiscoveredAccounts = $null [string[]]$DiscoveredAccounts = Get-ADSIObject -Query $Query | Select -ExpandProperty sAMAccountName | Where {$_} if($DiscoveredAccounts.count -gt 0) { Write-Verbose "Excluding $($DiscoveredAccounts.count) accounts from query [$Query]" [void]$Excludes.AddRange( $DiscoveredAccounts ) } else { Write-Verbose "No accounts found for ExcludeQuery [$Query]" } } $Excludes = $Excludes | Sort -Unique $Includes = $Includes | Where {$Excludes -notcontains $_} | Select -Unique $Existing = Expand-Account -Type Group -Identity $Group.TargetGroup -Expand $ToRemove = $Existing | Where {$Includes -notcontains $_} | Sort -Unique $ToAdd = $Includes | Where {$Existing -notcontains $_} | Sort -Unique if($Group.Purge -and $null -notlike $ToRemove) { foreach($Account in $ToRemove) { [pscustomobject]@{ PSTypeName = 'adgrouper.action' Group = $Group.TargetGroup Account = $Account Action = 'Remove' Type = Get-ADObjectClass -sAMAccountName $Account -IncludeType $IncludeType Definition = $Group } } } foreach($Account in $ToAdd) { [pscustomobject]@{ PSTypeName = 'adgrouper.action' Group = $Group.TargetGroup Account = $Account Action = 'Add' Type = Get-ADObjectClass -sAMAccountName $Account -IncludeType $IncludeType Definition = $Group } } } } } |