GetTLScontextDetails.ps1
<#PSScriptInfo .VERSION 0.9.5 .GUID 8306686e-1e7e-4fc9-8c07-4f131ff908f9 .AUTHOR enricoj .COMPANYNAME .COPYRIGHT Enrico Jost .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION GetTLScontextDetails Script to receive details about every configured TLS context (cert) on an AudioCodes SBC - utilizing REST API via HTTP or HTTPS #> # Written by Enrico Jost, December 2023 # Version 0.9.5 - BETA # GNU General Public License v3.0 # Versions 0.1 - 0.7 : initial codings, review, re-designs # Version 0.8 : Working script, only HTTP without choice of protocol # Version 0.9 : Added HTTP-HTTPS choice as well as certificate validation skipping (Credits to Bjorn Van Leemput - AudioCodes) # Version 0.9.5 : Added Expiration calculation based on cert property NotAfter + current date, adjusted script output to display it # Features planned: # Input via csv file # GUI to choose between HTTP/HTTPS # GUI is going to include a choice between individual TLS-contexts or all of them # Different output options in planning # Setting TLS preference for older PS versions [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 # Function to extract and store certificates from API responses function Get-Certificates { param ( [string]$ip, [string]$username, [string]$password, [bool]$useHttps ) # Build Authorization Header $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${username}:${password}")) $AuthorizationHeader = "Basic $base64AuthInfo" # Choose between HTTP and HTTPS $protocol = if ($useHttps) { "https" } else { "http" } # Get TLS contexts from the INI file try { $configEndpoint = "/api/v1/files/ini" $configUrl = "${protocol}://${ip}$configEndpoint" # Ignore certificate validation for this specific call if ($useHttps) { if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) { $certCallback = @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { if(ServicePointManager.ServerCertificateValidationCallback ==null) { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } } "@ Add-Type $certCallback } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 [ServerCertificateValidationCallback]::Ignore() } $configResponse = Invoke-RestMethod -Uri $configUrl -Headers @{ 'Authorization' = $AuthorizationHeader } -ErrorAction Stop } catch { Write-Host "Error getting TLS contexts from the config: $_" return $null } if ($configResponse) { # Extract TLS contexts using regex $tlsContexts = $configResponse -split '\r?\n' | Where-Object { $_ -match 'TLSContexts (\d+)' } | ForEach-Object { $matches[1] } } else { Write-Host "Error getting TLS contexts from the config." return $null } if ($tlsContexts.Count -eq 0) { Write-Host "No TLS contexts found in the config." return $null } # Loop through each TLS context foreach ($tlsContext in $tlsContexts) { $endpoint = "/api/v1/files/tls/$tlsContext/certificate" # Adjust the URL based on the user's choice of HTTP or HTTPS $url = "${protocol}://${ip}$endpoint" # Ignore certificate validation for this specific call if ($useHttps) { if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type) { $certCallback = @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { if(ServicePointManager.ServerCertificateValidationCallback ==null) { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } } "@ Add-Type $certCallback } [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; [ServerCertificateValidationCallback]::Ignore() } $response = Invoke-RestMethod -Uri $url -Headers @{ 'Authorization' = $AuthorizationHeader } -ErrorAction SilentlyContinue if ($response) { # Extract certificate content $certContent = $response -replace "(?s).*?(-----BEGIN CERTIFICATE-----)(.*?)(-----END CERTIFICATE-----).*", '$2' if ($certContent) { # Remove leading/trailing whitespaces $certContent = $certContent.Trim() # Define variable name $variableName = "Response${endpoint -replace '/','-'}" # Store certificate content in the variable Set-Variable -Name $variableName -Value $certContent # Decode and display certificate information $certBase64 = $certContent $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String($certBase64)) # Store the "NotAfter" attribute in expiresCount variable $Expiration = $cert.NotAfter # Calculate remaining days until the certificate expires $daysUntilExpiration = ($Expiration - (Get-Date)).Days # Output information about the stored certificate with remaining days Write-Output "Stored cert for TLS context $($tlsContext):" Write-Output $certContent $cert | Select-Object Issuer, Subject, NotBefore, NotAfter | Format-List * Write-Output "Certificate expires in $daysUntilExpiration days." `n } else { Write-Output "Certificate content not found for TLS context $($tlsContext)" } } } } # Get user input for HTTP or HTTPS $useHttps = Read-Host "Choose protocol:`n1. HTTP`n2. HTTPS`nEnter '1' for HTTP or '2' for HTTPS" # Validate user input if ($useHttps -eq '1' -or $useHttps -eq '2') { $useHttps = ($useHttps -eq '2') } else { Write-Host "Invalid choice. Defaulting to HTTP." $useHttps = $false } # Get user input $ip = Read-Host "Enter SBC IP address" $username = Read-Host "Enter username" $password = Read-Host -Prompt "Enter password" -AsSecureString # Convert SecureString to plain text password $passwordPlain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)) # Invoke the Get-Certificates function $certificates = Get-Certificates -ip $ip -username $username -password $passwordPlain -useHttps $useHttps # Output TLS contexts if ($certificates) { Write-Host "TLS Contexts:" `n $certificates } # End of the script Read-Host "Press Enter to exit" |