Reputation: 171
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)
Upvotes: 1
Views: 8317
Reputation: 171
#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
Upvotes: 0
Reputation: 171
#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.
Upvotes: 0
Reputation: 151
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}}
Upvotes: 0
Reputation: 171
$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
Upvotes: 0
Reputation: 1781
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
}
}
Upvotes: 1
Reputation: 3042
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}}
Upvotes: 1