public/Add-RBAC.ps1

Function Add-RBAC {
    <#
        .SYNOPSIS
        Creates basic OU skeleton and default rights/roles/delegations for RBAC-oriented AD
        .DESCRIPTION
        This creates several OUs that will support the RBAC system:
         * OU=Orgs
         * --> OU=Global
         * |--> AdminAccounts
         * |--> Rights
         * |--> Roles
         * |--> NewComputers (New Default Computer location)
         * |--> Users (New default user location)
         * OU=LinuxFeatures
         * --> Sudoroles
         * --> netgroups
 
        It also creates some basic rights and roles (security groups) and GPOs based on the Global template.
 
 
        .EXAMPLE
        add-rbac
        .INPUTS
        none
        .OUTPUTS
        none
    #>

    [CmdletBinding(SupportsShouldProcess=$true)]
    Param(
        [switch]$ResetRoleMembership,

        [switch]$ResetRightsMembership,

        [Microsoft.ActiveDirectory.Management.ADDirectoryServer]$Server = (get-addomainController -Writable -Discover)
    )
    Begin {

        $shouldProcess = @{
            Confirm = [bool]($ConfirmPreference -eq "low")
            Whatif = [bool]($WhatIfPreference.IsPresent)
            verbose = [bool]($VerbosePreference -ne "SilentlyContinue")
        }
    }
    PROCESS {
        write-loghandler -level "Verbose" -message "Beginning add-rbac process (DC: $($Server.Hostname))"
        $ResetParams = @{
            ResetRoleMembership = [bool]($ResetRoleMembership)
            ResetRightsMembership = [bool]($ResetRightsMembership)
        }
        try {
            Add-OUStructureFromTemplate @shouldProcess @ResetParams -asGlobal -description "Objects not specific to a business unit; users, global rights, etc"
            try {
                new-adobject -server $server -type MSDS-App-Configuration -path $Settings['OUPaths']['TenantRoot'] -name "ad-rbac"
            } catch [Microsoft.ActiveDirectory.Management.ADException] {
                if ($_.exception.innerException.message -like "The supplied entry already exists*") {
                    write-loghandler -level "Verbose" -message "MSDS-App-Configuration 'ad-rbac' already exists."
                } else {
                    throw $_
                }
            } catch {
                throw $_
            }

            try {
                new-adobject -name "_RBAC" -Path $Settings['OUPaths']['TenantRoot'] -ProtectedFromAccidentalDeletion $true -Type msMQ-Custom-Recipient -server $Server
            } catch [Microsoft.ActiveDirectory.Management.ADException] {
                if ($_.exception.innerException.message -like "The supplied entry already exists*") {
                    write-loghandler -level "Verbose" -message "MSDS-App-Configuration 'ad-rbac' already exists."
                } else {
                    throw $_
                }
            } catch {
                throw $_
            }

            if ((test-rbacFeatures).LAPS) {
                set-LapsADComputerSelfPermission -Identity $Settings['OUPaths']['TenantRoot']
            }


        write-loghandler -level "warning" -message "Finished building structure; waiting for AD to settle...."
        for ($i = 0; $i -lt $Settings.AppSettings.SleepTimeout/$Settings.AppSettings.SleepLength; $i+=$Settings.AppSettings.SleepLength) {
            if ([bool](get-adorganizationalUnit -server $server $settings['OUPaths']['DefaultUsers'])) {
                break
            }
            write-loghandler -level "Verbose" -message "Still waiting for UsersDN to appear...."
            start-sleep -seconds $Settings.AppSettings.SleepLength
        }
        if ($PSCmdlet.ShouldProcess($settings['OUPaths']['DefaultUsers'],"Redirecting default user container")) {
            $status = redirusr $settings['OUPaths']['DefaultUsers']
            if ($status -eq "Redirection was successful.") {
                Write-host ("{0,-42} : {1}" -f "Redirected default user DN to", $settings['OUPaths']['DefaultUsers'])
            } else {
                write-loghandler -level "warning" -message ("{0,-42} : {1}" -f "Failed to redirect default user DN to", $settings['OUPaths']['DefaultUsers'])
                write-loghandler -level "warning" -message ($status -join "`r`n" -replace "`r`n`r`n","`r`n")
            }
        }

        if ($PSCmdlet.ShouldProcess($settings['OUPaths']['DefaultComputers'],"Redirecting default computer container")){
            $status = redircmp $settings['OUPaths']['DefaultComputers']
            if ($status -eq "Redirection was successful.") {
                Write-host ("{0,-42} : {1}" -f "Redirected default computer DN to", $settings['OUPaths']['DefaultComputers'])
            } else {
                write-loghandler -level "warning" -message ("{0,-42} : {1}" -f "Failed to redirect default computer DN to", $settings['OUPaths']['DefaultComputers'])
                write-loghandler -level "warning" -message ($status -join "`r`n" -replace "`r`n`r`n","`r`n")
            }
        }
    } catch {
        $_.Exception.getType().fullname
        $_ | format-list * -force
    }

    }
}