Public/Get-ADCSServer.ps1
<#
.SYNOPSIS Retrieves ADCS (Active Directory Certificate Services) server information. .DESCRIPTION Retrieves information about ADCS servers. Allows filtering by server name and can target a specific Active Directory server for the query. .PARAMETER Name Specifies the name of the ADCS server to retrieve. If not provided, all ADCS servers are retrieved. .PARAMETER Properties Specifies specific properties of the ADCS server to retrieve. Defaults to all properties defined in the ADCSServerPropertyMap. .PARAMETER Server Specifies the Active Directory server to connect to for retrieving ADCS server information. If not provided, the default server is used. .OUTPUTS PSCustomObject with type 'ADCSServer'. .EXAMPLE PS C:\> Get-ADCSServer -Server "dc01.domain.com" Retrieves information about all ADCS servers from the specified Active Directory server "dc01.domain.com". .EXAMPLE PS C:\> Get-ADCSServer -Name "Root CA" Retrieves information about the ADCS server named "Root CA". #> Function Get-ADCSServer { [CmdletBinding()] [OutputType('ADCSServer')] param( [Parameter( Mandatory = $false, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true )] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [System.String]$Name, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [SupportsWildcards()] [PSDefaultValue(Help = 'All Properties')] [System.String[]]$Properties = ($script:ADCSServerPropertyMap | Select-Object -ExpandProperty Name), [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [System.String]$Server ) begin { $ErrorActionPreference = 'Stop' $common = @{} if ($PSBoundParameters.ContainsKey('Server')) { $common.Server = $Server } $defaultParameters = $script:ADCSServerPropertyMap | Where-Object -FilterScript { $_.Mandatory -eq $true } | Select-Object -ExpandProperty Name $requestProperties = [string[]]($defaultParameters + $Properties) # Filter unique values with a twist... powershell is not exactly consistent with case insensitity. $requestProperties = [string[]][System.Linq.Enumerable]::Distinct($requestProperties, [System.StringComparer]::OrdinalIgnoreCase) # $requestProperties = $defaultParameters + $Properties | Select-Object -Unique $configNC = (Get-ADRootDSE @common).configurationNamingContext $certAuthorityPath = "CN=Certification Authorities,CN=Public Key Services,CN=Services,$configNC" # Using AIA, Certification Authorities only lists Root CA's $AIAPath = "CN=AIA,CN=Public Key Services,CN=Services,$configNC" } process { $requestAll = $false if ($PSBoundParameters.ContainsKey('Name')) { $ldapFilter = "(&(objectClass=certificationAuthority)(name=$Name))" } else { $ldapFilter = '(objectClass=certificationAuthority)' $requestAll = $true } $objects = Get-ADObject @common -SearchScope Subtree -SearchBase $AIAPath -LDAPFilter $ldapFilter -Properties $requestProperties if (-not $requestAll -and -not $objects) { $errorRecord = New-ADCSServerNotFoundException -Message "ADCS Server '$Name' 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 } $certAuthority = [PSCustomObject]@{ PSTypeName = "ADCSServer" } $exportProperties | ForEach-Object { $propertyName = $_ $propertyValue = $object.$propertyName # Transform known properties to the correct type # ADPropertyValueCollection causes issues in some functions $typeInfo = $script:ADCSServerPropertyMap | Where-Object -FilterScript { $_.Name -eq $propertyName } | Select-Object -ExpandProperty Type if ($typeInfo) { $propertyValue = ($propertyValue -as $typeInfo) } $certAuthority | Add-Member -Type NoteProperty -Name $propertyName -Value $propertyValue } # Custom property to check if root CA # CA's listed in certAuthorityPath are root CA's $ldapFilter = "(&(objectClass=certificationAuthority)(name=$($object.Name)))" if (Get-ADObject @common -SearchScope Subtree -SearchBase $certAuthorityPath -LDAPFilter $ldapFilter) { $certAuthority | Add-Member -Type NoteProperty -Name "IsRootCA" -Value $true } else { $certAuthority | Add-Member -Type NoteProperty -Name "IsRootCA" -Value $false } Write-Output -InputObject $certAuthority } } } $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:ADCSServerPropertyMap | select-Object -ExpandProperty Name | Where-Object { $_ -like "$wordToComplete*" } } Register-ArgumentCompleter -CommandName "Get-ADCSServer" -ParameterName "Properties" -ScriptBlock $PropertiesArgumentCompleter |