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:

  • certificates might be issued from 3rd party Certification Authorities (CAs) and not always has SerialNumber fixed length. Therefore in some cases it incorrectly converts certificate serial number to it actual value;
  • by default X509Chain.Build() method (for Operating Systems prior Windows 7/Server 2008 R2) by default attempts to build a chain up to any root certificate that is stored in Trusted Root CAs container in CurrentUser store. This means that while original script return "Ok" status, OpsMgr Agent may not work with this certificate, because root certificate don't exist in Trusted Root CAs in LocalMachine store;

Another point is that what we want to get from script? I thing that we just want to know:

  • Is there any certificate configuration in OpsMgr Agent or no?
  • Is there any applicable certificate for OpsMgr Agent?
  • If yes, we have, does registry settings matches to one of the valid certificate?

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.


Share this article:

Comments:


Post your comment:

Please, solve this little equation and enter result below. Captcha