Jan 152014
 

If you’re working with SCCM 2012 Desired Configuration Management and want to create a CI for local machine certificates, here’s part 1 of a 2 part equation that is evolving. The remediation script is still in the works, but for right now, here’s a script that does the following.

  1. Query the Local Machine for a list of certs assigned to it.
  2. Check the list of certs for a valid machine certificate.
  3. Verify that the certificate has not expired.
  4. Verify that the certificate has the proper template (that you specify).
  5. And finally, verify that the certificate has the proper subject (again, that you specify).
  6. If items 3, 4, and 5 are all in agreement, echo “True” back to SCCM, or “False” if no machine certs are valid.

Note that there are a few strings you need to specify. $template and $subject need to be set or this isn’t going to work. You can also set $hostname to your hearts content. There’s obviously a lot of different ways you can modify this script, but for creating a CI in SCCM 2012 DCM this is a good start. Have fun!

 
########################################################
### Check for existence of valid machine certificate ###
########################################################
#
# By Robert Hollingshead
# Contributions by Steven Buck
#
# Transform function for Template property from
# http://social.technet.microsoft.com/Forums/windowsserver/en-US/187698d0-5602-4301-9d0c-85e89d948ea2/user-powershell-to-get-the-template-used-to-create-a-certificate?forum=winserversecurity
#
#
# Checks the certificate store for a valid machine
# certificate then outputs True.
#
########################################################

# Function to get Template.
function Transform-Certificate {
[CmdletBinding()]
    param(
 [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
 [Security.Cryptography.X509Certificates.X509Certificate2]$cert
 )
    process {
        $temp = $cert.Extensions | ?{$_.Oid.Value -eq "1.3.6.1.4.1.311.20.2"}
 if (!$temp) {
            $temp = $cert.Extensions | ?{$_.Oid.Value -eq "1.3.6.1.4.1.311.21.7"}
 }
        $cert | Add-Member -Name Template -MemberType NoteProperty -Value $temp.Format(1) -PassThru
 }
}

# Assume the store doesn't contain a valid cert.
[bool]$ValidCert = $false # Assume false.

# Get hostname+fqdn
$hostname = [system.net.dns]::gethostbyname(($env:computername)).Hostname

# Put the template string to match here. * is wildcard
$template = "*{a chunk of your template name to verify}*"

# Put the subject string to match here.
$subject = "CN=$hostname"

# Analyze each certificate in Local Machine.
foreach ($Certificate in (get-childitem -Path Cert:\LocalMachine\My | Transform-Certificate))
{
    If ($Certificate.Subject -eq $subject)  # If certificate has a proper subject.
    {
        If ($Certificate.NotBefore -le (Get-Date)) # If certificate has not expired.
        {
            If ($Certificate.Template -like $template) # If cert has proper template.
            {
                $ValidCert = $true # It's true!
            }
        }
    }
}

If ($ValidCert -eq $true)
    {
        write-host "True"
    }
else
    {
        write-host "False"
    }