1

I have this section of code that if I can merely get the script to ONLY reply with Subject that exists (which indicates the IIS cert), then I can be done... (I have the OU enumeration, and the Invoke section down, and the email of the file for scheduling in a task): [NOTE: I have the expiration set to 500 days so I can then use the script later to merely find specific expiration times] [NOTE2: $day is set in my $profile to '$day = Get-Date -Format yyyyMMdd']

 $serverlist = $serverListpath.Name foreach($server in $serverlist){ if($server -like '#*') { continue } $threshold = 500 #Number of days to look for expiring certificates $deadline = (Get-Date).AddDays($threshold) #Set deadline date $p = ($c++/$server.count) * 100 Write-Progress -Activity "Checking $._" -Status "$p % completed" -PercentComplete $p; if(Test-Connection -ComputerName $server -Count 2 -Quiet){ #$server = "KnownIISServerHostname" #<-- to test with a hostname Invoke-Command -Verbose -ComputerName $server { Dir Cert:\LocalMachine\My } |` foreach { If ($_.NotAfter -le $deadline) { $_ | Select *| select PSComputerName, Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} } }|` select PSComputerName,Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} |` export-csv -Force -Append -Encoding ASCII -NoTypeInformation .\output\$day-ExpiringIISSSLCerts.csv } } 

So where do I tweak this to get the reply to ONLY have existing "Subject" fields; Not to get the null subject field replies (which are RDP certificates)

0

6 Answers 6

1

Try to use this:

Import-Module WebAdministration $CertAll=Get-ChildItem -Path Cert:\LocalMachine\My $CertInUse=Get-Childitem -Path IIS:\SslBindings $CertSame=Compare-Object -ReferenceObject $CertAll -DifferenceObject $CertInUse -Property ThumbPrint -IncludeEqual -ExcludeDifferent $CertSame | foreach{Get-Childitem –path Cert:\LocalMachine\My\$($_.thumbprint)} | Select-Object -Property Subject, @{n=’ExpireInDays’;e={($_.notafter – (Get-Date)).Days}} 

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

I kept getting errors on $CertInUse - This worked-: '$CertInUse= Get-ChildItem -Path IIS:SSLBindings'
Ah, there we go: '$CertInUse= (GCI IIS:SSLBindings)'
I added '-First 1' to the very end and got what I needed
1

Since IIS certificates are your scope of concern here, I would suggest using the IIS PowerShell module to make sure you're selecting only certificates that are actually in use by IIS.

The following should pull certificates attached to sites with HTTPS(SSL). I don't currently have multiple sites on a single IIS server for testing, but theoretically this should find all of them, not just the "Default Web Site."

$serverlist = $serverListpath.Name foreach($server in $serverlist){ if($server -like '#*') { continue } $threshold = 500 #Number of days to look for expiring certificates $deadline = (Get-Date).AddDays($threshold) #Set deadline date $p = ($c++/$server.count) * 100 Write-Progress -Activity "Checking $._" -Status "$p % completed" -PercentComplete $p; if(Test-Connection -ComputerName $server -Count 2 -Quiet){ #$server = "KnownIISServerHostname" #<-- to test with a hostname #Pull certificates from existing IIS bindings $certificates = Invoke-Command -Verbose -ComputerName $server { Import-Module IISAdministration $sitebindings = Get-IISSite | foreach { Get-IISSiteBinding -Protocol HTTPS -Name $_ } $thumbprints = $sitebindings.Attributes | where {$_.Name -match "certificateHash"} | Select-Object -ExpandProperty Value $thumbprints | foreach {dir Cert:\LocalMachine\My\$_} } $certificates |` foreach { If ($_.NotAfter -le $deadline) { $_ | Select *| select PSComputerName, Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} } }|` select PSComputerName,Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} |` export-csv -Force -Append -Encoding ASCII -NoTypeInformation .\output\$day-ExpiringIISSSLCerts.csv } } 

1 Comment

We can't exactly 'Install-WindowsFeature web-mgmt-console' on every IIS server, which is what you need to do to get "IISAdministration" loaded... but thanks...
0

#Complete LOCAL run script. Call this in a Foreach Invoke-command.

$CertAll=GCI -Path Cert:\LocalMachine\My $CertInUse= (GCI IIS:SSLBindings) $CertSame=Compare-Object -ReferenceObject $CertAll -DifferenceObject $CertInUse -Property ThumbPrint -IncludeEqual -ExcludeDifferent #$CertSame=Compare-Object -ReferenceObject $CertAll -Property ThumbPrint -IncludeEqual -ExcludeDifferent $CertSame | foreach{GCI -filter "" –path Cert:\LocalMachine\My\$($_.thumbprint)} | Select-Object -Property Issuer, @{n=’ExpireInDays’;e={($_.notafter – (Get-Date)).Days}} -First 1 

Thank you to @bruce-zhang

Comments

0

Similar to @bruce-zhangs's excellent answer but gets the certs in use first, then retrieves only those from the appropriate certificate stores (instead of only looking at the My cert store):

Import-Module WebAdministration $CertsInUse = Get-Childitem -Path IIS:\SslBindings $CertsInUse | foreach{Get-Childitem –path Cert:\LocalMachine\$($_.Store)\$($_.Thumbprint)} | Select-Object -Property FriendlyName,Subject, @{n=’ExpireInDays’;e={($_.notafter – (Get-Date)).Days}} 

Here it is with a more verbose foreach:

Import-Module WebAdministration $CertsInUse = Get-Childitem -Path IIS:\SslBindings $CertsDetails = @() foreach ($Cert in $CertsInUse) { $CertsDetails += Get-ChildItem -Path Cert:\LocalMachine\$($Cert.Store)\$($Cert.Thumbprint) } $CertsDetails | Select-Object -Property FriendlyName,Subject, @{n=’ExpireInDays’;e={($_.notafter – (Get-Date)).Days}} 

2 Comments

Well, yours give the FriendlyName and the Subject but not the expiration. Thankfully, our SSL Cert provider marks every certificate with their company name, so I only had to search for that too.
By "search" above I meant use "Select-String" for the Issuer context. AND, also, if you set the '$threshold' to the numbers of days your company renews certs to then you will be guaranteed to only get those certificates you are looking for (Don't forget to remove the old ones when done binding the new SSL certs) Anyway, 'checkCertExpDate-manual.ps1' above works quite well (pushed to every enumerated server with a simple 'if(test-path file)' CP at the beginning -pull is problematic), and I use the $smtp/$message variables to email the output to our team distribution list. :)
0
#checkCertExpDate-manual.ps1 $day = Get-Date -Format yyyyMMdd $threshold = 5000 #Number of days to look for expiring certificates $deadline = (Get-Date).AddDays($threshold) #Set deadline date Dir Cert:\LocalMachine\My | foreach { If ($_.NotAfter -le $deadline) { $_ | Select Issuer, Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} } } 

Then you just grep for the name:

.\checkCertExpDate-manual.ps1|Select-String -pattern "companyname" 

Now, I can set the '$threshold' to whatever I want...

I invoke this remotely, after I copied to every server, and wrote the output to a log I then email to myself automatically every week from a scheduled task.

Comments

0
#D:\batch\checkCertExpDate.ps1 $day = Get-Date -Format yyyyMMdd Set-Location d:\batch $serverlist = gc ".\serverlist.txt" foreach($server in $serverlist) { $threshold = 45 #Number of days to look for expiring certificates $deadline = (Get-Date).AddDays($threshold) #Set deadline date Invoke-Command $server { Dir Cert:\LocalMachine\My } | foreach { If ($_.NotAfter -le $deadline) { $_ | Select Issuer, Subject, NotAfter, @{Label="Expires In (Days)";Expression={($_.NotAfter - (Get-Date)).Days}} } }|select -expandproperty Subject|out-file .\output\$day-ExpiringIISSSLCerts.txt -Encoding ascii -Append } # Start mail send $log = "d:\batch\output\$day-ExpiringIISSSLCerts.txt" if(Test-Path -Path $log){ $smtpServer = "smtp.domain.com" $messageSubject = "Verify SSL Cert Check Report - " + $env:computername $message = New-Object System.Net.Mail.MailMessage $message.From = "[email protected]" $message.To.Add("[email protected]") $message.Subject = $messageSubject $message.IsBodyHTML = $true $message.Body = "<head><pre>$style</pre></head>" $message.Body += "Cert Check Report - " + $env:computername $message.Body += Get-Date $message.Body += "<br><b>Expiring Non-Prod Verify SSL Certificates Report from " + $env:computername + "</b>" $message.Attachments.Add($log) $smtp = New-Object Net.Mail.SmtpClient($smtpServer) $smtp.Send($message) } $result = Get-content $log write-host $result |format-list -View table 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.