Private/Test-IsUniqueOID.ps1
Function Test-IsUniqueOID { <# .SYNOPSIS Checks if a given Certificate Template OID is unique within the specified context. .DESCRIPTION This function queries Active Directory to determine if a given Certificate Template OID is already in use within the specified configuration context. It returns $True if the OID is unique and $False if it already exists. The function performs the following validations: - Verifies the OID format - Checks the connection to the specified AD server - Validates the configuration naming context - Ensures proper access rights .PARAMETER cn Specifies the Common Name (CN) of the Certificate Template. Must be a valid CN format string. .PARAMETER TemplateOID Specifies the OID (Object Identifier) of the Certificate Template. Must be in valid OID format (e.g., 1.3.6.1.4.1.311.21.8.1234567.1234567). .PARAMETER Server Specifies the Active Directory server to query. Must be a valid FQDN of a domain controller. .PARAMETER ConfigNC Specifies the Configuration Naming Context (ConfigNC) to search for the Certificate Template. Must be a valid AD path starting with "CN=Configuration,". .INPUTS System.String You can pipe string values for all parameters to this function. .OUTPUTS System.Boolean Returns $True if the Certificate Template OID is unique, and $False if it already exists. .EXAMPLE Test-IsUniqueOID -cn "WebServer2025" ` -TemplateOID "1.3.6.1.4.1.311.21.8.1234567.1234567" ` -Server "DC01.contoso.com" ` -ConfigNC "CN=Configuration,DC=contoso,DC=com" Checks if the Certificate Template OID is unique in the specified context. .EXAMPLE $splat = @{ cn = "UserAuth2025" TemplateOID = "1.3.6.1.4.1.311.21.8.7654321.7654321" Server = "DC01.contoso.com" ConfigNC = "CN=Configuration,DC=contoso,DC=com" } Test-IsUniqueOID @splat -Verbose Checks template uniqueness with verbose output using splatting. .NOTES Used Functions: Name ║ Module/Namespace ═══════════════════════════════════════╬══════════════════════════════ Get-ADObject ║ ActiveDirectory Write-Verbose ║ Microsoft.PowerShell.Utility Write-Debug ║ Microsoft.PowerShell.Utility Write-Error ║ Microsoft.PowerShell.Utility .NOTES Version: 2.1 DateModified: 22/May/2025 LastModifiedBy: Vicente Rodriguez Eguibar vicente@eguibar.com Eguibar IT http://www.eguibarit.com .LINK https://github.com/vreguibar/EguibarIT/blob/main/Private/Test-IsUniqueOID.ps1 .COMPONENT PKI .ROLE Certificate Management .FUNCTIONALITY OID Validation #> [CmdletBinding( SupportsShouldProcess = $false, ConfirmImpact = 'Low' )] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specifies the Common Name (CN) of the Certificate Template')] [ValidateNotNullOrEmpty()] [ValidatePattern('^[a-zA-Z0-9\s-_]+$')] [Alias('CommonName', 'Name')] [string] $cn, [Parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specifies the OID of the Certificate Template')] [ValidateNotNullOrEmpty()] [ValidatePattern('^\d+(\.\d+)*$')] [Alias('OID')] [string] $TemplateOID, [Parameter(Mandatory = $true, Position = 2, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specifies the Active Directory server to query')] [ValidateNotNullOrEmpty()] [Alias('DomainController', 'DC')] [string] $Server, [Parameter(Mandatory = $true, Position = 3, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Specifies the Configuration Naming Context')] [ValidateNotNullOrEmpty()] [ValidatePattern('^CN=Configuration,(?:CN|DC)=')] [Alias('ConfigurationNC', 'ConfigurationNamingContext')] [string] $ConfigNC ) Begin { Set-StrictMode -Version Latest ############################## # Module imports ############################## # Variables Definition [hashtable]$Splat = [hashtable]::New([StringComparer]::OrdinalIgnoreCase) $SearchBase = 'CN=OID,CN=Public Key Services,CN=Services,{0}' -f $ConfigNC $Filter = '{ cn -eq {0} -and msPKI-Cert-Template-OID -eq {1} }' -f $cn, $TemplateOID Write-Debug -Message ('Search base: {0}' -f $SearchBase) Write-Debug -Message ('Filter: {0}' -f $Filter) } #end Begin Process { try { Write-Debug -Message ('Checking uniqueness for OID {0} on server {1}' -f $TemplateOID, $Server) # Query Active Directory for the Certificate Template $Splat = @{ Server = $Server SearchBase = $SearchBase Filter = $Filter Properties = 'cn', 'msPKI-Cert-Template-OID' ErrorAction = 'Stop' } $Search = Get-ADObject @Splat # If the Certificate Template is found, it's not unique if ($Search) { Write-Verbose -Message 'Certificate Template with OID {0} already exists.' -f $TemplateOID return $false } else { Write-Verbose -Message 'Certificate Template with OID {0} is unique.' -f $TemplateOID return $true } #end If } catch [Microsoft.ActiveDirectory.Management.ADServerDownException] { Write-Error -Message ('Failed to connect to server {0}' -f $Server) throw } catch [Microsoft.ActiveDirectory.Management.ADException] { Write-Error -Message ('Access denied or invalid search path: {0}' -f $SearchBase) throw } catch { Write-Error -Message ('An unexpected error occurred: {0}' -f $_.Exception.Message) throw } #end Try-Catch } #end Process End { } #end End } #end Function Test-IsUniqueOID |