Functions/Get-SyncActiveDirectoryGroupsScriptBlocks.ps1

<#
.SYNOPSIS
    This function returns the script blocks used to sync Active Directory groups.
#>

function Get-SyncActiveDirectoryGroupsScriptBlocks {
    [CmdletBinding(PositionalBinding=$false)]
    [OutputType([PSCustomObject])]
    param ()

    # Return the script blocks
    return [PSCustomObject]@{
        # The script block used to create an Active Directory group
        CreateEntity = {
            # Create a hash table for the cmdlet parameters
            $newADGroupParams = @{}

            # Add the properties which are defined in the expected group
            $activeDirectoryGroupProperties = Get-ActiveDirectoryGroupPropertyList
            foreach ($property in $activeDirectoryGroupProperties) {
                if (![String]::IsNullOrWhiteSpace($entity.Expected.$property)) {
                    $newADGroupParams.Add($property, $entity.Expected.$property)
                }
            }

            # Create the group
            $newGroup = New-ADGroup @newADGroupParams -PassThru -ErrorVariable errorVariable
            if (!$newGroup) {
                throw "Failed to create Active Directory group.`r`n$($errorVariable)"
            }

            # Retrieve all Active Directory users
            $allADUsers = Get-ADUser -Filter *

            # Add the members to the group
            foreach ($member in $entity.Expected.Members) {
                Write-Information "Adding '$($member)' to '$($newGroup.Name)'."
                $memberIdentity = ($allADUsers | Where-Object { $_.UserPrincipalName -eq $member }).ObjectGUID
                $newGroupMember = Add-ADGroupMember -Identity $newGroup.ObjectGUID -Members $memberIdentity -PassThru -ErrorVariable errorVariable
                if (!$newGroupMember) {
                    throw "Failed to add '$($member)' to '$($newGroup.Name)'.`r`n$($errorVariable)"
                }
            }

            # Created the group
            "success"
        }

        # The script block used to compare two Active Directory groups for equality
        CompareEntities = {
            # The 'None' output stream is selected to suppress the difference messages
            # Only the the true/false result of the compare is required here
            return Compare-ActiveDirectoryGroups -ReferenceGroup $entity.Expected -ComparisonGroup $entity.Current -OutputStream "None"
        }

        # The script block used to update a current group's properties to match the expected group
        UpdateEntity = {
            # Create a hash table for the cmdlet parameters
            $setADGroupParams = @{
                Identity = $entity.Current.ObjectGUID
            }

            # Add the properties which are defined in the expected group and are different from the current group
            $activeDirectoryGroupProperties = Get-ActiveDirectoryGroupPropertyList
            foreach ($property in $activeDirectoryGroupProperties) {
                if (![String]::IsNullOrWhiteSpace($entity.Expected.$property) -and $entity.Expected.$property -ne $entity.Current.$property) {
                    $setADGroupParams.Add($property, $entity.Expected.$property)
                }
            }

            # Update the group
            $updatedGroup = Set-ADGroup @setADGroupParams -PassThru -ErrorVariable errorVariable
            if (!$updatedGroup) {
                throw "Failed to update Active Directory group.`r`n$($errorVariable)"
            }

            # Retrieve all Active Directory users
            $allADUsers = Get-ADUser -Filter *

            # Retrieve all current group members
            $currentGroupMembers = $entity.Current.Members
            $expectedGroupMembers = $entity.Expected.Members

            # Add members to the group
            $groupMembersToAdd = $expectedGroupMembers | Where-Object { $_ -notIn $currentGroupMembers }
            foreach ($groupMemberToAdd in $groupMembersToAdd) {
                Write-Information "Adding '$($groupMemberToAdd)' to '$($entity.Current.Name)'."
                $memberIdentity = ($allADUsers | Where-Object { $_.UserPrincipalName -eq $groupMemberToAdd }).ObjectGUID
                $newGroupMember = Add-ADGroupMember -Identity $entity.Current.ObjectGUID -Members $memberIdentity -PassThru -ErrorVariable errorVariable
                if (!$newGroupMember) {
                    throw "Failed to add '$($groupMemberToAdd)' to '$($entity.Current.Name)'.`r`n$($errorVariable)"
                }
            }

            # Remove members from the group
            $groupMembersToRemove = $currentGroupMembers | Where-Object { $_ -notIn $expectedGroupMembers }
            foreach ($groupMemberToRemove in $groupMembersToRemove) {
                Write-Information "Removing '$($groupMemberToRemove)' from '$($entity.Current.Name)'."
                $memberIdentity = ($allADUsers | Where-Object { $_.UserPrincipalName -eq $groupMemberToRemove }).ObjectGUID
                $updatedGroup = Remove-ADGroupMember -Identity $entity.Current.ObjectGUID -Members $memberIdentity -Confirm:$false -PassThru -ErrorVariable errorVariable
                if (!$updatedGroup) {
                    throw "Failed to remove '$($groupMemberToRemove)' to '$($entity.Current.Name)'.`r`n$($errorVariable)"
                }
            }

            # Updated the group
            "success"
        }

        # The script block used to delete a current group
        DeleteEntity = {
            Remove-ADGroup -Identity $entity.Current.ObjectGUID -Confirm:$false

            # Deleted the group
            "success"
        }
    }
}