Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function global:Write-Host() {} # Supress Write-Hosts Logs (Keep for Debugging).
- # Ensure WebAdministration module is available and loaded
- function Ensure-WebAdministrationModule {
- Write-Host "Checking if WebAdministration module is available..." -ForegroundColor Yellow
- if (-not (Get-Module -ListAvailable -Name WebAdministration)) {
- try {
- Write-Host "WebAdministration module not found, attempting to import..." -ForegroundColor Yellow
- Import-Module WebAdministration -WarningAction:SilentlyContinue
- Write-Host "WebAdministration module successfully imported." -ForegroundColor Green
- }
- catch {
- Write-Host "Failed to import WebAdministration module." -ForegroundColor Red
- Exit 1 # Exit the script if the module cannot be imported
- }
- } else {
- Write-Host "WebAdministration module is already available." -ForegroundColor Green
- }
- if (-not (Get-Command -Name Get-Website -ErrorAction SilentlyContinue)) {
- Write-Host "Get-Website cmdlet not available. Exiting..." -ForegroundColor Red
- Exit 1 # Exit if the Get-Website cmdlet is not available
- } else {
- Write-Host "Get-Website cmdlet is available." -ForegroundColor Green
- }
- }
- # Get the bindings for a site using Get-WebBinding (for WebAdministration)
- function Get-SiteBindings {
- param (
- [string]$SiteName # Name of the site for which we want bindings
- )
- Write-Host "Fetching bindings for site: $SiteName" -ForegroundColor Cyan
- try {
- # Use Get-WebBinding to fetch bindings for the site
- $bindings = Get-WebBinding -Name $SiteName
- if (-not $bindings) {
- Write-Host "No bindings found for site: $SiteName" -ForegroundColor Red
- return $null
- }
- # Log retrieved bindings
- $bindings | ForEach-Object {
- Write-Host "Binding: Protocol=$($_.protocol), Info=$($_.bindingInformation)" -ForegroundColor Cyan
- }
- return $bindings
- }
- catch {
- Write-Host "Error fetching bindings for site: $SiteName. Exception: $_" -ForegroundColor Red
- return $null
- }
- }
- # Process each binding for a site and apply filtering
- function Process-SiteBindings {
- param (
- [array]$bindings # The full set of bindings for the current site
- )
- Write-Host "`n[Process-SiteBindings] Processing site bindings..." -ForegroundColor Cyan
- Write-Host "Bindings count: $($bindings.Count)" -ForegroundColor Cyan
- # Log the received bindings to see their structure
- $bindings | ForEach-Object { Write-Host "Binding Object: $($_.ToString())" -ForegroundColor Cyan }
- # Case 1: Single binding
- if ($bindings.Count -eq 1) {
- Write-Host "Single binding detected." -ForegroundColor Cyan
- # Prepare the single binding as a PSCustomObject
- $singleBinding = @(
- [PSCustomObject]@{
- "Protocol" = $bindings[0].protocol
- "BindingInformation" = $bindings[0].bindingInformation
- }
- )
- Write-Host "`nPrepared single binding: $($singleBinding | ConvertTo-Json -Compress)" -ForegroundColor Cyan
- return Filter-SiteBindings -bindings $singleBinding
- }
- # Case 2: Multiple bindings
- elseif ($bindings.Count -gt 1) {
- Write-Host "Multiple bindings detected. Applying filter..." -ForegroundColor Cyan
- return Filter-SiteBindings -bindings $bindings
- }
- # Case 3: No bindings or empty bindings
- else {
- Write-Host "No bindings found or bindings are empty." -ForegroundColor Red
- return $null
- }
- }
- # Filter site bindings based on exclusion patterns
- function Filter-SiteBindings {
- param (
- [array]$bindings # Input array of bindings
- )
- Write-Host "`n[Filter-SiteBindings] Entering function with minimal filtering (BindingInformation length check)..." -ForegroundColor Blue
- if (-not $bindings) {
- Write-Host "No bindings passed to filter. Exiting Filter-SiteBindings." -ForegroundColor Red
- return $null
- }
- # Log the received bindings for better clarity
- $bindings | ForEach-Object {
- Write-Host "`nReceived Binding: $($_.ToString())" -ForegroundColor Blue
- }
- # Apply the exclusion filter based on BindingInformation length (<14 characters)
- $filteredBindings = $bindings | Where-Object {
- $_.BindingInformation -notmatch "^.{1,14}$" # Exclude very short bindings (1 to 14 characters)
- }
- # Log the filtered bindings
- if ($filteredBindings) {
- Write-Host "`nFiltered Bindings after applying BindingInformation length check:" -ForegroundColor Blue
- $filteredBindings | ForEach-Object {
- Write-Host "Filtered Binding: Protocol=$($_.protocol), BindingInformation=$($_.BindingInformation)" -ForegroundColor Blue
- }
- } else {
- Write-Host "No bindings matched the filter criteria." -ForegroundColor Red
- }
- # Return filtered bindings as PSCustomObject
- $allBindings = $filteredBindings | ForEach-Object {
- [PSCustomObject]@{
- "Protocol" = $_.protocol
- "BindingInformation" = $_.bindingInformation
- }
- }
- return $allBindings
- }
- # Get the SSL certificate thumbprint for the given site's bindings
- function Get-SiteSSLCertificateDetails {
- param (
- [string]$SiteName # Site for which we want to get SSL certificate details
- )
- Write-Host "`nGetting SSL certificate thumbprint for site: $SiteName" -ForegroundColor Magenta
- $bindings = Get-SiteBindings -SiteName $SiteName
- if (-not $bindings) {
- Write-Host "No bindings found for the site: $SiteName" -ForegroundColor Red
- return $null
- }
- $certificateThumbprints = @()
- foreach ($binding in $bindings) {
- if ($binding.protocol -eq "https") {
- # Safely retrieve the certificate hash from the binding
- $thumbprint = $binding.certificateHash
- Write-Host "Found certificate hash: $thumbprint" -ForegroundColor Magenta
- # Add the thumbprint to the list if it exists
- if ($thumbprint) {
- $certificateThumbprints += $thumbprint
- } else {
- Write-Host "No certificate hash found for this binding." -ForegroundColor Red
- }
- }
- }
- # Log thumbprints found
- if ($certificateThumbprints) {
- Write-Host "Certificate thumbprints found for site $SiteName : $($certificateThumbprints -join ', ')" -ForegroundColor Magenta
- } else {
- Write-Host "No certificate thumbprints found for site $SiteName" -ForegroundColor Red
- }
- return ($certificateThumbprints | Select-Object -Unique)
- }
- # Retrieve certificate details from the LocalMachine\My store using the thumbprint
- function Get-SSLCertificate {
- param (
- [string]$Thumbprint
- )
- Write-Host "`nRetrieving certificate for thumbprint: $Thumbprint" -ForegroundColor Yellow
- $certificate = Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq $Thumbprint }
- if ($certificate) {
- Write-Host "Certificate found: $($certificate.Subject)" -ForegroundColor Yellow
- } else {
- Write-Host "No certificate found with thumbprint: $Thumbprint" -ForegroundColor Red
- }
- return $certificate
- }
- # Function to clean up the JSON string
- function CleanUp-JsonString {
- param (
- [string]$jsonString
- )
- # Replace "\r\n" and any extra whitespace to clean up the JSON string
- $cleanedJson = $jsonString -replace "\r\n", "" -replace "\s{2,}", ""
- return $cleanedJson
- }
- # Function to discover site certificates and return an array or object
- function Discover-SiteCertificates {
- param (
- [string]$SiteName # The name of the site to get certificates for
- )
- Write-Host "`nDiscovering certificates for site: $SiteName" -ForegroundColor Magenta
- # Attempt to get SSL certificate thumbprints for each binding
- $thumbprints = Get-SiteSSLCertificateDetails -SiteName $SiteName
- # Initialize certificate information as an array (in case of multiple certificates)
- $certificateInfo = @()
- # Check if thumbprints are found before retrieving certificate details
- if ($thumbprints) {
- Write-Host "`nThumbprints found for site. Starting to retrieve certificate details..." -ForegroundColor Magenta
- Write-Host "Number of thumbprints: $($thumbprints.Count)" -ForegroundColor Magenta
- # Iterate through each thumbprint and attempt to retrieve the certificate
- foreach ($thumbprint in $thumbprints) {
- Write-Host "`nProcessing thumbprint: $thumbprint" -ForegroundColor Magenta
- # Call the function to get certificate details for the thumbprint
- $certificate = Get-SSLCertificate -Thumbprint $thumbprint
- # If a certificate is found, log details and append it to the certificate info array
- if ($certificate) {
- Write-Host "Certificate found: Issuer = $($certificate.Issuer), Thumbprint = $($certificate.Thumbprint)" -ForegroundColor Magenta
- # Add certificate details to the array as a PowerShell object
- $certificateInfo += [PSCustomObject]@{
- "Issuer" = $certificate.Issuer
- "Thumbprint" = $certificate.Thumbprint
- "Expiration Date" = $certificate.NotAfter.ToString("yyyy-MM-dd'T'HH:mm:sszzz")
- }
- } else {
- Write-Host "No certificate found for thumbprint: $thumbprint" -ForegroundColor Magenta
- }
- }
- } else {
- Write-Host "`nNo thumbprints found for site. Skipping certificate retrieval." -ForegroundColor Magenta
- }
- return $certificateInfo
- }
- # Function to format certificates into proper JSON-like structure
- function Format-SiteCertificates {
- param (
- [array]$certificateInfo # Array of certificates to format
- )
- Write-Host "`nFormatting site certificates..." -ForegroundColor Cyan
- # Check how many certificates are present and return the appropriate format
- if ($certificateInfo.Count -gt 1) {
- Write-Host "Multiple certificates found, formatting as array of objects." -ForegroundColor Cyan
- return $certificateInfo # Return as array of certificates
- } elseif ($certificateInfo.Count -eq 1) {
- Write-Host "Single certificate found, formatting as single object." -ForegroundColor Cyan
- return $certificateInfo[0] # Return single certificate object
- } else {
- Write-Host "No certificates found, returning null." -ForegroundColor Cyan
- return $null # No certificates, return null
- }
- }
- # Main logic to discover IIS sites, their bindings, and certificate details
- function Discover-IISSitesAndCertificates {
- Ensure-WebAdministrationModule
- Write-Host "`nDiscovering IIS Sites and Certificates..." -ForegroundColor Green
- $sites = Get-Website
- Write-Host "Found $($sites.Count) sites in IIS." -ForegroundColor Green
- $discoveredSites = @()
- foreach ($site in $sites) {
- Write-Host "`nProcessing site: $($site.Name)" -ForegroundColor White
- # Fetch and process the site's bindings
- $bindings = Get-SiteBindings -SiteName $site.Name
- # Process the site bindings
- $processedBindings = if ($bindings) {
- Process-SiteBindings -bindings $bindings
- } else {
- Write-Host "No bindings found for site: $($site.Name)" -ForegroundColor White
- $null
- }
- if (-not $processedBindings) {
- Write-Host "No valid bindings after processing for site: $($site.Name). Skipping..." -ForegroundColor White
- continue
- }
- # Call the Discover-SiteCertificates function to get the certificates
- $certificateInfo = Discover-SiteCertificates -SiteName $site.Name
- # Format the certificates using the Format-SiteCertificates function
- $formattedCertificateInfo = Format-SiteCertificates -certificateInfo $certificateInfo
- # Add the site details to the discoveredSites collection
- Write-Host "Adding site to discovered sites list: $($site.Name)" -ForegroundColor White
- $siteObject = [PSCustomObject]@{
- Name = $site.Name
- ID = $site.ID
- State = $site.State
- PhysicalPath = $site.PhysicalPath
- Bindings = $processedBindings
- Certificate = $formattedCertificateInfo # No ConvertTo-Json here
- }
- $discoveredSites += $siteObject
- }
- Write-Host "`nCompleted site and certificate discovery." -ForegroundColor Green
- # Convert the entire array to JSON at once
- $discoveredSites | ConvertTo-Json -Depth 3 -Compress 3>$null
- }
- # Execute the site and certificate discovery function
- Discover-IISSitesAndCertificates
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement