internal/functions/Get-SchemaAdminCredential.ps1
function Get-SchemaAdminCredential { <# .SYNOPSIS Returns the credentials for the account to use for schema administration. .DESCRIPTION Returns the credentials for the account to use for schema administration. The behavior of this command is heavily controlled by the configuration system: ForestManagement.Schema.* .PARAMETER Server The server / domain to work with. .PARAMETER Credential The credentials to use for this operation. .EXAMPLE PS C:\> Get-SchemaAdminCredential @parameters Returns the configured schema credentials #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")] [OutputType([PSCredential])] [CmdletBinding()] Param ( [PSFComputer] $Server, [PSCredential] $Credential ) begin { $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential $parameters['Debug'] = $false $script:temporarySchemaUpdateUser = $null } process { #region Case: Explicit Credentials if (Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.Credential') { Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.Credential' return } #endregion Case: Explicit Credentials #region Case: Temporary Schema Admin Account if (Get-PSFConfigValue -FullName 'ForestManagement.Schema.AutoCreate.TempAdmin') { do { $newName = "$(Get-Random -Minimum 100000 -Maximum 999999)_$($env:USERNAME)" } while (Get-ADUser @parameters -LDAPFilter "(name=$newName)") $password = New-Password -Length 128 -AsSecureString Invoke-PSFProtectedCommand -ActionString 'Get-SchemaAdminCredential.Account.Creation' -Target $newName -ScriptBlock { $newUser = New-ADUser @parameters -Name $newName -Description 'Temporary Admin account used to update the schema' -AccountPassword $password -PassThru -Enabled $true -ErrorAction Stop } -EnableException $true -PSCmdlet $PSCmdlet if (-not $newUser) { return } $script:temporarySchemaUpdateUser = $newUser $domain = Get-ADDomain @parameters try { Get-ADGroup @parameters -Identity "$($domain.DomainSID)-518" | Add-ADGroupMember @parameters -Members $newUser -ErrorAction Stop } catch { Remove-ADUser -Identity $userObject @parameters $script:temporarySchemaUpdateUser = $null Stop-PSFFunction -String 'Get-SchemaAdminCredential.Account.Assignment.Failure' -StringValues $newName -EnableException $true -Cmdlet $PSCmdlet -ErrorRecord $_ } New-Object System.Management.Automation.PSCredential("$($domain.NetBIOSName)\$($newName)", $password) return } #endregion Case: Temporary Schema Admin Account #region Case: Explicit Schema Admin Account if (Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.Name') { $accountName = Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.Name' if ($accountName -like "*\*") { $accountName = $account.Split("\")[1] } $domain = Get-ADDomain @parameters $accountObject = Get-ADUser @parameters -LDAPFilter "(name=$accountName)" $schemaAdmins = Get-ADGroup @parameters -Identity "$($domain.DomainSID)-518" -Properties Members #region Scenario: Account does not exist if (-not $accountObject) { if (-not (Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.AutoCreate')) { Stop-PSFFunction -String 'Get-SchemaAdminCredential.Account.ExistsNot' -StringValues $accountName -EnableException $true -Cmdlet $PSCmdlet -Category ObjectNotFound } $password = New-Password -Length 128 -AsSecureString Invoke-PSFProtectedCommand -ActionString 'Get-SchemaAdminCredential.Account.Creation' -Target $accountName -ScriptBlock { $userObject = New-ADUser @parameters -Name $accountName -AccountPassword $password -Enabled $true -Description "Admin account for updating the schema. Created by $($env:USERDOMAIN)\$($env:USERNAME)" -PassThru -ErrorAction Stop } -EnableException $true -PSCmdlet $PSCmdlet if (-not $userObject) { return } try { Get-ADGroup @parameters -Identity "$($domain.DomainSID)-518" | Add-ADGroupMember @parameters -Members $userObject -ErrorAction Stop } catch { Remove-ADUser -Identity $userObject @parameters Stop-PSFFunction -String 'Get-SchemaAdminCredential.Account.GroupAssignment.Failure' -StringValues $accountName -EnableException $true -Cmdlet $PSCmdlet -ErrorRecord $_ } New-Object System.Management.Automation.PSCredential("$($domain.NetBIOSName)\$($accountName)", $password) return } #endregion Scenario: Account does not exist #region Fail Fast if ($schemaAdmins.Members -notcontains $accountObject.DistinguishedName) { if (-not (Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.AutoGrant')) { Stop-PSFFunction -String 'Get-SchemaAdminCredential.Account.Unprivileged' -StringValues $accountName -EnableException $true -Category ResourceUnavailable -Cmdlet $PSCmdlet } } if (-not $accountObject.Enabled) { if (-not (Get-PSFConfigValue -FullName 'ForestManagement.Schema.Account.AutoEnable')) { Stop-PSFFunction -String 'Get-SchemaAdminCredential.Account.Disabled' -StringValues $accountName -EnableException $true -Category ResourceUnavailable -Cmdlet $PSCmdlet } } #endregion Fail Fast #region Prepare account for schema administration if ($schemaAdmins.Members -notcontains $accountObject.DistinguishedName) { Invoke-PSFProtectedCommand -ActionString 'Get-SchemaAdminCredential.Account.Group.Assignment' -Target $accountName -ScriptBlock { $null = $schemaAdmins | Add-ADGroupMember @parameters -Members $accountObject -ErrorAction Stop } -EnableException $true -PSCmdlet $PSCmdlet } if (-not $accountObject.Enabled) { Invoke-PSFProtectedCommand -ActionString 'Get-SchemaAdminCredential.Account.Enable' -Target $accountName -ScriptBlock { $null = Enable-ADAccount @parameters -Identity $accountObject -ErrorAction Stop } -EnableException $true -PSCmdlet $PSCmdlet } #endregion Prepare account for schema administration #region Handle Password if (Get-PSFConfigValue -FullName 'ForestManagement.Schema.Password.AutoReset') { $password = New-Password -Length 128 -AsSecureString try { Write-PSFMessage -String 'Get-SchemaAdminCredential.Password.Reset' -StringValues $accountName $null = Set-ADAccountPassword @parameters -Identity $accountObject -NewPassword $password -ErrorAction Stop -Reset } catch { Stop-PSFFunction -String 'Get-SchemaAdminCredential.Password.Reset.Failed' -StringValues $accountName -EnableException $true -ErrorRecord $_ -Cmdlet $PSCmdlet } New-Object System.Management.Automation.PSCredential("$($domain.NetBIOSName)\$($accountName)", $password) return } else { try { $password = Read-Host -Prompt "Specify password for schema admin $accountName" -AsSecureString -ErrorAction Stop } catch { Stop-PSFFunction -String 'Get-SchemaAdminCredential.Password.InteractiveRead.Failed' -StringValues $accountName -EnableException $true -ErrorRecord $_ -Cmdlet $PSCmdlet } New-Object System.Management.Automation.PSCredential("$($domain.NetBIOSName)\$($accountName)", $password) return } #endregion Handle Password } #endregion Case: Explicit Schema Admin Account # Case: Current User Credential $Credential } } |