Search code examples
powershellpowershell-remotingwindows-scripting

Powershell script to find currently bound expiring certificates in IIS remotely


I'm currently working on a script that will send an email once the certificates binded in my web servers' IIS are nearing there expiration date. I do have the script to send it in email. All I need to know is how to compare the certificates available in the store query versus the certificates currently in use. For now, here's what I have:

$Date= (Get-Date)
$SMTPServer = "smtp.test.com" 
$From = "testmail@noreply.com"

Import-Module WebAdministration

$Servers = @("WEBSERVER1", "WEBSERVER2")

$certificates = foreach($server in $Servers){
    Invoke-Command -ComputerName $server -ScriptBlock { $CertAll = Get-ChildItem -Path Cert:\LocalMachine\My }
    Invoke-Command -ComputerName $server -ScriptBlock { $CertInUse = Get-ChildItem -Path IIS:\SslBindings }
    Invoke-Command -ComputerName $server -ScriptBlock { $CertSame = Compare-Object -ReferenceObject $CertAll -DifferenceObject $CertInUse -Property Thumbprint -IncludeEqual -ExcludeDifferent }

    Invoke-Command -ComputerName $server -ScriptBlock { $cert = $CertSame | ForEach {Get-ChildItem -Path Cert:\LocalMachine\My\$($_.thumbprint)} | 
  Select-Object Subject, DaysUntilExpired, NotAfter, @{n='ExpireInDays';e={($_.notafter - ($Date)).Days}}}
}

    $certificates | Sort DisplayName

Any help and suggestion would be appreciated. Thanks!


Solution

  • The script above never works as you are creating variables in separate sessions to the same computer.

    You can do it in two ways.

    1. Create a session object targeting the destination server once and reuse it. So that you will be able to get the variables defined in the session in subsequent Invoke-command executions.

    2. Without creating a session object, but by executing everything on the remote server in a single Invoke-Command .

    example:-

    Invoke-command -computerName $Server {
        $CertAll = ....
        $CertInUse = ....
        $CertSame = ....
        $cert = $CertSame | ForEach ..... |
        Select-Object Subject, DaysUntilExpired .....
    
    }
    

    if you don't have any further actions on the remote server after identifying the certiricates expire date, I would suggest to use the second option.