Tuesday, June 30, 2015

Certificate Expiration Report

Generate-CertificateExpirationReport

<#
    .SYNOPSIS
        Generate report of  SSL certificates that will expire in the next 90 days.
    .DESCRIPTION
        This script runs Check-CertExpiration.ps1 as a background job on multiple web servers in 
        parallel using PowerShell Remoting. It waits for all background jobs to complete
        and retrieves results and errors and generates an html report and a log file that are send out
        by email.
        
    .EXAMPLE
        Generate-CertificateExpirationReport.ps1 -verbose
    .LINK
        "https://technet.microsoft.com/en-us/library/hh847761.aspx"
        "http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/18/hey-scripting-guy-march-18-2010.aspx"
        "http://thesurlyadmin.com/2013/01/21/how-to-create-html-reports/#more-817"

#>

[CmdletBinding()]

Param (

)



Import-Module ActiveDirectory
$Servers = Get-ADComputer -SearchBase 'OU=ProdServers,dc=adatum,dc=local' -Filter {(Name -like "*web*") -and (OperatingSystem -like "Windows*")} | % {$_.Name} | Sort-Object -Property $_.name


Write-Verbose "Number of Servers: $($Servers.count)"

Function CheckSSL {
    $Objs = @()
    $Jobs = @()
    $i = 0
    ForEach ($Server in $Servers) {
        Write-Verbose "Checking certificates on $Server"
        $i++
        $percent = [decimal]::round($i / $Servers.length * 100)
        Write-Progress -activity "Checking SSL Expiration Status on $Server" -status "Percent Complete: $percent %" -PercentComplete ($i / $Servers.count * 100)
        
        Try {        
                Test-WSMan -ComputerName $Server -ErrorAction Stop
                $Jobs += Invoke-Command -ComputerName $Server  -FilePath .\Check-CertExpiration.ps1 -AsJob -ErrorAction SilentlyContinue
        
            } Catch {
                Write-Verbose $_.Exception.Message
                $Properties = @{'ServerName' = $Server
                                'Error' = $_.Exception.Message
                                }
                $Unavailable = New-Object -TypeName PSObject -Property $Properties
                $Objs += $Unavailable

       
            }#End Try-Catch
        
       
        } # End ForEach

    $Objs | Select-Object ServerName,Error
    Write-Verbose "Waiting for jobs to complete..."
    $complete = $false
    while (-not $complete) {
    $arrayJobsInProgress = $Jobs | `
    Where-Object { $_.State -match 'running' }
        if (-not $arrayJobsInProgress) { "All Jobs Have Completed" ; $complete = $true } 
    }# End while

    Write-Verbose "Getting job's results..."
    $Jobs | Receive-Job 2> JobsErrors.log
    Get-job | Remove-Job
    Write-Verbose "Sending results by email."
}# End Function

$Header = @"

"@

$Message = CheckSSL | Select ServerName,ExpirationDate,FriendlyName,Subject,Issuer,Error| Where-Object {$_.ServerName} | sort-object ExpirationDate | ConvertTo-HTML -head $Header –body "

SSL Certificate Expiration Report

" $Message = "The following list of SSL certs will expire in the next 90 days.`n`r$Message" Send-MailMessage -To "admin@adatum.local" -Subject "SSL Certificate Expiration Report" -From $env:ComputerName"@adatum.local" ` -BodyAsHtml $Message ` -SmtpServer "smtp.adatum.local" ` -Attachments "JobsErrors.log"

Check-CertExpiration.ps1


    gci -Path cert:\LocalMachine\My, cert:\LocalMachine\WebHosting -Recurse `
    | ? {$_.NotAfter -lt (Get-Date).AddDays(60)} `
    | ? {$_.NotAfter -gt (Get-Date).AddDays(-30)} `
    | Select -Property `
        @{n='ServerName';e={$env:ComputerName}},`
        @{n='ExpirationDate';e={$_.NotAfter}},`
        @{n='FriendlyName';e={$_.FriendlyName}},`
        @{n='Subject';e={$_.Subject}},`
        @{n='Issuer';e={$_.Issuer}}