Last active
July 7, 2023 14:28
-
-
Save Rugby-Ball/8d9f6f467df3cf60eda655ae8ecd9e47 to your computer and use it in GitHub Desktop.
Do a search/inventory for a specific domains SSL across all Running Domain joined IIS servers. Will also pull in ALL ssl certs installed on all server for #Powershell #Inventory #Utility #WebServer #SSL_Certificate #Public # SSL # IIS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ssl-cert-scan-inventory-IIS-servers.ps1 | |
| <# | |
| Description: Pull ALL ssl certs installed on all Windows servers for a full inventory of installed SSL Certificates. | |
| Written: Ed Walsh | |
| PowerShell.Core tested: No | |
| Version: 2.1 | |
| Create Date: 5/15/2021 | |
| Revised Date: 7/7/2023 | |
| #> | |
| Import-Module -name AWSPowershell | |
| $timestamp = get-date -format yyyyMMddHHmmss | |
| $subfolder = if (($PSVersionTable.PSEdition) -eq "Core") { if ( $True -eq $iswindows ) { "\Documents\" } Else { "" } } Else {"\Documents\"} | |
| $mydocuments = $home + $subfolder | |
| $fileName = "Installed-Windows-SSL-Certificate-Inventory-"+ [string]$timestamp + ".csv" | |
| $filePath = Join-Path $mydocuments $fileName | |
| $ErrorActionPreference = 'Stop' | |
| $Array = @() | |
| ##-----------------------------------------------------------------------------------------## | |
| ## Chose which option you want to use to pull the variable $Servers ## | |
| ##-----------------------------------------------------------------------------------------## | |
| # | |
| ## This will only get EC2's that are Windows and Running, and have a WEB or WB in the EC2 Tag 'Name' | |
| #$Servers = ((((Get-EC2Instance -region $region -Filter @( @{name = 'instance-state-name'; values = 'running' }; , @{name = 'platform'; values = "windows" }) ).Instances).tag) | Where-Object {($_.Key -eq 'Name' -and $_.Value -Match 'WEB') -or ($_.Key -eq 'Name' -and $_.Value -Match 'WB')} | select-object @{name="Hostname"; expression={$_.Value + ".mrirdp.com"}}).hostname | |
| ## Use if you want ALL running Windows EC2's. This can take some time to run. Be patient. | |
| #$Servers = ((((Get-EC2Instance -region $region -Filter @( @{name = 'instance-state-name'; values = 'running' }; , @{name = 'platform'; values = "windows" }) ).Instances).tag) |Where-Object {($_.Key -eq 'Name')} | select-object @{name="Hostname"; expression={$_.Value + ".mrirdp.com"}}).hostname | |
| ## This gets the servers Hostname using SSM | |
| $Servers = @() | |
| # Get the Running EC2 Instances managed by SSM | |
| $Filters = @(@{ Key = 'PingStatus'; values = 'Online' }; @{ key = "PlatformTypes"; values = (<#"Linux",#> "Windows") }; @{ Key = "ResourceType"; values = "EC2Instance" }) | |
| Get-EC2Region -RegionToCall us-east-1 <# -RegionToCall used because of https://github.com/aws/aws-tools-for-powershell/issues/46 #> | Foreach-Object { | |
| $region = $_.RegionName | |
| $Servers += Get-SSMInstanceInformation -Region $Region -Filter $Filters | Select @{Name = 'Region'; Expression = {$Region} },InstanceId, ComputerName, @{Name = 'EC2Name'; Expression ={ ((((Get-EC2Instance -region $region -InstanceId $_.InstanceID ).Instances).tag) | Where-Object {($_.Key -eq 'Name')} | select-object @{name="EC2Name"; expression={$_.Value}}).EC2Name } }, IPAddress, PlatformType, PlatformName, PlatformVersion, LastPingDateTime | |
| } | |
| # Remove WORKGROUP servers | |
| $Servers = $Servers | where computername -NotLike "*.workgroup" | |
| ##-------------------------------------------------------------------## | |
| # Looping each server | |
| foreach($Server in $Servers) | |
| { | |
| Write-Host Processing $Server.ComputerName -ForegroundColor yellow | |
| Try | |
| { | |
| # Checking local DNS for hostname of a server provided in variable. If not found throw an error. | |
| #$hostname = ([System.Net.Dns]::GetHostByName("$Server")).hostname | |
| $hostname = $Server.ComputerName | |
| # Querying for certificates on remote server. | |
| $Certs = Invoke-Command $Server.ComputerName -ScriptBlock{ Get-ChildItem Cert:\LocalMachine\* -Recurse | where-object {($_.PSParentPath -eq "Microsoft.PowerShell.Security\Certificate::LocalMachine\My") -or ($_.PSParentPath -eq "Microsoft.PowerShell.Security\Certificate::LocalMachine\webhosting") } } | |
| If ($certs -eq $Null) {$certs = "No certs"} | |
| } | |
| Catch | |
| { | |
| $errormsg = $_.Exception.Message | |
| $hostnamenotmatch = "*No such host is known*" | |
| $tagname = $Server.ComputerName #$Server.Substring(0,$server.Length-11) | |
| if ($errormsg -like $hostnamenotmatch) {Write-Host "The EC2 Name Tag: " -f Magenta -nonewline; Write-Host $tagname -f white -nonewline; Write-Host " is not found as a hostname in the Local DNS." -ForegroundColor Magenta} Else {$errormsg} | |
| Continue | |
| } | |
| If($hostname -and $Certs) | |
| { | |
| Foreach($Cert in $Certs) | |
| { | |
| #RegEx out the URL from the Subject field, if blank return blank | |
| $Subject = if (($cert.Subject)) {($cert.Subject) -replace "(CN=)(.*?),.*",'$2'} else {($cert.Subject)} | |
| #Is $Subject a URL | |
| $A_URL = if ($Subject -match " " -or $Subject -like "CN=*" -or $Subject -eq "" -or $Subject -eq $Null ) {$False} Else {$True} | |
| # Adding certificate properties and server name to object | |
| #$Object = New-Object PSObject | |
| $Object = New-Object pscustomobject | |
| $Object | Add-Member Noteproperty "Region" -Value $Server.region | |
| $Object | Add-Member Noteproperty "InstanceID" -Value $Server.InstanceID | |
| $Object | Add-Member Noteproperty "EC2_name" -Value $Server.ec2name | |
| $Object | Add-Member Noteproperty "Server_HostName" -Value $hostname | |
| #Below using -join, avoids the issue of returning System.Object[] in a CSV file. | |
| $Object | Add-Member Noteproperty "Certificate_name" -Value (@($cert.dnsnamelist.punycode) -join ',') #This is original way to do it # $cert.dnsnamelist.punycode | |
| $Object | Add-Member Noteproperty "Certificate_issuer" -Value $cert.issuer | |
| $Object | Add-Member Noteproperty "Certificate_expiration date" -Value $cert.notafter | |
| $Object | Add-Member Noteproperty "Certificate_thumbprint" -Value $cert.thumbprint | |
| $Object | Add-Member Noteproperty "Certificate_Location" -Value $cert.PSParentPath | |
| $Object | Add-Member Noteproperty "Certificate_Subject" -Value $Subject | |
| $Object | Add-Member Noteproperty "Certificate_Subject_A_URL" -Value $A_URL | |
| # Adding object to an array | |
| $Array += $Object | |
| } | |
| } | |
| Else | |
| { | |
| Write-Warning "Something went wrong on $Server.ComputerName" | |
| } | |
| } | |
| If($Array) | |
| { | |
| ## Display searched certificate. | |
| # $array | Where-Object {($_.Certificate_Subject_a_URL -eq $True)} | Sort-Object $_.Certificate_Subject | |
| ## To export to CSV | |
| #This adds a filter to check if a URL, and dumps the list of all SSL certs on all Windows Webservers on the domain. | |
| $array | Where-Object {($_.Certificate_Subject_a_URL -eq $True)} | Sort-Object $_.Certificate_Subject | Export-Csv -Path $filePath -Force -NoTypeInformation | |
| } | |
| Write-Output "Exported to: $filePath" | |
| Write-Output "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|||||||////////////////////////////////////" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment