private/CreateOrSetOU.ps1

function CreateOrSetOU {
    [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,
        $newVariable
    )
    BEGIN {
        $CreatedOUs = [System.Collections.Generic.List[String]]::new()
        $RootDSE = [adsi]"LDAP://RootDSE"
        $DefaultOU_SDDL = (get-adobject -filter { (ldapDisplayName -eq "organizationalUnit") } -searchBase ($rootDSE.SchemaNamingContext[0]) -properties defaultSecurityDescriptor).defaultSecurityDescriptor
        $defaultOU_ACL = [System.DirectoryServices.ActiveDirectorySecurity]::new()
        $defaultOU_ACL.SetSecurityDescriptorSddlForm($defaultOU_SDDL)
    }
    PROCESS {
        if ($PsItem.Name) { $Name = $_.Name}
        if ($PsItem.Description) {$Description = $_.Description}
        if ($PsItem.Path) {$Path = $_.Path}

        if ($path -ne $((get-addomain).distinguishedName)) {
            if (-not (Get-ADOrganizationalUnit -filter "distinguishedname -eq '$path'")) {
                write-verbose "Parent OU '$path' doesn't seem to exist; waiting...."
                start-sleep -seconds 1
            }
        }

        $OU_DN = "OU=$name,$path"
        $OUParams = @{
            Description = $Description
            ProtectedFromAccidentalDeletion = $True
        }
        
        if ($PSCmdlet.ShouldProcess($OU_dn,"Setting Description, ACL, and protection on OU")){
            try {
                Set-ADOrganizationalUnit -Identity $OU_DN @OUParams -confirm:$False -passthru
                set-ACL -path "AD:$OU_DN" -AclObject $defaultOU_ACL
            } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
                write-verbose " OU didn't exist; creating"
                try {
                    New-ADOrganizationalUnit -name $name -path $path @OUParams -confirm:$False -passthru
                    $CreatedOUs.add($OU_DN)                    
                } catch {
                    Write-warning ("Error creating OU {0} at {1} with Description {2}" -f $OUParams.name, $OUParams.Path, $OUParams.Description)
                    throw $_
                }
            } catch {
                Write-warning ("Error setting OU {0} at {1} with Description {2}" -f $OUParams.name, $OUParams.Path, $OUParams.Description)
                throw $_
            }
        }
    }

    END {
        for ($i = 0; $i -lt $CreatedOUs.count; $i++) {
        #foreach ($OU in $CreatedOUs) {
            $ProgressActivity = "Waiting for creation of new OUs (total: {0} " -f $CreatedOUs.count
            $OU = $CreatedOUs[$i]
            Write-Progress -Activity $ProgressActivity -PercentComplete (($i/$createdOUs.count) * 100)
            try {
                Get-ADOrganizationalUnit -identity $OU | out-null
            } catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] {
                for ($j = 0; $j -lt $sleepTimeout; $j+=$sleepLength) {
                    $OUExists = [bool](Get-ADOrganizationalUnit -filter "distinguishedName -eq '$OU'")
                    if ($OUExists) {
                        break
                    }
                    $status = "Checking $OU (waiting for $j seconds)"
                    Write-Progress -Activity $ProgressActivity -Status $status -CurrentOperation $status -SecondsRemaining $($sleepLength - $j)
                    start-sleep -seconds $sleepLength
                }
                Write-Progress -Activity $ProgressActivity -completed
            } catch {
                throw $_
            }
            Write-Progress -Activity $ProgressActivity -completed
        }
    }
}