This post is based on existing OpsMgr product group (PG) post: Troubleshooting Ops Mgr Certificate issues with Powershell. For me existing script return overloaded information to user and is not quite easy for understanding. Also there is missing some points:
Another point is that what we want to get from script? I thing that we just want to know:
Nothing else we need. So, I have rewrited this script with some comments inside:
##################################################################### # OpsMgrCertChecker.ps1 # Version 1.0 # # Checks for valid OpsMgr Agent certificate and it configuration # # Vadims Podans (c) 2010 # http://en-us.sysadmins.lv/##################################################################### Write-Host @" This script will inspect Local Machine certificate store and registry settings. This will take several seconds... $("-" * 50) Script will check certificates to match the following requirements: Subject equals computer FQDN Certificate is time valid Certificate has private key and it supposed for computer certificate KeySpec is set to 1" Certificate Application Policies (in former EKU) contains both Server and Client Authentication $("-" * 50) "@ -ForegroundColor Cyan trap {continue} # get managed computer FQDN. If this workgroup computer, NetBIOS name is used $domain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name if ($domain -eq $null) { $fqdn = $Env:COMPUTERNAME } else { $fqdn = $env:COMPUTERNAME + "." + $domain } # read for existing OpsMgr Agent certificate configuration $RegKey = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings" -ErrorAction SilentlyContinue if ($RegKey.ChannelCertificateSerialNumber -ne $null) { # if configuration exist, retrieve serial number that is stored as reversed byte array $Reg = $true # reverse backward array to foreward array [array]::Reverse($RegKey.ChannelCertificateSerialNumber) # convert each byte to it hex representation and concatenate each byte to a string $SerialNumber = [string]::Join("",$($RegKey.ChannelCertificateSerialNumber | %{"{0:X2}" -f $_})) } else {$Reg = $false} # looking to local machine store for any valid certificate that match the following requirements $certs = Get-ChildItem cert:\LocalMachine\My | Where-Object { $EKUs = ($_.Extensions | Where-Object {$_.ToString() -match "X509EnhancedKeyUsageExtension"}).EnhancedKeyUsages | ForEach-Object {$_.Value} $_.Subject -match 'CN=([^,]+)' -and $fqdn -eq $matches[1] -and $_.HasPrivateKey -eq $true -and $_.NotBefore -lt [DateTime]::Now -and $_.NotAfter -gt [DateTime]::Now -and $_.PrivateKey.CspKeyContainerInfo.MachineKeyStore -eq $true -and $_.PrivateKey.CspKeyContainerInfo.KeyNumber.Value__ -eq 1 -and $EKUs -contains "1.3.6.1.5.5.7.3.1" -and $EKUs -contains "1.3.6.1.5.5.7.3.2" } if ($certs -eq $null -and $SerialNumber -eq $null) { # based on results return appropriate messages. Write-Warning "There is no valid certificates and no configuration is set for OpsMgr Agent" Write-Host @" To resolve this issue, obtain new certificate from trusted Certification Authority using the following instructions: http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=5 and install it by running the following command: MOMCertImport /Subject $fqdn "@ } elseif ($certs -eq $null -and $SerialNumber -ne $null) { Write-Warning "OpsMgr Agent is already configured to work with certificate, but this certificate don't exist in" Write-Warning "LocalComputer store or not match all certificate requirements." Write-Host @" To resolve this issue, obtain new certificate from trusted Certification Authority using the following instructions: https://www.sysadmins.lv/blog-en/trubleshoting-opsmgr-agent-certificate-issues-with-powershell.aspx and install it by running the following command: MOMCertImport /Subject $fqdn "@ } elseif ($certs -ne $null -and $SerialNumber -eq $null) { Write-Host @" There is a valid certificate(s):" $certs but neither of them is configured for OpsMgr Agent." To resolve this issue, install this certificate using the following instructions:" http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=5#import_cert1 "@ } elseif ($certs -ne $null -and $SerialNumber -ne $null) { # if configuration and valid certificates exist, check if valid certificate is the same # as written in registry. $cert = $certs | Where-Object {$_.SerialNumber -eq $SerialNumber} if ($cert -eq $null) { Write-Warning "OpsMgr Agent is already configured to work with certificate that don't exist in" Write-Warning "LocalComputer store or not match all certificate requirements." Write-Host @" However there is a valid certificate(s):" $certs To resolve this issue, install this certificate using the following instructions:" http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=5#import_cert1 "@ } else { # if valid certificate serial number match registry entry, check certificate passing it through # certificate chaining engine adding Application Policies constraints for cross-certification cases. $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain $status = $chain.Build($cert) if ($status -eq $true) { Write-Host "The existing certificate with SerialNumber:$SerialNumber match all certificate requirements" -ForegroundColor Green Write-Host "and is properly configured and imported for OpsMgr use." -ForegroundColor Green # By default (prior Windows 7/Server 2008 R2) X509Chain validate chain to CurrentUser Trusted Root CAs container # therefore we need to ensure if chain trust anchor exist in appropriate container in LocalMachine store. if ((Get-ChildItem cert:\LocalMachine\Root) -notcontains ($chain.ChainElements | select -last 1).Certificate) { Write-Warning "Root certificate is not stored in Trusted Root Certification Authorities container in" Write-Warning "LocalComputer store. Move root certificate from CurrentUser store to" Write-Warning "LocalComputer store." } else { Write-Host "Root certificate is valid and is located in Trusted Root Certification Authority" -ForegroundColor Green Write-Host "in LocalComputer store." -ForegroundColor Green } } else { Write-Warning "The existing certificate with SerialNumber:$SerialNumber match all certificate requirements" Write-Warning "but fails certificate chain validation due of the following reasons:" $chain.ChainStatus | Format-Table -AutoSize Write-Warning "If certificate is revoked - reenroll new certificate using the following instructions:" Write-Warning "http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=5" Write-Host "" Write-Warning "If certificate chain is not completed, install required Certification Authority certificates" Write-Warning "using the following instrustions:" Write-Warning "http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=5#export_ca_chain" Write-Warning "http://en-us.sysadmins.lv/Lists/Posts/Post.aspx?ID=5#distribute_ca_chain" Write-Host "" Write-Warning "If certificate fails Application Policies constraints, select another" Write-Warning "Certification Authority to enroll certificate." } } }
And some retrun examples:
PS C:\Users\TestUser\Desktop> .\1.ps1 This script will inspect Local Machine certificate store and registry settings. This will take several seconds... -------------------------------------------------- Script will check certificates to match the following requirements: Subject equals computer FQDN Certificate is time valid Certificate has private key and it supposed for computer certificate KeySpec is set to 1 Certificate Application Policies (in former EKU) contains both Server and Client Authentication -------------------------------------------------- The existing certificate with SerialNumber:1EEAF88B0000000000E6 match all certificate requirements and is properly configured and imported for OpsMgr use. WARNING: Root certificate is not stored in Trusted Root Certification Authorities container in WARNING: LocalComputer store. Move root certificate from CurrentUser store to WARNING: LocalComputer store. PS C:\Users\TestUser\Desktop> .\1.ps1 This script will inspect Local Machine certificate store and registry settings. This will take several seconds... -------------------------------------------------- Script will check certificates to match the following requirements: Subject equals computer FQDN Certificate is time valid Certificate has private key and it supposed for computer certificate KeySpec is set to 1 Certificate Application Policies (in former EKU) contains both Server and Client Authentication -------------------------------------------------- The existing certificate with SerialNumber:1EEAF88B0000000000E6 match all certificate requirements and is properly configured and imported for OpsMgr use. Root certificate is valid and is located in Trusted Root Certification Authority in LocalComputer store. PS C:\Users\TestUser\Desktop>
This is my first revision, so let me know if you have any comments or questions regarding this script.
Post your comment:
Comments: