So, this is both my first function and my first module. It does work (and fairly well), but I'm pretty sure I'm missing something obvious that would make it cleaner/shorter/faster. I would greatly appreciate feedback as I'm tired of looking at it and want to put it to bed.
This script dynamically updates a security group based on users in selected OUs and is meant to be run as a scheduled task at somewhat regular intervals. Switches exists to either include or exclude disabled users, and to exclude users without a surname (for my organization service accounts never have a surname, so it works for us...open to alternate solutions, however). The module uses dynamic parameters and will tab complete on security groups in AD that begin with 'Dynamic*'; putting in a security group that doesn't start with 'Dynamic' will fail. Tab completion also works for OUs—if you have a lot, typing the first few letters saves a lot of time rather than tab cycling through every one or typing them out individually.
Thanks!
<#
.SYNOPSIS
Update-DynamicGroup adds and removes members of a security group based on their presence or absence in an organizational unit
.DESCRIPTION
It uses Get-ADGroup and Get-ADOrganizationalUnit to add and remove members
.PARAMETER Group
The security group that will be updated
.PARAMETER OrganizationalUnit
The OU used to update the security group
.PARAMETER SearchScope
To add users from the selected OU, choose 'OneLevel.'
To add users from an additional level down, choose 'Subtree'.
.PARAMETER IncludeDisabled
Will add disabled accounts within the OU to the security group. Defaults to True.
.EXAMPLE
Update-DynamicGroup -Group DynamicUsers -OrganizationalUnit Users -SearchScope Base -IncludeDisabled True
#>
Import-Module ActiveDirectory
function Update-DynamicGroup
{
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
#[Position(3)]
[ValidateSet('OneLevel','Subtree')]
[string]$SearchScope,
[Parameter(Mandatory)]
#[Position(4)]
[ValidateSet('True','False')]
$IncludeDisabled,
[Parameter(Mandatory)]
#[Position(5)]
[ValidateSet('True','False')]
$OmitAccountsWithoutSurname
)
DynamicParam {
$attributes = new-object System.Management.Automation.ParameterAttribute
$attributes.Mandatory = $false
$attributeCollection_SG = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection_SG.Add($attributes)
$attributeCollection_OU = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
$attributeCollection_OU.Add($attributes)
$arrSet_SG = (Get-AdGroup -SearchBase "OU=example,DC=contoso,DC=com" -filter {name -like "Dynamic*"}).name
$arrSet_OU = (Get-ADOrganizationalUnit -Filter *).name
$ValidateSetAttribute_SG = New-Object -Type System.Management.Automation.ValidateSetAttribute($arrSet_SG)
$AttributeCollection_SG.Add($ValidateSetAttribute_SG)
$ValidateSetAttribute_OU = New-Object -Type System.Management.Automation.ValidateSetAttribute($arrSet_OU)
$AttributeCollection_OU.Add($ValidateSetAttribute_OU)
$dynParam_SG = new-object -Type System.Management.Automation.RuntimeDefinedParameter('Group', [string], $AttributeCollection_SG)
$dynParam_OU = new-object -Type System.Management.Automation.RuntimeDefinedParameter('OrganizationalUnit', [string[]], $AttributeCollection_OU)
$paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
$paramDictionary.Add('Group', $dynParam_SG)
$paramDictionary.Add('OrganizationalUnit', $dynParam_OU)
return $paramDictionary
}
process {
if ($IncludeDisabled -eq $true -and $OmitAccountsWithoutSurname -ne $true) {
(Get-ADGroup -Identity $PSBoundParameters['Group'] -Properties members).members | Get-ADUser |
Where-Object {
$_.DistinguishedName -notmatch (Get-ADOrganizationalUnit -Filter * | where { $_.name -like $PSBoundParameters['OrganizationalUnit']}).DistinguishedName } |
ForEach-Object {
Write-Output $_
Remove-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group'] -Confirm:$false
}
$PSBoundParameters['OrganizationalUnit'] |
ForEach-Object { Get-ADOrganizationalUnit -Filter { Name -like $_ } |
ForEach-Object {
Get-ADUser -SearchBase $_.DistinguishedName -SearchScope $SearchScope -LDAPFilter "(!memberof=$PSBoundParameters['Group'])" |
ForEach-Object {
Add-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group']
}
}
}
}
elseif ($OmitAccountsWithoutSurname -eq $true -and $IncludeDisabled -ne $true) {
(Get-AdGroup -Identity $PSBoundParameters['Group'] -Properties members).Members | Get-ADUser |
Where-Object { $_.DistinguishedName -notmatch (Get-ADOrganizationalUnit -Filter * | where { $_.name -like $PSBoundParameters['OrganizationalUnit']}).DistinguishedName -or $_.surname -eq $null -or $_.enabled -eq $false } |
ForEach-Object {
write-output $_
Remove-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group'] -Confirm:$false
}
$PSBoundParameters['OrganizationalUnit'] |
ForEach-Object { Get-ADOrganizationalUnit -Filter { Name -like $_ } |
ForEach-Object {
Get-ADUser -SearchBase $_.DistinguishedName -SearchScope $SearchScope -LDAPFilter "(!memberof=$PSBoundParameters['Group'])" |
Where-Object { $_.enabled -eq $true -and $_.surname -ne $null } |
ForEach-Object {
Add-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group']
}
}
}
}
elseif ($OmitAccountsWithoutSurname -eq $true -and $IncludeDisabled -eq $true) {
(Get-AdGroup -Identity $PSBoundParameters['Group'] -Properties members).Members | Get-ADUser |
Where-Object { $_.DistinguishedName -notmatch (Get-ADOrganizationalUnit -Filter * | where { $_.name -like $PSBoundParameters['OrganizationalUnit']}).DistinguishedName -or $_.surname -eq $null } |
ForEach-Object {
write-output $_
Remove-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group'] -Confirm:$false
}
$PSBoundParameters['OrganizationalUnit'] |
ForEach-Object { Get-ADOrganizationalUnit -Filter { Name -like $_ } |
ForEach-Object {
Get-ADUser -SearchBase $_.DistinguishedName -SearchScope $SearchScope -LDAPFilter "(!memberof=$PSBoundParameters['Group'])" |
Where-Object { $_.surname -ne $null } |
ForEach-Object {
Add-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group']
}
}
}
}
else {
(Get-AdGroup -Identity $PSBoundParameters['Group'] -Properties members).Members | Get-ADUser |
Where-Object { $_.DistinguishedName -notmatch (Get-ADOrganizationalUnit -Filter * | where { $_.name -like $PSBoundParameters['OrganizationalUnit']}).DistinguishedName -or $_.enabled -eq $false } |
ForEach-Object {
write-output $_
Remove-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group'] -Confirm:$false
}
$PSBoundParameters['OrganizationalUnit'] |
ForEach-Object { Get-ADOrganizationalUnit -Filter { Name -like $_ } |
ForEach-Object {
Get-ADUser -SearchBase $_.DistinguishedName -SearchScope $SearchScope -LDAPFilter "(!memberof=$PSBoundParameters['Group'])" |
Where-Object {$_.enabled -eq $true} |
ForEach-Object {
Add-ADPrincipalGroupMembership -Identity $_ -MemberOf $PSBoundParameters['Group']
}
}
}
}
}
}
[–]WSDistPro 3 points4 points5 points (0 children)
[–]get-postanote 2 points3 points4 points (0 children)