public/Sync-RBACSudoers.ps1

Function Sync-RBACSudoers {
    [CmdletBinding(SupportsShouldProcess=$true,DefaultParameterSetName='None')]
    Param
    (
        [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)]
        [Parameter(ParameterSetName = 'SpecificComponent', Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)]
        [ValidateScript({[bool](get-rbacOrg -org $_ )})]
                [Parameter(ValueFromPipelineByPropertyName, ValueFromPipeline)]
        [ArgumentCompleter( {
            param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
            (get-rbacOrg -org "$wordToComplete*").Org
        })]
        [String[]]$Org,

        [Parameter(ParameterSetName = 'SpecificComponent', ValueFromPipelineByPropertyName, ValueFromPipeline)]
                [ArgumentCompleter( {
            param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
            if ($fakeBoundParameters.containsKey('Org')) {
                (get-rbacComponent -org $fakeBoundParameters.Org -component "$wordToComplete*"  | sort-object -unique Component).Component
            } else {
                (get-rbacComponent -component "$wordToComplete*").Component
            }
        })]
        [String[]]$Component,
        [Microsoft.ActiveDirectory.Management.ADDirectoryServer]$Server = (get-addomainController -Writable -Discover)
    )

    BEGIN {
    }

    Process {
        if (-not $org) {

            $orgList = get-rbacOrg
            write-loghandler -level "Verbose" -message ("No Org specified; using all.")
        } else {
            $OrgList = $org | get-rbacOrg

        }
        write-loghandler -level "Verbose" -message ("{0} orgs found: `r`n--> {1}" -f $orgList.count, ($orgList.org -join "`r`n--> "))
        foreach ($orgObject in $orgList) {
            if ($orgObject.org -eq $settings.names.GlobalOU) {
                $SearchBase = $Settings.OUPaths.TenantRoot
                $ComponentList = $null
                write-loghandler -level "Verbose" -message (".....Global org, no components")
            } else {
                $searchBase = $orgObject.DistinguishedName
                if ($component) {
                    $ComponentList = get-RBACComponent -org $orgObject.org -Component $Component
                } else {
                    $ComponentList = get-rbacComponent -org $orgObject.org
                }
            }
            write-loghandler -level "Verbose" -message ("Processing org {0} at {1}" -f $orgObject.org, $searchBase)
            $NetgroupParams = @{
                name = "Netgroup-{0}" -f $orgObject.org
                Path = $Settings.OUPaths.LinuxNetgroups
                Description = "For consumption by sudoers-ldap. Replicates host membership of OU at {0}" -f $searchBase
                NISNetgroupTriple = [String[]](generateNetgroupTripleFromSearchbase -searchBase $searchBase)
            }
            $Org_netgroup = createOrSetNetgroup @NetgroupParams
            #Region This should be a function
            $sudoRole_BasePath = $Settings.OUPaths.LinuxSudoers
            $SudoRole_Path = "OU={0},{1}" -f $orgObject.Org, $sudoRole_BasePath
            $createdOU = createorsetOU -name $orgObject.Org -description "Sudoroles for $($orgObject.Org)" -path $sudorole_BasePath
            if ($ObjectGUIDs.name.contains("sudoRole")) {
                foreach ($sudoRoleType in $SUDO_ROLE_DEFS) {
                    foreach ($passwd in $SUDO_PASSWD_TYPES) {
                        write-loghandler -level "Verbose" -message "Create and / or update the group for sudo$passwd / $($sudoRoleType.name)"
                        $group_Params = @{
                            Name = "{0}-{1}-sudo{2}_{3}" -f $Settings.Names.RightsName,$orgObject.org, $passwd, $sudoRoleType.name
                            Description = "$($OrgObject.Org) - Sudoers- Right to use sudo$passwd for $($sudoRoleType.name) access: $($sudoRoleType.description)"
                            Path = "OU={0},{1}" -f "Rights", $OrgObject.DistinguishedName
                            GroupScope = $RightScope
                            Info = $sudoRoleType.SudoCommand -join "`r`n"
                        }
                        $sudoGroup = createOrSetGroup @group_Params

                        $sudorole_Settings = @{
                            Description = "Org: {0} sudo$passwd role for {1} admins (Linux)" -f $orgObject.org, $sudoRoleType.name
                            replace = @{
                                sudoCommand=$sudoRoleType.sudocommand;`
                                sudoOrder="500";`
                                sudoHost="+$($Org_netgroup.name)";`
                                sudoUser=@("%$($sudoGroup.name)", "%$($sudoGroup.sid.value)")
                            }
                        }
                        if ($passwd -eq "-nopasswd") {
                            $sudorole_Settings.replace.Add("sudoOption","!authenticate")
                        }
                        write-loghandler -level "Verbose" -message "Create and / or update the sudorole$passwd"
                        $sudoRole_Params = @{
                            name = "sudorole-{0}-sudo{1}_{2}" -f $orgObject.org, $passwd, $sudoRoleType.name
                            path = $sudoRole_Path
                            type = "sudorole"
                        }
                        $sudoRole = try {
                            new-adobject -server $server @SudoRole_Params -verbose
                        } catch [Microsoft.ActiveDirectory.Management.ADException] {
                            if ($_.exception.message -eq "An attempt was made to add an object to the directory with a name that is already in use.") {
                                write-loghandler -level "Verbose" -message "sudoRole already existed, updating."
                                get-adobject -server $server -filter "objectclass -eq 'sudoRole' -and name -eq '$($sudorole_Params.name)'"  -verbose
                            } else {
                                write-loghandler -level "warning" -message "Strange error."
                                $_.exception.message
                                throw $_
                            }
                        } catch {
                            write-warning $_.exception.getType().fullname
                            throw $_
                        }
                        $sudoRole = $sudoRole |set-adobject @sudorole_Settings  -passthru -verbose | select-object name,objectClass,distinguishedname
                    }
                }
            } else {
                write-loghandler -level "warning" -message "SudoRole schema object is missing: you may need a schema mod."
            }
            #endregion
            foreach ($componentObject in $componentList ) {
                $searchbase = $componentObject.distinguishedName
                write-loghandler -level "Verbose" -message ("Processing org {0} / Component {1} at {2}" -f $orgObject.name, $ComponentObject.name, $searchBase)
                $NetgroupParams = @{
                    name = "Netgroup-{0}-{1}" -f $orgObject.org, $componentObject.Component
                    Path = $Settings.OUPaths.LinuxNetgroups
                    Description = "For consumption by sudoers-ldap. Replicates host membership of OU at {0}" -f $searchBase
                    NISNetgroupTriple = @([String[]](generateNetgroupTripleFromSearchbase -searchBase $searchBase))
                }
                $Component_netgroup = createOrSetNetgroup @NetgroupParams
                #Region This should be a function
                $sudoRole_BasePath = "OU={0},{1}" -f $orgObject.Org, $Settings.OUPaths.LinuxSudoers
                $SudoRole_Path = "OU={0},{1}" -f $ComponentObject.Component, $sudoRole_BasePath
                $createdOU = createorsetOU -name $ComponentObject.Component -description "Sudoroles for $($orgObject.Org) - ($ComponentObject.Component)" -path $sudorole_BasePath
                if ($ObjectGUIDs.name.contains("sudoRole")) {
                    foreach ($sudoRoleType in $SUDO_ROLE_DEFS) {
                        foreach ($passwd in $SUDO_PASSWD_TYPES) {
                            write-loghandler -level "Verbose" -message "Create and / or update the group for sudo$passwd / $($sudoRoleType.name)"
                            $Group_Params = @{
                                Name = "{0}-{1}-{2}-sudo{3}_{4}" -f $Settings.Names.RightsName,$orgObject.org,$ComponentObject.Component, $passwd, $sudoRoleType.name
                                Description = "$($orgObject.Org) - $($ComponentObject.Component) - Sudoers- Right to use sudo$passwd for $($sudoRoleType.name) access: $($sudoRoleType.description)"
                                Path = "OU={0},{1}" -f "Rights", $ComponentObject.DistinguishedName
                                GroupScope = "DomainLocal"
                                Info = $sudoRoleType.SudoCommand -join "`r`n"
                            }
                            $sudoGroup = createOrSetGroup @group_Params

                            $sudorole_Settings = @{
                                Description = "{0} - {1} sudo$passwd role for {1} admins (Linux)" -f $orgObject.org, $componentObject.Component, $sudoRoleType.name
                                replace = @{
                                    sudoCommand=$sudoRoleType.sudocommand;`
                                    sudoOrder="500";`
                                    sudoHost="+$($Component_netgroup.name)";`
                                    sudoUser=@("%$($sudoGroup.name)", "%$($sudoGroup.sid.value)")
                                }
                            }
                            if ($passwd -eq "-nopasswd") {
                                $sudorole_Settings.replace.Add("sudoOption","!authenticate")
                            }
                            write-loghandler -level "Verbose" -message "Create and / or update the sudorole$passwd : $($sudoRoleType.sudoCommand)"
                            $sudoRole_Params = @{
                                name = "sudorole-{0}-{1}-sudo{2}_{3}" -f $orgObject.org, $componentObject.Component,$passwd, $sudoRoleType.name
                                path = $sudoRole_Path
                                type = "sudorole"
                            }
                            $sudoRole = try {
                                new-adobject -server $server @SudoRole_Params -verbose
                            } catch [Microsoft.ActiveDirectory.Management.ADException] {
                                if ($_.exception.message -eq "An attempt was made to add an object to the directory with a name that is already in use.") {
                                    write-loghandler -level "Verbose" -message "sudoRole already existed, updating."
                                    get-adobject -server $server -filter "objectclass -eq 'sudoRole' -and name -eq '$($sudorole_Params.name)'"  -verbose
                                } else {
                                    write-loghandler -level "warning" -message "Strange error."
                                    $_.exception.message
                                    throw $_
                                }
                            } catch {
                                write-warning $_.exception.getType().fullname
                                throw $_
                            }
                            $sudoRole = $sudoRole |set-adobject @sudorole_Settings  -passthru | select-object name,objectClass,distinguishedname
                        }
                    }
                } else {
                    write-loghandler -level "warning" -message "SudoRole schema object is missing: you may need a schema mod."
                }
                #endregion
            }
        }
    }
}