Private/Remove-AGTemplate.ps1
|
function Remove-AGTemplate { <# .SYNOPSIS Deletes an ADCSGoat-owned template object and its companion OID object. .DESCRIPTION Removes a pKICertificateTemplate object from the Certificate Templates container and, where the deleted object's msPKI-Cert-Template-OID identifies a companion msPKI-Enterprise-Oid object under CN=OID, removes that companion too. Companion ownership is established by OID equality against the owned template being replaced (the companion class cannot carry the description marker - its schema has no description attribute). Callers are responsible for only invoking this on objects already confirmed ADCSGoat-owned via the description marker. .PARAMETER Name The cn of the template object to delete. .PARAMETER Server The domain controller to write to. Defaults to the logon server. .EXAMPLE Remove-AGTemplate -Name 'Copy of Web Server' #> # ShouldProcess is deliberately not implemented: internal building block # whose delete is gated by the caller's (Copy-AGTemplate) collision # prompt / -Force contract, matching the module's existing precedent. [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Internal building block; AD deletes gated by caller collision contract per module precedent.')] [CmdletBinding()] param ( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter()] [ValidateNotNullOrEmpty()] [string]$Server ) begin { Add-Type -AssemblyName System.DirectoryServices if ([string]::IsNullOrEmpty($Server)) { $Server = [System.Net.Dns]::GetHostEntry($env:LOGONSERVER.TrimStart('\')).HostName } $rootDSE = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$Server/RootDSE") $configurationPartition = $rootDSE.configurationNamingContext $templatesContainerDN = "CN=Certificate Templates,CN=Public Key Services,CN=Services,$configurationPartition" } process { $dn = "CN=$Name,$templatesContainerDN" $path = "LDAP://$Server/$dn" if (-not [System.DirectoryServices.DirectoryEntry]::Exists($path)) { Write-Verbose "Template '$Name' not present; nothing to remove." return } $existing = New-Object System.DirectoryServices.DirectoryEntry($path) $oldOid = "$($existing.Properties['msPKI-Cert-Template-OID'].Value)" $existing.DeleteTree() $existing.Dispose() Write-Verbose "Deleted owned template '$Name'." # Remove the old companion OID object, identified by OID equality. if (-not [string]::IsNullOrEmpty($oldOid)) { $oidContainerDN = "CN=OID,CN=Public Key Services,CN=Services,$configurationPartition" $oidContainer = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$Server/$oidContainerDN") foreach ($child in @($oidContainer.Children)) { if ("$($child.Properties['msPKI-Cert-Template-OID'].Value)" -eq $oldOid) { $child.DeleteTree() Write-Verbose "Deleted companion OID object for '$oldOid'." } $child.Dispose() } $oidContainer.Dispose() } } } |