Get-NetCertificateHealth.ps1
<#
.Synopsis Show the TLS certificate from a remote server as a certificate file. .DESCRIPTION Obtain the TLS certificate from a remote server by name or IP address and TCP port and save it to disk. .EXAMPLE Save-NetCertificate -ComputerName www.google.com -Port 443 -Path C:\Temp\server.crt .EXAMPLE Save-NetCertificate -IP 8.8.8.8 -Port 853 -Path C:\Temp\server.crt .NOTES Adapted by: Jason Wasser Original code by: Rob VandenBrink Inspiration https://isc.sans.edu/forums/diary/Assessing+Remote+Certificates+with+Powershell/20645/ Modified: 1/9/2020 02:16:05 PM #> function Get-NetCertificateHealth { Param ( [Alias('IP')] $ComputerName, [int]$Port = 443, [int]$WarningDays = 60, [int]$CriticalDays = 30, [string[]]$WarningAlgorithm = ('sha1RSA'), [string[]]$CriticalAlgorithm = ('md5RSA'), [int]$CriticalKeySize = 1024, [int]$WarningKeySize = 2048 ) $NetCertificate = Get-NetCertificate -ComputerName $ComputerName -Port $Port $CertificateProperties = @{ ComputerName = $ComputerName + ':' + $Port FileName = 'N/A' Subject = $NetCertificate.Subject SignatureAlgorithm = $NetCertificate.SignatureAlgorithm.FriendlyName NotBefore = $NetCertificate.NotBefore NotAfter = $NetCertificate.NotAfter Days = ($NetCertificate.NotAfter - (Get-Date)).Days Thumbprint = $NetCertificate.Thumbprint KeySize = $NetCertificate.PublicKey.Key.KeySize } $Certificate = New-Object -TypeName PSObject -Property $CertificateProperties #region Check certificate expiration # Check certificate is within $WarningDays if ($Certificate.NotAfter -le (Get-Date).AddDays($WarningDays) -and $Certificate.NotAfter -gt (Get-Date).AddDays($CriticalDays)) { Write-Verbose "Certificate is expiring within $WarningDays days." $ValidityPeriodStatus = 'Warning' $ValidityPeriodStatusMessage = "Certificate expiring in $($Certificate.Days) days." } # Check certificate is within $CriticalDays elseif ($Certificate.NotAfter -le (Get-Date).AddDays($CriticalDays) -and $Certificate.NotAfter -gt (Get-Date)) { Write-Verbose "Certificate is expiring within $CriticalDays days." $ValidityPeriodStatus = 'Critical' $ValidityPeriodStatusMessage = "Certificate expiring in $($Certificate.Days) days." } # Check certificate is expired elseif ($Certificate.NotAfter -le (Get-Date)) { Write-Verbose "Certificate is expiring within $CriticalDays" $ValidityPeriodStatus = 'Critical' $ValidityPeriodStatusMessage = "Certificate expired: $($Certificate.Days) days." } # Certificate validity period is healthy. else { Write-Verbose "Certificate is within validity period." $ValidityPeriodStatus = 'OK' $ValidityPeriodStatusMessage = "Certificate expires in $($Certificate.Days) days." } #endregion #region Check certificate algorithm if ($CriticalAlgorithm -contains $Certificate.SignatureAlgorithm) { Write-Verbose "Certificate uses critical algorithm." $AlgorithmStatus = 'Critical' $AlgorithmStatusMessage = "Certificate uses a vulnerable algorithm $($Certificate.SignatureAlgorithm)." } elseif ($WarningAlgorithm -contains $Certificate.SignatureAlgorithm) { Write-Verbose "Certificate uses warning algorithm." $AlgorithmStatus = 'Warning' $AlgorithmStatusMessage = "Certificate uses the deprecated algorithm $($Certificate.SignatureAlgorithm)." } else { Write-Verbose "Certificate uses acceptable algorithm." $AlgorithmStatus = 'OK' $AlgorithmStatusMessage = "Certificate uses valid algorithm $($Certificate.SignatureAlgorithm)." } #endregion #region Check MinimumKeySize Write-Verbose 'Checking minimum key length.' if ($Certificate.KeySize -lt $CriticalKeySize) { # Key Size is critical Write-Verbose 'Certificate key length is critical.' $KeySizeStatus = 'Critical' $KeySizeStatusMessage = "Certificate key size $($Certificate.KeySize) is less than $CriticalKeySize." } elseif ($Certificate.KeySize -lt $WarningKeySize -and $Certificate.KeySize -ge $CriticalKeySize) { # Key Size is warning Write-Verbose 'Certificate key length is warning.' $KeySizeStatus = 'Warning' $KeySizeStatusMessage = "Certificate key size $($Certificate.KeySize) is less than $WarningKeySize." } elseif ($Certificate.KeySize -ge $WarningKeySize) { # Key Size is OK Write-Verbose 'Certificate key length is OK.' $KeySizeStatus = 'OK' $KeySizeStatusMessage = "Certificate key size $($Certificate.KeySize) is greater than or equal to $WarningKeySize." } else { # Key Size is OK Write-Verbose 'Certificate key length is Unknown.' $KeySizeStatus = 'Unknown' $KeySizeStatusMessage = "Certificate key size is unknown." } #endregion Write-Verbose 'Adding additional properties to the certificate object.' $CertificateProperties = [ordered]@{ ComputerName = $ComputerName + ':' + $Port FileName = $Certificate.FileName Subject = $Certificate.Subject SignatureAlgorithm = $Certificate.SignatureAlgorithm NotBefore = $Certificate.NotBefore NotAfter = $Certificate.NotAfter Days = $Certificate.Days Thumbprint = $Certificate.Thumbprint ValidityPeriodStatus = $ValidityPeriodStatus ValidityPeriodStatusMessage = $ValidityPeriodStatusMessage AlgorithmStatus = $AlgorithmStatus AlgorithmStatusMessage = $AlgorithmStatusMessage KeySize = $Certificate.KeySize KeySizeStatus = $KeySizeStatus KeySizeStatusMessage = $KeySizeStatusMessage } $Certificate = New-Object -TypeName PSObject -Property $CertificateProperties $Certificate } |