Skip to content

Instantly share code, notes, and snippets.

@davops
Created August 2, 2016 13:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save davops/6b1988bcd2427524b4963987cccbdae2 to your computer and use it in GitHub Desktop.
Save davops/6b1988bcd2427524b4963987cccbdae2 to your computer and use it in GitHub Desktop.
Retrieves all websites from IIS. Prints the hostname of the target server, the website name, whether or not SSL is enabled, the certificate expiration date, the certificate subject and the certificate subject alternative names (for multi-domain certificates).
<#
.NOTES
Name: Get-CertSettings.ps1
Author: Davina Fournier
Requires: PowerShell v3 or higher. The account running this script needs to have rights to access IIS settings on the target servers. Tested on 2012 servers in a single domain.
Last Updated: 7/31/2016
.SYNOPSIS
Retrieves all websites from IIS. Prints the hostname of the target server, the website name, whether or not SSL is enabled, the certificate expiration date, the certificate subject and the certificate subject alternative names (for multi-domain certificates).
.DESCRIPTION
A list of remote computer names should be entered into the Server_list.txt file currently located in the "Tools\Scripts" directory. The script creates a session to each remote computer, then queries IIS for the binding settings of each website. If the website has no SSL binding, then the "SSL Enabled" setting will be set to "Not Enabled" and the remaining values will be empty. If there is a SSL binding, the Local Machine stores are searched for the corresponding certificate information.
All of the values are logged to a csv filed stored on the system drive in the "Tools\Scripts" folder. If one website has multiple certificates, each certificate will be printed in a separate row of the csv file.
The script assumes all computers are in the same domain from which the script is run. However, the additional sections needed to connect to computers that are not in a domain are within comments. Currently, it will prompt for the credentials of each computer in the workgroup. However, if a single credential is available, move the $cred = Get-Credential line above the servers loop to avoid repeating it.
.EXAMPLE
[PS] C:\Tools\Scripts>.\Get-CertSettings.ps1
All servers in the Server_list.txt file will be queried. The output will appear in the console and in a file called Get-CertSettings_Output ending in the date.
#>
$ErrorActionPreference = "Stop"
$VerbosePreference = "Continue" ###Turn off additonal output with "SilentlyContinue"
$thisCSV = "$env:systemdrive\Tools\Scripts\Get-CertSettings_Output_$((Get-Date).ToString('yyyy-MM-dd')).csv"
If (!(Test-Path $thisCSV))
{
New-Item "$env:systemdrive\Tools\Scripts\" -Type container -force | out-null
}
$theServers = (Get-Content "$env:systemdrive\Tools\Scripts\Server_list.txt").Trim()
foreach ($thisServer in $theServers)
{
Try
{
Write-Verbose "Beginning the connection to $thisServer... `n"
<# Include this section for non-domain computers
Set-Item -Path WSMan:localhost\Client\TrustedHosts -Value $thisServer
$cred = Get-Credential
#>
$thisPsSession = New-PSSession $thisServer ### Include this switch for non-domain computers: -Credential $cred
[pscustomobject]$properties = Invoke-Command -Session $thisPsSession -ScriptBlock {
Import-Module Webadministration ###Required to use IIS:\Sites - not available in PowerShell v2.0
$appCmd = "$env:systemroot\system32\inetsrv\appcmd.exe"
[array]$sites = (Get-ChildItem -Path IIS:\Sites | Select-Object -Property Name).Name
foreach($site in $sites)
{
$bindingInfo = Get-WebBinding | where {$_.ItemXPath -like "*@name='$site'*"}| select certificateHash, certificateStoreName
foreach($cert in $bindingInfo)
{
if($cert.certificateHash -ne "")
{
$store = $cert.certificateStoreName
$expiration = (Get-ChildItem CERT:LocalMachine/$store | where {$_.Thumbprint -eq $cert.certificateHash} | select notafter).notAfter
$DNSname = (Get-ChildItem CERT:LocalMachine/$store | where {$_.Thumbprint -eq $cert.certificateHash} | select DnsNameList).DnsNameList ###only in PowerShell 3.0 & Up; used to pull the Subject Alternative Names (for multiple domain names)
$subject = (Get-ChildItem CERT:LocalMachine/$store | where {$_.Thumbprint -eq $cert.certificateHash} | select subject).subject
$sslEnabled = "Enabled"
}
else
{
$sslEnabled = "Not Enabled"
$expiration = ""
$DNSname = ""
$subject = ""
}
$properties = [pscustomobject] @{
Script = "Get-CertSettings"
HostName = $env:computername
Website = $site
"SSL Enabled" = $sslEnabled
"Expiration Date" = $expiration
"Subject" = $subject
"Subject Alternative Names" = $DNSname
"Current Date" = (Get-Date)
}
$properties ###needed in order to return the output to a variable outside of the session
}
} ###end of the sites loop
}###end of the session
Remove-PSSession $thisPsSession
$properties | select Hostname,Website,"SSL Enabled","Expiration Date",Subject,"Subject Alternative Names"###Outputs to the console
foreach($property in $properties)
{
$property | select Script,Hostname,Website,"SSL Enabled","Expiration Date",Subject,"Subject Alternative Names", "Current Date" | Export-Csv -Path $thisCSV -Append
}
<# Include this section for non-domain computers ###removes the value from the trusted hosts list that was originally added
#$newvalue = ((Get-ChildItem WSMan:\localhost\Client\TrustedHosts).Value).Replace("$thisServer,","")
#Set-Item WSMan:\localhost\Client\TrustedHosts $newvalue
#>
}
Catch [System.Management.Automation.RemoteException] {Write-Verbose "Error once connected to the remote server, $thisServer. Check the IIS installation and PowerShell version. Version 3.0 or higher is required. Detailed Error Message: $_.Exception.Message `n"}
Catch [System.Management.Automation.Remoting.PSRemotingTransportException] {Write-Verbose "Error connecting remotely to $thisServer. Verify connectivity and WinRM settings. Detailed Error Message: $_.Exception.Message `n"}
Catch {Write-Verbose "Error on $thisServer. Detailed Error Message: $_.Exception.Message `n"}
}###end of the foreach server loop
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment