Public/Install-ADCSGoat.ps1
|
function Install-ADCSGoat { <# .SYNOPSIS Deploys the full ADCSGoat lab by running the four scenario deploys. .DESCRIPTION Orchestrates the four-scenario design settled in ADCSGoat issue #19 and completed in issue #30. Each scenario clones a built-in template, applies its recipe and rights, publishes (or deliberately withholds) per its design, and records state for teardown: - ESC1 Deploy-AGEsc1 — "Copy of Web Server" (Web Server + Client Auth), Domain Users enroll, published. - ESC4 Deploy-AGEsc4 — "Test SSL" (verbatim Web Server), Domain Users Full Control, published. - ESC2+SchemaV1 Deploy-AGEsc3Chain — "VMware 6.x" (SubCA clone) + built-in User published, Authenticated Users enroll. - ESC4+ESC5 Deploy-AGEsc5Chain — "Copy of Workstation" (Workstation clone), Domain Users Full Control, NOT published; Authenticated Users Full Control on the CA object. All scenarios target a single selected enterprise CA and write a state file used by Uninstall-ADCSGoat for byte-exact teardown. .PARAMETER CAName The cn of the enterprise CA to target. Optional; autodetected when the forest has exactly one enterprise CA. .PARAMETER StatePath Where the deploy state file lives. Defaults to ADCSGoat.State.xml next to the module root. .PARAMETER Server The domain controller to write to. Defaults to the logon server. .PARAMETER Force Replaces ADCSGoat-owned existing clones without prompting. Required for non-interactive redeploy. .PARAMETER SkipLowPrivUser Skips creating the low privileged lab user and its RDP access to the PAW. .PARAMETER LowPrivUserName The sAMAccountName of the low privileged lab user. Defaults to 'user'. Letters, digits, '.', '_' and '-', up to 20 characters. .PARAMETER LowPrivUserPassword The lab user's password. Defaults to the deliberately known 'Somepass1'. .PARAMETER PawComputerName The workstation the lab user may RDP to. Found in AD when omitted: the one computer named '*-PAW'. Zero or several matches stop the install after the user is created; pass this parameter then. Runs locally when this is the current computer, otherwise through PowerShell remoting, which needs admin rights on the PAW. .EXAMPLE Install-ADCSGoat Creates the low privileged RDP user, then deploys all four scenarios against the forest's single CA. .EXAMPLE Install-ADCSGoat -CAName 'LabRootCA1' -Force -SkipLowPrivUser Redeploys all four scenarios against the named CA without the lab user. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'AD writes gated by the per-scenario collision prompt / -Force contract per module precedent.')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'The lab user is a deliberately known, low privileged credential.')] [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$CAName, [Parameter()] [ValidateNotNullOrEmpty()] [string]$StatePath, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Server, [Parameter()] [switch]$Force, [Parameter()] [switch]$SkipLowPrivUser, [Parameter()] [ValidatePattern('^[\w.-]{1,20}$')] [string]$LowPrivUserName = 'user', [Parameter()] [securestring]$LowPrivUserPassword = (ConvertTo-SecureString -String 'Somepass1' -AsPlainText -Force), [Parameter()] [ValidateNotNullOrEmpty()] [string]$PawComputerName ) begin { if ([string]::IsNullOrEmpty($StatePath)) { $StatePath = Join-Path -Path $PSScriptRoot -ChildPath '..\ADCSGoat.State.xml' } $scenarioParams = @{ StatePath = $StatePath } if ($PSBoundParameters.ContainsKey('CAName')) { $scenarioParams['CAName'] = $CAName } if ($PSBoundParameters.ContainsKey('Server')) { $scenarioParams['Server'] = $Server } if ($Force.IsPresent) { $scenarioParams['Force'] = $true } } process { # First, so an unreachable PAW fails before any template is written to AD. if (-not $SkipLowPrivUser) { $userParams = @{} if ($PSBoundParameters.ContainsKey('Server')) { $userParams['Server'] = $Server } # Created before the PAW is touched: the user must exist even when the PAW can't be found or reached. $null = New-AGLowPrivUser -UserName $LowPrivUserName -Password $LowPrivUserPassword @userParams if (-not $PSBoundParameters.ContainsKey('PawComputerName')) { $PawComputerName = Find-AGPawComputer @userParams } $serverPrefix = if ($Server) { "LDAP://$Server/" } else { 'LDAP://' } $rootDSE = New-Object System.DirectoryServices.DirectoryEntry("${serverPrefix}RootDSE") $netbiosName = Get-ADDomainNameFromNc -ConfigurationNC "$($rootDSE.configurationNamingContext)" @userParams Set-AGRdpUserAccess -ComputerName $PawComputerName -Member "$netbiosName\$LowPrivUserName" -Ensure Present } Deploy-AGEsc1 @scenarioParams Deploy-AGEsc4 @scenarioParams Deploy-AGEsc3Chain @scenarioParams Deploy-AGEsc5Chain @scenarioParams } } |