Troubleshooting OpsMgr 2007 and OpsMgr 2012 certificate issues with PowerShell

Troubleshooting OpsMgr 2007 and OpsMgr 2012 certificate issues with PowerShell

  • Comments 3
  • Likes

ToolsThis is actually an old post I found over on our archived SMSandMOM blog but the script and the information still seems to apply so I thought I’d post it again over here in case it might help. If you’re having trouble with certificate based authentication then give this a try and let us know what you think.

======

The steps for configuring certificates in System Center Operations Manager 2007 and System Center 2012 Operations Manager are numerous and one can easily get them confused. I see posts to the newsgroups and discussion lists regularly trying to troubleshoot why certificate authentication is not working, perhaps for a workgroup machine or gateway. Sometimes it takes 3 or 4 messages back and forth before I or anyone else can diagnose what the problem actually is but once this is finally done we can suggest how to fix the problem.

In an attempt to make this diagnosis stage easier I put together a PowerShell script that automatically checks installed certificates for the needed properties and configuration.  If you think everything is set up correctly but the machines just won't communicate, try running this script on each computer and it will hopefully point you to the issue. I have tried to provide useful knowledge for fixing the problems.

This script is for stand-alone PowerShell 1.0 - it does not require the OpsMgr PowerShell snapins.

Just create a text file with the contents below and save as a PS1 file.

# OMv3CertCheck.ps1
# 1/2009
#
# Update 2/2009
#    Fixes for subjectname validation
#    Typos
#    Modification for CA chain validation
#    Adds needed check for MachineKeyStore property on the private key
#
# Update 7/2009
#    Fix for workgroup machine subjectname validation
#

# Consider all certificates in the Local Machine "Personal" store
$certs = [Array] (dir cert:\LocalMachine\my\)

write-host "Checking that there are certs in the Local Machine Personal store..."
if ($certs -eq $null)
{
    Write-Host "There are no certs in the Local Machine `"Personal`" store."
    Write-Host "This is where the client authentication certificate should be imported."
    Write-Host "Check if certificates were mistakenly imported to the Current User"
    Write-Host "`"Personal`" store or the `"Operations Manager`" store."
    exit
}

write-host "Verifying each cert..."
foreach ($cert in $certs)
{
    write-host "`nExamining cert - Serial number $($cert.SerialNumber)"
    write-host "---------------------------------------------------"

    $pass = $true
     
    # Check subjectname
         
    $pass = &{
        $fqdn = $env:ComputerName
        $fqdn += "." + [DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Name
        trap [DirectoryServices.ActiveDirectory.ActiveDirectoryObjectNotFoundException]
        {
            # Not part of a domain
            continue;
        }
           
        $fqdnRegexPattern = "CN=" + $fqdn.Replace(".","\.") + '(,.*)?$'
           
        if (!( $cert.SubjectName.Name -match $fqdnRegexPattern ))
        {
            Write-Host "Cert subjectname" -BackgroundColor Red -ForegroundColor Black
            Write-Host "`tThe SubjectName of this cert does not match the FQDN of this machine."
            Write-Host "`tActual - $($cert.SubjectName.Name)"
            Write-Host "`tExpected (case insensitive)- CN=$fqdn"
            $false
        } else { $true; Write-Host "Cert subjectname" -BackgroundColor Green -ForegroundColor Black }
    }
     
    # Verify private key
           
    if (!( $cert.HasPrivateKey ))
    {
        Write-Host "Private key" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tThis certificate does not have a private key."
        Write-Host "`tVerify that proper steps were taken when installing this cert."
        $pass = $false
    } elseif (!($cert.PrivateKey.CspKeyContainerInfo.MachineKeyStore))
    {
        Write-Host "Private key" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tThis certificate's private key is not issued to a machine account."
        Write-Host "`tOne possible cause of this is that the certificate"
        Write-Host "`twas issued to a user account rather than the machine,"
        Write-Host "`tthen copy/pasted from the Current User store to the Local"
        Write-Host "`tMachine store.  A full export/import is required to switch"
        Write-Host "`tbetween these stores."
        $pass = $false
    }
    else { Write-Host "Private key" -BackgroundColor Green -ForegroundColor Black }

    # Check expiration dates
           
    if (($cert.NotBefore -gt [DateTime]::Now) -or ($cert.NotAfter -lt [DateTime]::Now))
    {
        Write-Host "Expiration" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tThis certificate is not currently valid."
        Write-Host "`tIt will be valid between $($cert.NotBefore) and $($cert.NotAfter)"
        $pass = $false
    } else { Write-Host "Expiration" -BackgroundColor Green -ForegroundColor Black }
     
     
    # Enhanced key usage extension
           
    $enhancedKeyUsageExtension = $cert.Extensions |? {$_.ToString() -match "X509EnhancedKeyUsageExtension"}
    if ($enhancedKeyUsageExtension -eq $null)
    {
        Write-Host "Enhanced Key Usage Extension" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tNo enhanced key usage extension found.`n"
        $pass = $false
    }
    else
    {
        $usages = $enhancedKeyUsageExtension.EnhancedKeyUsages
        if ($usages -eq $null)
        {
            Write-Host "Enhanced Key Usage Extension" -BackgroundColor Red -ForegroundColor Black
            Write-Host "`tNo enhanced key usages found.`n"
            $pass = $false
        }
        else
        {
            $srvAuth = $cliAuth = $false
            foreach ($usage in $usages)
            {
                if ($usage.Value -eq "1.3.6.1.5.5.7.3.1") { $srvAuth = $true}
                if ($usage.Value -eq "1.3.6.1.5.5.7.3.2") { $cliAuth = $true}
            }
            if ((!$srvAuth) -or (!$cliAuth))
            {
                Write-Host "Enhanced Key Usage Extension" -BackgroundColor Red -ForegroundColor Black
                Write-Host "`tEnhanced key usage extension does not meet requirements."
                Write-Host "`tRequired EKUs are 1.3.6.1.5.5.7.3.1 and 1.3.6.1.5.5.7.3.2"
                Write-Host "`tEKUs found on this cert are:"
                $usages |%{ Write-Host "`t$($_.Value)" }
                $pass = $false
            }
            else { Write-Host "Enhanced Key Usage Extension" -BackgroundColor Green -ForegroundColor Black }
        }
    }
     
    # KeyUsage extension
     
    $keyUsageExtension = $cert.Extensions |? {$_.ToString() -match "X509KeyUsageExtension"}
    if ($keyUsageExtension -eq $null)
    {
        Write-Host "Key Usage Extensions" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tNo key usage extension found."
        Write-Host "`tA KeyUsage extension matching 0xA0 (Digital Signature, Key Encipherment)"
        Write-Host "`tor better is required."
        $pass = $false
    }
    else
    {
        $usages = $keyUsageExtension.KeyUsages
        if ($usages -eq $null)
        {
            Write-Host "Key Usage Extensions" -BackgroundColor Red -ForegroundColor Black
            Write-Host "`tNo key usages found."
            Write-Host "`tA KeyUsage extension matching 0xA0 (DigitalSignature, KeyEncipherment)"
            Write-Host "`tor better is required."
            $pass = $false
        }
        else
        {
            if (($usages.value__ -band 0xA0) -ne 0xA0)
            {
                Write-Host "Key Usage Extensions" -BackgroundColor Red -ForegroundColor Black
                Write-Host "`tKey usage extension exists but does not meet requirements."
                Write-Host "`tA KeyUsage extension matching 0xA0 (Digital Signature, Key Encipherment)"
                Write-Host "`tor better is required."
                Write-Host "`tKeyUsage found on this cert matches:"
                Write-Host "`t$usages"
                $pass = $false
            } else { Write-Host "Key Usage Extensions" -BackgroundColor Green -ForegroundColor Black }
        }
    }
     
    # KeySpec
           
    $keySpec = $cert.PrivateKey.CspKeyContainerInfo.KeyNumber
    if ($keySpec -eq $null)
    {
        Write-Host "KeySpec" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tKeyspec not found.  A KeySpec of 1 is required"
        $pass = $false
    }
    elseif ($keySpec.value__ -ne 1)
    {
        Write-Host "KeySpec" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tKeyspec exists but does not meet requirements."
        Write-Host "`tA KeySpec of 1 is required."
        Write-Host "`tKeySpec for this cert: $($keySpec.value__)"
        $pass = $false
    } else {Write-Host "KeySpec" -BackgroundColor Green -ForegroundColor Black}
     
     
    # Check that serial is written to proper reg
           
    $certSerial = $cert.SerialNumber
    $certSerialReversed = ""
    -1..-10 |% {$certSerialReversed += $certSerial[2*$_] + $certSerial[2*$_ + 1]}
 
    if (! (Test-Path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings"))
    {
        Write-Host "Serial number written to registry" -BackgroundColor Red -ForegroundColor Black
        Write-Host "`tThe cert serial number is not written to registry."
        Write-Host "`tNeed to run MomCertImport.exe"
        $pass = $false
    }
    else
    {
        $regKeys = get-itemproperty -path "HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings"
        if ($regKeys.ChannelCertificateSerialNumber -eq $null)
        {
            Write-Host "Serial number written to registry" -BackgroundColor Red -ForegroundColor Black
            Write-Host "`tThe cert serial number is not written to registry."
            Write-Host "`tNeed to run MomCertImport.exe"
            $pass = $false
        }
        else
        {
            $regSerial = ""
            $regKeys.ChannelCertificateSerialNumber |% {$regSerial += $_.ToString("X2")}
                 
            if ($regSerial -ne $certSerialReversed)
            {
                Write-Host "Serial number written to registry" -BackgroundColor Red -ForegroundColor Black
                Write-Host "`tThe serial number written to the registry does not match this certificate"
                Write-Host "`tExpected registry entry: $certSerialReversed"
                Write-Host "`tActual registry entry:   $regSerial"
                $pass = $false
            } else { Write-Host "Serial number written to registry" -BackgroundColor Green -ForegroundColor Black }
        }
    }


    # Check that the cert's issuing CA is trusted (This is not technically required
    # as it is the remote machine cert's CA that must be trusted.  Most users leverage
    # the same CA for all machines, though, so it's worth checking

    $chain = new-object Security.Cryptography.X509Certificates.X509Chain
    $chain.ChainPolicy.RevocationMode = 0
    if ($chain.Build($cert) -eq $false )
    {
        Write-Host "Certification chain" -BackgroundColor Yellow -ForegroundColor Black
        Write-Host "`tThe following error occurred building a certification chain with this cert:"
        Write-Host "`t$($chain.ChainStatus[0].StatusInformation)"
        write-host "`tThis is an error if the certificates on the remote machines are issued"
        write-host "`tfrom this same CA - $($cert.Issuer)"
        write-host "`tPlease ensure the certificates for the CAs which issued the certificates configured"
        write-host "`ton the remote machines is installed to the Local Machine Trusted Root Authorities"
        write-host "`tstore on this machine."
    }
    else
    {
        $rootCaCert = $chain.ChainElements | select -property Certificate -last 1
        $localMachineRootCert = dir cert:\LocalMachine\Root |? {$_ -eq $rootCaCert.Certificate}
        if ($localMachineRootCert -eq $null)
        {
            Write-Host "Certification chain" -BackgroundColor Yellow -ForegroundColor Black
            Write-Host "`tThis certificate has a valid certification chain installed, but"
            Write-Host "`ta root CA certificate verifying the issuer $($cert.Issuer)"
            Write-Host "`twas not found in the Local Machine Trusted Root Authorities store."
            Write-Host "`tMake sure the proper root CA certificate is installed there, and not in"
            Write-Host "`tthe Current User Trusted Root Authorities store."
        }
        else
        {
            Write-Host "Certification chain" -BackgroundColor Green -ForegroundColor Black
            Write-Host "`tThere is a valid certification chain installed for this cert,"
            Write-Host "`tbut the remote machines' certificates could potentially be issued from"
            Write-Host "`tdifferent CAs.  Make sure the proper CA certificates are installed"
            Write-Host "`tfor these CAs."
        }

    }


    if ($pass) { Write-Host "`n***This certificate is properly configured and imported for Ops Manager use.***" }
}

Hope this helps!

J.C. Hornbeck | Solution Asset PM | Microsoft GBS Management and Security Division

Get the latest System Center news on Facebook and Twitter:

clip_image001 clip_image002

System Center All Up: http://blogs.technet.com/b/systemcenter/
System Center – Configuration Manager Support Team blog: http://blogs.technet.com/configurationmgr/
System Center – Data Protection Manager Team blog: http://blogs.technet.com/dpm/
System Center – Orchestrator Support Team blog: http://blogs.technet.com/b/orchestrator/
System Center – Operations Manager Team blog: http://blogs.technet.com/momteam/
System Center – Service Manager Team blog: http://blogs.technet.com/b/servicemanager
System Center – Virtual Machine Manager Team blog: http://blogs.technet.com/scvmm

Windows Intune: http://blogs.technet.com/b/windowsintune/
WSUS Support Team blog: http://blogs.technet.com/sus/
The AD RMS blog: http://blogs.technet.com/b/rmssupp/

App-V Team blog: http://blogs.technet.com/appv/
MED-V Team blog: http://blogs.technet.com/medv/
Server App-V Team blog: http://blogs.technet.com/b/serverappv

The Forefront Endpoint Protection blog : http://blogs.technet.com/b/clientsecurity/
The Forefront Identity Manager blog : http://blogs.msdn.com/b/ms- identity-support/
The Forefront TMG blog: http://blogs.technet.com/b/isablog/
The Forefront UAG blog: http://blogs.technet.com/b/edgeaccessblog/

Attachment: OMv3CertCheck.txt
Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • <p>Hello,</p> <p>Thank you for your script.</p> <p>An &quot;}&quot; is missing at the end of the script.</p>