# encoding: ascii
# api: powershell
# title: SCOM GW Certificate AE
# description: Automation of SCOM Gateway Certificate Renewal (you need to configure autoenrollment separetly)
# version: 3.0
# type: script
# author: DollarUnderscore
# license: CC0
# x-poshcode-id: 4512
# x-archived: 2015-05-18T02:15:17
# x-published: 2015-10-08T17:36:00
#
#
#========================================================================
# Generated By: Anders Wahlqvist
# Website: DollarUnderscore (http://dollarunderscore.azurewebsites.net)
#========================================================================

# Script to automatically update SCOM Certificate registry key.

# -------------------------------
# User controlled variables below
# -------------------------------

# Specify SCOM Template name
$SCOMTemplateName="SCOM Template"

# Specify SCOM Certificate Registry Key Path
$SCOMCertRegPath="HKLM:\SOFTWARE\Microsoft\Microsoft Operations Manager\3.0\Machine Settings"

# Specify SCOM Certificate Registry Value Name
$SCOMCertRegValueName="ChannelCertificateSerialNumber"

# -------------------------------
# User controlled variables above
# -------------------------------

# Initialize new array
$ParsedCertificates=@()

# List all local certificates
$LocalCertificates=Get-ChildItem Cert:\LocalMachine\My

# Go through the certificate and parse them to get the certificate template information out
 foreach ($LocalCertificate in $LocalCertificates) {

	$ParsedCertificates+= $LocalCertificate | Select `
		Friendlyname,
		Thumbprint,
        SerialNumber,
        NotAfter,
        NotBefore,
		@{Name="Template";Expression={($_.Extensions | 
			Where-Object {$_.oid.Friendlyname -match "Certificate Template Information"}).Format(0) -replace "(.+)?=(.+)\((.+)?", '$2'}},
		@{Name="Subject";Expression={$_.SubjectName.name}}
}

# Load the serial number of the newest SCOM Certificate into a new variable
$SerialNumber=($ParsedCertificates | Where-Object { $_.Template -eq $SCOMTemplateName } | Sort-Object NotAfter -Descending | select -First 1).SerialNumber

# Reverse the serial number to match the format in the registry
$ReversedPairs=[regex]::Matches($SerialNumber,'..','RightToLeft') | ForEach-Object { $_.Value }

# Convert string to binary
$ReversedPairsInBinary=$ReversedPairs | ForEach-Object { [convert]::ToByte($_,16) }

# Load current serial number into variable
$CurrentSCOMCertificate=Get-ItemProperty -Path $SCOMCertRegPath | Select-Object $SCOMCertRegValueName -ExpandProperty $SCOMCertRegValueName

# Check if we have a new certificate
if (($ReversedPairsInBinary -join "") -eq ($CurrentSCOMCertificate -join "")) {
    Write-Output "The current certificate is the latest."
}
else {
    Write-Output "New certificate found. Changing registry..."
    # Write to registry key
    New-ItemProperty -Path $SCOMCertRegPath -Name $SCOMCertRegValueName -Value $ReversedPairsInBinary -Type Binary -Force

    Write-Output "Restarting health service..."
    # Restart the Health Service
    Restart-Service -Name HealthService -Force
}
