Public/Get-ADCSTemplate.ps1
<#
.SYNOPSIS Retrieves Active Directory Certificate Services (ADCS) certificate templates. .DESCRIPTION Retrieves ADCS certificate templates based on name, display name, or input object. .PARAMETER Name Specifies the name of the ADCS certificate template(s) to retrieve. .PARAMETER DisplayName Specifies the display name of the ADCS certificate template(s) to retrieve. .PARAMETER InputObject Specifies an ADCSTemplate object from which to retrieve properties. .PARAMETER Properties Specifies specific properties of the ADCS certificate template to retrieve. Defaults to all properties defined in the ADCSTemplatePropertyMap. .PARAMETER Server Specifies the server to connect to for retrieving ADCS information. .OUTPUTS PSCustomObject with type 'ADCSTemplate'. .EXAMPLE PS C:\> Get-ADCSTemplate Retrieves all ADCS certificate templates. .EXAMPLE PS C:\> Get-ADCSTemplate -Name "WebServer" Retrieves the ADCS certificate template with the name "WebServer". .EXAMPLE PS C:\> Get-ADCSTemplate -DisplayName "Web Server Authentication" Retrieves the ADCS certificate template with the display name "Web Server Authentication". .EXAMPLE PS C:\> Get-ADCSTemplate -Properties Name, Created, Modified | Sort-Object Name | ft Retrieves the Created and Modified properties of all ADCS certificate templates. #> function Get-ADCSTemplate { [CmdletBinding(DefaultParameterSetName = 'Name')] [OutputType('ADCSTemplate')] param( [Parameter( Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Name' )] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [System.String]$Name, [Parameter( Mandatory = $false, Position = 0, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'DisplayName' )] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [System.String]$DisplayName, [Parameter( Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'InputObject' )] [ValidateNotNullOrEmpty()] [PSTypeName('ADCSTemplate')]$InputObject, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [PSDefaultValue(Help = 'All Properties')] [System.String[]]$Properties = ($script:ADCSTemplatePropertyMap | Select-Object -ExpandProperty ADProperty), [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [System.String]$Server ) begin { $ErrorActionPreference = 'Stop' $common = @{} if ($PSBoundParameters.ContainsKey('Server')) { $common.Server = $Server } $defaultParameters = $script:ADCSTemplatePropertyMap | Where-Object -FilterScript { $_.Mandatory -eq $true } | Select-Object -ExpandProperty ADProperty $requestProperties = [System.String[]]($defaultParameters + $Properties) # Filter unique values with a twist... powershell is not exactly consistent with case insensitity. $requestProperties = [System.String[]][System.Linq.Enumerable]::Distinct($requestProperties, [System.StringComparer]::OrdinalIgnoreCase) # $requestProperties = $defaultParameters + $Properties | Select-Object -Unique $configNC = (Get-ADRootDSE @common).configurationNamingContext $templatePath = "CN=Certificate Templates,CN=Public Key Services,CN=Services,$configNC" } process { $requestAll = $false if ($PSBoundParameters.ContainsKey('Name')) { $templateName = $Name $ldapFilter = "(&(objectClass=pKICertificateTemplate)(name=$Name))" } elseif ($PSBoundParameters.ContainsKey('DisplayName')) { $templateName = $DisplayName $ldapFilter = "(&(objectClass=pKICertificateTemplate)(displayName=$DisplayName))" } elseif ($PSBoundParameters.ContainsKey('InputObject')) { $templateName = $InputObject.Name $ldapFilter = "(&(objectClass=pKICertificateTemplate)(name=$templateName))" } else { $ldapFilter = "(objectClass=pKICertificateTemplate)" $requestAll = $true } $objects = Get-ADObject @common -SearchScope OneLevel -SearchBase $templatePath -LDAPFilter $ldapFilter -Properties $requestProperties if (-not $requestAll -and -not $objects) { $errorRecord = New-ADCSTemplateNotFoundException -Message "Template '$templateName' does not exist." $PSCmdlet.ThrowTerminatingError($errorRecord) } foreach ($object in $objects) { if ($requestProperties.Contains('*')) { # Grab all properties $exportProperties = $object.PSObject.Properties | Select-Object -ExpandProperty Name } else { $exportProperties = $requestProperties } $template = [PSCustomObject]@{ PSTypeName = "ADCSTemplate" } # Only export requested and default properties $exportProperties | ForEach-Object { $ADPropertyName = $_ $ADPropertyValue = $object.$ADPropertyName $propertyInfo = $script:ADCSTemplatePropertyMap | Where-Object -FilterScript { $_.ADProperty -eq $ADPropertyName } if ($null -ne $propertyInfo) { # if type info available, cast to AD Type $ADPropertyValue = ($ADPropertyValue -as $propertyInfo.ADType) } $template | Add-Member -Type NoteProperty -Name $ADPropertyName -Value $ADPropertyValue } Write-Output -InputObject $template } } } $propertiesArgumentCompleter = { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Command')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Parameter')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'CommandAst')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'FakeBoundParams')] param ($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams) $script:ADCSTemplatePropertyMap | Select-Object -ExpandProperty ADProperty | Where-Object { $_ -like "$wordToComplete*" } } Register-ArgumentCompleter -CommandName "Get-ADCSTemplate" -ParameterName "Properties" -ScriptBlock $propertiesArgumentCompleter |