Public/Deploy-AGEsc3Chain.ps1
|
function Deploy-AGEsc3Chain { <# .SYNOPSIS Deploys the ESC3 enrollment chain: "VMware 6.x" plus the built-in User template. .DESCRIPTION Implements the ESC3 chain settled in ADCSGoat issue #22 (structurally ESC3, labelled "ESC2 + schema-v1 User" when scoped), riding the shared scenario pipeline (Invoke-AGTemplateScenario, issue #27). - VMware 6.x is a clone of the built-in SubCA template with NO EKU override: the no-EKU profile satisfies the Certificate-Request-Agent check (EKU absence is unrestricted per RFC 5280 4.2.1.12 + CAPI2 behavior), so nothing is added. - Authenticated Users are granted Read + Enroll, layered on the copied source DACL. - VMware 6.x is published on the selected CA. - The built-in User template is published on the selected CA if not already published. Its ACL is never changed. Preflight (issue #26) already hard-errors if Domain Users cannot enroll through User. - VMware 6.x is never added to NTAuthCertificates. The SubCA source and the User template are never written; verification asserts both are unchanged. .PARAMETER CAName The cn of the enterprise CA to publish to. 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 an ADCSGoat-owned existing clone without prompting. Required for non-interactive redeploy. .OUTPUTS System.Management.Automation.PSCustomObject with CloneCn, Oid, and CompanionOidObjectDN. .EXAMPLE Deploy-AGEsc3Chain Clones SubCA to 'VMware 6.x', grants Authenticated Users enroll, and publishes both VMware 6.x and the built-in User template. .EXAMPLE Deploy-AGEsc3Chain -CAName 'LabRootCA1' -Force Redeploys against the named CA, replacing any owned clone. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'AD writes gated by the Copy-AGTemplate collision prompt / -Force contract per module precedent.')] [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$CAName, [Parameter()] [ValidateNotNullOrEmpty()] [string]$StatePath, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Server, [Parameter()] [switch]$Force ) begin { if ([string]::IsNullOrEmpty($StatePath)) { $StatePath = Join-Path -Path $PSScriptRoot -ChildPath '..\ADCSGoat.State.xml' } $enrollGuid = [guid]'0e10c968-78fb-11d2-90d4-00c04f79dc55' $allPropsGuid = [guid]'00000000-0000-0000-0000-000000000000' # Rights: Authenticated Users Read + Enroll, layered on the copied # DACL. The pipeline resolves the well-known S-1-5-11 SID and passes it # in. No recipe: no EKU override (no-EKU profile satisfies the # Certificate-Request-Agent check). $accessRules = { param($principalSid) New-Object System.DirectoryServices.ActiveDirectoryAccessRule $principalSid, ([System.DirectoryServices.ActiveDirectoryRights]::ExtendedRight), ([System.Security.AccessControl.AccessControlType]::Allow), $enrollGuid New-Object System.DirectoryServices.ActiveDirectoryAccessRule $principalSid, ([System.DirectoryServices.ActiveDirectoryRights]::GenericRead), ([System.Security.AccessControl.AccessControlType]::Allow), $allPropsGuid } } process { $pipelineParams = @{ Scenario = 'ESC3Chain' SourceName = 'SubCA' DestinationName = 'VMware 6.x' AccessRules = $accessRules Principal = 'AuthenticatedUsers' AlsoPublishTemplate = 'User' StatePath = $StatePath } if ($PSBoundParameters.ContainsKey('CAName')) { $pipelineParams['CAName'] = $CAName } if ($PSBoundParameters.ContainsKey('Server')) { $pipelineParams['Server'] = $Server } if ($Force.IsPresent) { $pipelineParams['Force'] = $true } Invoke-AGTemplateScenario @pipelineParams } } |