Pulling SSL certs from a local Certificate store
I am wondering if any one has been able to pull SSL certificate info from a servers local computer certificate store. I can get on the server and run the below PowerShell command and it pulls all of the SSL certificates that i expect. When i create a custom datasource to run this same PowerShell command its only pulling the SSL certificates for my local session.
Get-item Cert:\LocalMachine\my\* | select-object certificatedomains,issuer,status,notbefore,subject
I can run this command without admin rights, i am suspecting that Logic Monitor is using WMI to run this and for some reason it isnt allow of some sort. I have searched all of the docs and cannot find anything on how to do this. Any help is greatly appreciated.
I created a module for this some time back -- should be in the Exchange. I just looked at ours, though, and it is marked ‘Security Review’ which is super annoying since it was submitted 2 years ago at least -- LM has no apparent workflow for the Exchange, just have to find the right person to poke (if you get lucky). There should at least be some sort of “escalate” button on those to get someone’s attention.
I also don’t think the version posted is our current version (we added some code later to avoid expired certs in some cases). Here is the full source code (AD and collection). Somewhat ironically, the code handler for the forum post editor does not include “PowerShell”.
$TargetHostName = '##SYSTEM.SYSNAME##'
$CollectorHostName = $env:computername
$TargetUserName = '##wmi.user##'
$TargetPassword = '##wmi.pass##'
$DebugMode = $false
$ScriptBlock = {
param (
[bool]$Debug
)
# Certificates need to have a lifespan of at least this number of days to be considered.
$MinLifeSpan = 30
# Certificates that are expired by more than this many days are ignored.
$MaxExpired = 60
$AllCerts = @()
$CertExpire = @{}
$CertList = Get-ChildItem -Path cert:LocalMachine -Recurse -SSLServerAuthentication
Foreach ($Cert in $CertList) {
$SerialNumber = $Cert.SerialNumber
$FriendlyName = $Cert.FriendlyName;
$Name = ""
if ($FriendlyName -eq "")
{
$Name = $SerialNumber
}
else
{
$Name = "$FriendlyName - $SerialNumber"
}
$NotBefore = $Cert.NotBefore
$NotAfter = $Cert.NotAfter
$LifeSpan = New-TimeSpan -Start $NotBefore -End $NotAfter
$LifeSpanDays = $LifeSpan.Days
$Expired = New-TimeSpan -Start $NotAfter -End (Get-Date)
$ExpiredDays = $Expired.Days
if (($SerialNumber -ne "") -AND ($LifeSpanDays -gt $MinLifeSpan) -AND ($ExpiredDays -lt $MaxExpired)) {
$Props = @()
$propPrefix = "auto.windowscerts"
$Props += "${propPrefix}.serialnum=$SerialNumber"
$Store = ($Cert.PSParentPath -split "::")[1]
#
# Add this store to the cert expiration tracking hashtable if it isn't
# there already
#
if ( -not $CertExpire.ContainsKey($Store) ){
$CertExpire[$Store] = @{}
}
$Props += "${propPrefix}.lifespan_days=$LifeSpanDays"
if ($Store -ne "") { $Props += "${propPrefix}.store=$Store" }
if ($NotBefore -ne "") { $Props += "${propPrefix}.starts=$NotBefore" }
if ($NotAfter -ne "") { $Props += "${propPrefix}.expires=$NotAfter" }
$Subject = $Cert.Subject
if ($Subject -ne "") { $Props += "${propPrefix}.subject=$Subject" }
$Issuer = $Cert.Issuer
if ($Issuer -ne "") { $Props += "${propPrefix}.issuer=$Issuer" }
$Thumbprint = $Cert.Thumbprint
if ($Thumbprint -ne "") { $Props += "${propPrefix}.thumbprint=$Thumbprint" }
$DNSNameList = $Cert.DNSNameList
if ($DNSNameList -ne "") { $Props += "${propPrefix}.dnsnames=$DNSNameList" }
# If $ExpiredDays is negative it means the cert has not expired yet.
# We care about all non-expired certs but only the most recent of expired certs with
# the same CN in the same store
$AllCerts += @{
Subject = $Subject
Store = $Store
Name = $Name
SerialNumber = $SerialNumber
ExpiredDays = $ExpiredDays
Props = $Props
}
if ( $CertExpire[$Store].ContainsKey($Subject) ){
if ( $ExpiredDays -lt $CertExpire[$Store][$Subject] ){
$CertExpire[$Store][$Subject] = $ExpiredDays
}
}
else {
$CertExpire[$Store][$Subject] = $ExpiredDays
}
# Write-Host "$SerialNumber##$Name##$Subject####", ($Props -join '&')
}
}
foreach ( $Cert in $AllCerts ){
$Subject = $Cert.Subject
$Store = $Cert.Store
$ExpiredDays = $Cert.ExpiredDays
if ( ($ExpiredDays -gt 0) -AND ($ExpiredDays -gt $CertExpire[$Store][$Subject]) ){
# Don't care about expired certs when a newer one exists in the same store
# with the same Subject
continue
}
$SerialNumber = $Cert.SerialNumber
$Name = $Cert.Name
$Props = $Cert.Props
Write-Host "$SerialNumber##$Name##$Subject####", ($Props -join '&')
}
}
if ($TargetHostName -eq $CollectorHostName)
{
Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList @($DebugMode)
}
else
{
#If WMI creds undefined - invoke remote command without creds, if not - create credential object and use it for authorization
if (($TargetUserName -Match "wmi.user" -and $TargetPassword -Match "wmi.pass") -or
($TargetUserName -eq "" -and $TargetPassword -eq ""))
{
Invoke-Command -ComputerName $TargetHostName -ScriptBlock $ScriptBlock -ArgumentList @($DebugMode)
}
else
{
$TargetCredentials = New-Object System.Management.Automation.PSCredential ($TargetUserName, $(ConvertTo-SecureString $TargetPassword -AsPlainText -Force))
Invoke-Command -ComputerName $TargetHostName -ScriptBlock $ScriptBlock -Credential $TargetCredentials -ArgumentList @($DebugMode)
}
}
Exit 0$Instance = '##WILDVALUE##'
$TargetHostName = '##SYSTEM.SYSNAME##'
$CollectorHostName = $env:computername
$TargetUserName = '##wmi.user##'
$TargetPassword = '##wmi.pass##'
$DebugMode = $false
$ScriptBlock = {
param (
[bool]$Debug,
[String]$SerialNumber
)
if ($Cert = Get-ChildItem -Path cert:LocalMachine -Recurse | Where-Object { $_.SerialNumber -eq $SerialNumber }) {
# NotAfter can return multiple values, we'll just take the first (zeroth) one using [0]
$TimeSpan = New-TimeSpan -Start (Get-Date) -End $Cert.NotAfter[0]
$DaysLeft = $TimeSpan.Days
Write-Host "DaysLeft=$DaysLeft"
}
}
if ($TargetHostName -eq $CollectorHostName)
{
Invoke-Command -ScriptBlock $ScriptBlock -ArgumentList @($DebugMode,$Instance)
}
else
{
#If WMI creds undefined - invoke remote command without creds, if not - create credential object and use it for authorization
if (($TargetUserName -Match "wmi.user" -and $TargetPassword -Match "wmi.pass") -or
($TargetUserName -eq "" -and $TargetPassword -eq ""))
{
Invoke-Command -ComputerName $TargetHostName -ScriptBlock $ScriptBlock -ArgumentList @($DebugMode,$Instance)
}
else
{
$TargetCredentials = New-Object System.Management.Automation.PSCredential ($TargetUserName, $(ConvertTo-SecureString $TargetPassword -AsPlainText -Force))
Invoke-Command -ComputerName $TargetHostName -ScriptBlock $ScriptBlock -Credential $TargetCredentials -ArgumentList @($DebugMode,$Instance)
}
}
Exit 0