public/add-ADSchemaMod.ps1
<#
.Synopsis Adds predefined AD Schema modifications related to RBAC .DESCRIPTION Implements predefined schema mods like sshpublickey, sudoroles, and LAPS. Must be run from a Domain Controller with Schema admin rights .EXAMPLE Add-ADSchemaMod -name sshpublickey Adds 'sshPublicKey' attribute to user objects in AD. This allows you to define public key auth centrally and avoid trhe use of authorized_keys. This requires a correctly-configured sssd and sshd on the Linux clients, example below: sssd.conf: [sssd] services = nss, pam, sudo, ssh <...snip...> [domain/$DOMAIN] ldap_user_extra_attrs = sshPublicKey:sshPublicKey,phone:telephoneNumber,email:mail ldap_user_ssh_public_key = sshPublicKey sshd_config: <....snip...> AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys AuthorizedKeysCommandUser nobody .EXAMPLE Add-ADSchemaMod -name SudoRoles Adds 'sudoRole' object definition to the schema, allowing Linux hosts using a correctly-configured sssd to pull sudoers definitions via LDAP. Examples of this config can be found under the `misc` folder, but the key elements are a correctly-configured nsswitch.conf and sssd.conf: nsswitch.conf: <...snip...> sudoers: sss files sssd.conf: (replace variables) [sssd] services = nss, pam, sudo, ssh <...snip...> [domain/$DOMAIN] ldap_netgroup_search_base = OU=Netgroups,OU=LinuxFeatures,DC=$DOMAIN?subtree? ldap_sudo_search_base = OU=SudoRoles,OU=LinuxFeatures,DC=$DOMAIN?subtree? .EXAMPLE Add-ADSchemaMod -name LAPS .OUTPUTS $Null .NOTES Requires Schema Admin, Enterprise Admin, and Domain Admin. This will briefly turn on the "Schema Updates Allowed" registry setting for NTDS #> function add-ADSchemaMod { [CmdletBinding(SupportsShouldProcess=$true)] param( # The name of the schema modification. Tab-completion will show available options [ValidateScript({[bool](get-RBACSchemaMods -name $_)})] [ArgumentCompleter( {@((get-RBACSchemaMods).name)})] [string]$Name ) begin { $DomainProperties = get-ADDomain $domainDN = $domainProperties.distinguishedName $DomainDNS = $domainProperties.DNSRoot $DomainSID = $domainProperties.DomainSID $SID_DomainAdmin = "$DomainSID-512" $SID_EnterpriseAdmin = "$DomainSID-519" $SID_SchemaAdmin = "$DomainSID-518" $GroupInfo = get-currentUserGroups $PreChecks = @{ IsDomainAdmin = $groupInfo.sid.contains($SID_DomainAdmin) IsEnterpriseAdmin = $groupInfo.sid.contains($SID_EnterpriseAdmin) IsSchemaAdmin = $groupInfo.sid.contains($SID_SchemaAdmin) OnDomainController = [bool](get-wmiObject -query "Select * from Win32_OperatingSystem where ProductType='2'") } if ($PreChecks.values -contains $false) { Write-warning "Please run this from a domain controller with Domain-, Enterprise-, and Schema-Admin rights." Write-warning "See below for failing checks" foreach ($check in $PreChecks.getEnumerator()) { write-warning (" * {0,-24} : {1}" -f $check.name, $check.value) } Break } $schemaBaseDirectory = "\\$DomainDNS\SYSVOL\$DomainDNS" $registryMod = @{ path = "Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters" Name = "Schema Update Allowed" } if ($PSCmdlet.ShouldProcess("$($registryMod.path) : $($registryMod.Name)","Enabling Schema modifications in registry")) { New-ItemProperty @RegistryMod -propertyType DWord -value 1 -confirm:$false } } Process { $schemaDef = get-RBACSchemaMods -name $name $modName = $schemaDef.name $LDIF_Document = $schemaDef.Value.LDIF_Document $SchemaCommand = $schemaDef.Value.Command $schemaFileName = "$modName.schema.activeDirectory" $schemaFilePath = "$schemaBaseDirectory\$SchemaFileName" if ($LDIF_Document) { if ($PSCmdlet.ShouldProcess($SchemaFilePath, "Importing Schema file")) { $LDIF_Document | out-file -filePath $SchemaFilePath ldifde -i -f $schemaFilePath -c "CN=Schema,CN=Configuration,DC=X" "CN=Schema,CN=Configuration,$DomainDN" -j "C:\" } } if ($SchemaCommand) { if ($PSCmdlet.ShouldProcess($schemaCommand,"Running Schema Command")) { invoke-Expression -command $schemaCommand } } } End { if ($PSCmdlet.ShouldProcess("$($registryMod.path) : $($registryMod.Name)","Disabling Schema modifications in registry")) { Remove-ItemProperty @RegistryMod -confirm:$False } } } |