Home > PowerShell > Function: Test-InvalidCerts – Ensuring Certificates Are In The Correct Certificate Store

Function: Test-InvalidCerts – Ensuring Certificates Are In The Correct Certificate Store

I learned some very valuable lessons on my first Lync Server deployment. If Lync doesn’t work, it’s probably certificate related. That’s still the case with Skype for Business. Simple certificate issues can cause all kinds of problems. That’s why I’ve written about them in Lync Users Can’t Download Address Book if Certificate Uses CNG and One Liner: Add Trusted Root Cert Authorities to Edge Servers (among others). Today I again saw another issue around McAfee solutions and Front End services not starting (see An intermediate certificate is installed under “Trusted Root Certification Authorities” for more info). Turns out some certificates are in the wrong certificate store. An example would be an intermediate certificate improperly placed in the ‘Trusted Root Certification Authorities’. The solution is to just move the cert into the correct store. But rather than manually looking at each one, surely there is a way to check them all and move them to the right store! Well, Shirley (see what I did there?), there is.

Here is a simple function that checks both the intermediate and trusted root stores for certificates that should be in the opposite store. If it finds them, it will move them. Run this in an elevated PowerShell session.

function Test-InvalidCert {
  <#
  .SYNOPSIS
    Checks root and intermediate certificate stores for certificates in the wrong store & moves them to the correct store.

  .DESCRIPTION
    Checks root and intermediate certificate stores for certificates in the wrong store & moves them to the correct store. Certificates in the wrong store can be very problematic for Lync Server and Skype for Business Server.

  .NOTES
    Version               : 1.2
    Wish list             : 
    Rights Required       : Local administrator on server
    Sched Task Required   : No
    Lync/Skype4B Version  : N/A
    Author/Copyright      : © Pat Richard, Office Servers and Services (Skype for Business) MVP - All Rights Reserved
    Email/Blog/Twitter    : pat@innervation.com  https://ucunleashed.com  @patrichard
    Donations             : https://www.paypal.me/PatRichard
    Dedicated Post        : https://ucunleashed.com/3903
    Disclaimer            : You running this script means you won't blame author(s) if this breaks your stuff. This script is
                            provided AS IS without warranty of any kind. Author(s) disclaim all implied warranties including,
                            without limitation, any implied warranties of merchantability or of fitness for a particular
                            purpose. The entire risk arising out of the use or performance of the sample scripts and
                            documentation remains with you. In no event shall author(s) be liable for any damages whatsoever
                            (including, without limitation, damages for loss of business profits, business interruption,
                            loss of business information, or other pecuniary loss) arising out of the use of or inability
                            to use the script or documentation. Neither this script, nor any part of it other than those
                            parts that are explicitly copied from others, may be republished without author(s) express written 
                            permission.
    Acknowledgements      :
    Assumptions           : ExecutionPolicy of AllSigned (recommended), RemoteSigned, or Unrestricted (not recommended)
    Limitations           :
    Known issues          : None yet, but I'm sure you'll find some!

  .LINK
    
Function: Test-InvalidCerts – Ensuring Certificates Are In The Correct Certificate Store
.EXAMPLE .\Test-InvalidCerts.ps1 Description ----------- Checks root and intermediate store for certs in the wrong store & moves them to the proper store. .INPUTS None. You cannot pipe objects to this script. #> [CmdletBinding(SupportsPaging)] param( ) # end of param block process{ Write-Verbose -Message 'Checking for improper certs in root store' $InvalidCertsInRoot = Get-Childitem -Path cert:\LocalMachine\root -Recurse | Where-Object {$_.Issuer -ne $_.Subject} if ($InvalidCertsInRoot){ Write-Verbose -Message ('{0} invalid certificates detected in Root Certificate Store' -f $InvalidCertsInRoot.count) ForEach ($cert in $InvalidCertsInRoot){ Write-Verbose -Message ('Moving `"{0}`" to intermediate certificate store' -f $cert.subject) Move-Item -Path $cert.PSPath -Destination Cert:\LocalMachine\CA } }else{ Write-Verbose -Message 'No invalid certs found in Root Certificate Store' } $InvalidCertsInInt = Get-Childitem -Path cert:\LocalMachine\Ca -Recurse | Where-Object {$_.Issuer -eq $_.Subject} if ($InvalidCertsInInt){ Write-Verbose -Message ('{0} invalid certificates detected in Intermediate Certificate Store' -f $InvalidCertsInInt.count) ForEach ($cert in $InvalidCertsInInt){ Write-Verbose -Message ('Moving `"{0}`" to root certificate store' -f $cert.subject) Move-Item -Path $cert.PSPath -Destination Cert:\LocalMachine\Root } }else{ Write-Verbose -Message 'No invalid certs found in Intermediate Certificate Store' } } } # end function Test-InvalidCert

All output is verbose, so if you want to see what it’s doing, run the function with -Verbose.

Donations

I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.

Categories: PowerShell Tags:
  1. Wayne
    April 24th, 2017 at 04:48 | #1

    Hi, This works great on 2012R2, but errors when running on a 2008R2 server in ?, can’t see why ?. ANy help greatly appreciated

    The “=” operator is missing after a named argument.
    At C:\temp\Test-InvalidCerts.ps1:47 char:33
    + [CmdletBinding(SupportsPaging) <<<< ]
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

  2. wayne
    April 25th, 2017 at 02:46 | #2

    Hi This works great on 2012 R2 servers but errors on 2008 R2

    The “=” operator is missing after a named argument.
    At C:\temp\Test-InvalidCerts.ps1:47 char:33
    + [CmdletBinding(SupportsPaging) <<<< ]
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

  3. wayne
    April 25th, 2017 at 03:24 | #3

    Hi Pat, thanks , is it simple to change it to work with PowerShell 2.0 as the bulk of our estate is 2008R2

  1. March 17th, 2017 at 17:13 | #1