private/CreateOrSetGroup.ps1

function CreateOrSetGroup {
    [CmdletBinding(SupportsShouldProcess=$true)]
    Param
    (
        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)]
        [String]$Name,

        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)]
        [String]$Description,

        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)]
        [String]$Path,

        [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=3)]
        [String]$GroupScope,   

        [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=4)]
        [String]$Info,

        [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=5)]
        [String[]]$MemberOf=$null,

        [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=6)]
        [String[]]$Members=$null,

        [Switch]$ResetMembership
    )
    Begin{
        #$ConfirmPreference = "none"
        <#$shouldProcess = @{
            Confirm = [bool]($ConfirmPreference -eq "low")
            Whatif = [bool]($WhatIfPreference.IsPresent)
            verbose = [bool]($VerbosePreference -ne "SilentlyContinue")
        }#>

        $CreatedGroups = [System.Collections.Generic.List[String]]::new()
        $MembershipChanges = [System.Collections.Generic.List[System.collections.hashtable]]::new()
    }
    PROCESS {
        if ($PsItem.Name) { $Name = $_.Name}
        if ($PsItem.Description) {$Description = $_.Description}
        if ($PsItem.Path) {$Path = $_.Path}
        if ($PsItem.GroupScope) {$GroupScope = $_.GroupScope}
        if ($PsItem.Info) {$Info = $_.Info}

        $GroupParams = @{
            Description = "+$Description"
            GroupScope = $groupScope
            confirm = $false
        }

        $GroupDN = "CN=$name,$path"
        if ($PSCmdlet.ShouldProcess($GroupDN,"Set Description and metadata")) {
            try {
                Set-ADGroup -Identity $GroupDN @GroupParams -replace @{info=$info} -passthru
                if ($resetMembership) {
                    get-adgroup -identity $groupDN -properties memberOf | select-object -expand memberOf | remove-adgroupmember -member $groupDN -confirm:$false
                }
                if ($members) {
                    add-adgroupMember -identity $GroupDN -members $members
                }
            } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
                Write-Verbose " Didn't exist; creating"
                try {
                    New-ADGroup -name $name -path $path @GroupParams -groupCategory "Security" -passthru
                    $CreatedGroups.add($GroupDN)
                } catch {
                    write-warning ("Error creating {0} at {1}" -f $name,$path)
                    #throw $_
                }

            }
        }
        if ($members) {
            if ($null -eq $groupDN) {
                write-debug "you have null members for $groupDN"
            } else {
                $MembershipChanges.add(@{
                    Identity = $GroupDN
                    Members = $members
                })
            }
        }
        if ($memberOf) {
            foreach ($g in $memberOf) {
                if ($null -eq $g) {
                    write-debug "you have null memberofs for $groupDN"
                } else {
                    $MembershipChanges.add(@{
                        Identity = $g
                        Members = $groupDN
                    })
                }
            }
        }
    }
    END{
        $ProgressActivity ="Waiting for creation of new Groups"
        for ($i = 0; $i -lt $CreatedGroups.count; $i++) {
            $ProgressActivity = "Waiting for creation of new Groups ({0} / {1})" -f $($i+1), $Createdgroups.count
            $item = $CreatedGroups[$i]
            $name = $item.split(",")[0].split("=")[1]
            $status = $name
            write-Progress -id 1 -Activity $ProgressActivity -status $status  -PercentComplete (($i/$createdGroups.count) * 100)   -SecondsRemaining $sleepTimeout
            for ($j = 0; $j -lt $sleepTimeout; $j++) {
                $itemExists = [bool](Get-ADGroup -filter "distinguishedName -eq '$item'")
                Write-Progress -id 1 -Activity $ProgressActivity  -Status $status  -SecondsRemaining $($sleepTimeout - $j) -PercentComplete (($i/$createdGroups.count) * 100)
                if ($itemExists) {
                    break
                } 
                start-sleep -seconds $sleepLength
            }
        }
        write-Progress -id 1 $progressActivity -Completed
        if ($MembershipChanges.count -gt 0) {
            Write-verbose "Updating memberships"
            foreach ($line in $MembershipChanges) {
                if ($PSCmdlet.ShouldProcess($line.identity,"Add child membership")) {
                    try {
                        add-adgroupMember @line
                    } catch {
                        write-warning ("Error adding {0} to {1}" -f $line.members,$line.identity)
                        #Write-warning "Name: $Name; Description: $Description; Path: $Path; Parent: $g"
                        throw $_
                    }
                }
            }
        }
    }
}