Public/Get-PWSHCertutilShortTermExpiringCerts.ps1
|
function Get-PWSHCertutilShortTermExpiringCerts { <# .SYNOPSIS Gets certificates expiring within a specified number of days from one or all CAs in a profile. .DESCRIPTION Connects to each CA in the profile via WinRM and retrieves issued certificates whose NotAfter date falls within the next N days. The expiration threshold is substituted dynamically into the profile's restrict template at query time, so changing -Days produces a different restrict without touching the config. .PARAMETER Profile The configuration profile to use. .PARAMETER Days Expiration window in days. Accepted values: 30, 60, 90, 120. Default: 30. .PARAMETER CAFqdn Optional. Queries only this CA instead of all CAs in the profile. .PARAMETER Credential Optional PSCredential for WinRM. Defaults to current user. .EXAMPLE Get-PWSHCertutilShortTermExpiringCerts -Profile 'prod-pki' Returns certificates expiring within 30 days from all CAs in 'prod-pki'. .EXAMPLE Get-PWSHCertutilShortTermExpiringCerts -Profile 'prod-pki' -Days 90 Returns certificates expiring within 90 days. .OUTPUTS PSCustomObject[]. One object per expiring certificate with Profile, CAServer, and all configured -out fields. #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0)] [string] $Profile, [Parameter()] [ValidateSet(30, 60, 90, 120)] [int] $Days = 30, [Parameter()] [string] $CAFqdn, [Parameter()] [pscredential] $Credential ) $config = Read-ConfigFile $profileConfig = Get-ProfileConfig -Config $config -ProfileName $Profile $autoSyncArgs = @{ Config = $config; ProfileName = $Profile; ProfileConfig = $profileConfig } if ($PSBoundParameters.ContainsKey('Credential')) { $autoSyncArgs['Credential'] = $Credential } $profileConfig = Invoke-ProfileAutoSync @autoSyncArgs $fieldMap = @{} if ($profileConfig.syncState -and $profileConfig.syncState.fieldNameMap) { $profileConfig.syncState.fieldNameMap.PSObject.Properties | ForEach-Object { $fieldMap[$_.Name] = $_.Value } } $cas = if ($PSBoundParameters.ContainsKey('CAFqdn')) { $found = $profileConfig.cas | Where-Object { $_.fqdn -eq $CAFqdn } if (-not $found) { throw "CA '$CAFqdn' is not defined in profile '$Profile'." } $found } else { $profileConfig.cas } foreach ($ca in $cas) { try { $sessionArgs = @{ CAFqdn = $ca.fqdn; RemotingConfig = $profileConfig.remoting } if ($PSBoundParameters.ContainsKey('Credential')) { $sessionArgs['Credential'] = $Credential } $session = Get-CASession @sessionArgs # Compute dates on the CA server so the format and timezone match what certutil expects. $caDate = Get-CALocalDate -Session $session -Days $Days $viewParams = Get-CertutilViewParams -ProfileConfig $profileConfig -Operation 'expiringCerts' ` -Substitutions @{ TODAY = $caDate.Today; EXPIRE_DATE = $caDate.ExpireDate } $rawOutput = Invoke-CertutilView -Session $session -Restrict $viewParams.Restrict -Out $viewParams.Out ConvertFrom-CertutilCsv -RawOutput $rawOutput -FieldMap $fieldMap | Add-ResultMetadata -Profile $Profile -CAServer $ca.fqdn } catch { Write-Error "Failed to query expiring certs from '$($ca.fqdn)': $_" } } } |