#!/usr/bin/env pwsh . /opt/idssys/nodemgmt/conf/powerwall/settings.ps1 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Force -Confirm:$false function Show-Failure { $global:helpme = $body $global:helpmoref = $moref $global:result = $_.Exception.Response.GetResponseStream() $global:reader = New-Object System.IO.StreamReader($global:result) $global:responseBody = $global:reader.ReadToEnd(); Write-Host -BackgroundColor:Black -ForegroundColor:Red "Status: A system exception was caught." Write-Host -BackgroundColor:Black -ForegroundColor:Red $global:responsebody Write-Host -BackgroundColor:Black -ForegroundColor:Red "The request body has been saved to `$global:helpme" break } $vCenterURL = $VCENTERHOST $CommonName = $VCENTERHOST $EmailContact = $ACMEEMAIL #[string]$userName = $VCENTERUSER #[string]$userPassword = $VCENTERPASS #[SecureString]$secureString = ConvertTo-SecureString $VCENTERPASS -AsPlainText -Force [PSCredential]$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $VCENTERUSER, (ConvertTo-SecureString $VCENTERPASS -AsPlainText -Force) $pArgs = @{ PowerDNSApiHost = $WDNSHOST PowerDNSApiKey = $PDNSAPI | ConvertTo-SecureString -AsPlainText -Force #PowerDNSApiKey = (Read-Host "API Key" -AsSecureString) PowerDNSUseTLS = $true PowerDNSPort = 443 PowerDNSServerName = 'localhost' } Write-Host "Checking for Required Module Posh-ACME" -ForegroundColor Green if (Get-Module -ListAvailable -Name Posh-ACME) { Write-Host "Posh-ACME Module Already Installed" -ForegroundColor Green } else { Write-Host "Posh-ACME Module Not Found, Attempting to Install" -ForegroundColor Yellow Write-Host "Restart of this Script is Required!" -ForegroundColor Yellow Install-Module -Name Posh-ACME -Scope CurrentUser -Force -Confirm:$false Return } Do { Write-host "Waiting to for Posh-ACME Module to be Loaded" -ForegroundColor Cyan $PoshACME = Get-Module -ListAvailable -Name Posh-ACME Start-Sleep -Seconds 5 } While ( $PoshACME -eq $null ) # --- Importing the Posh-ACME Module. if (Get-Module -ListAvailable -Name Posh-ACME) { Write-Host "Importing Posh-ACME Module" -ForegroundColor Green Import-Module -Name Posh-ACME -Force } Else { Write-host "Something Went Wrong, Stopping Script" -ForegroundColor Red Break } if ((Get-PAServer).name -eq "LE_PROD") { Write-Host "ACME Server Already Set to $((Get-PAServer).Name)" -ForegroundColor Green } else { Write-Host "Setting ACME Server to LE_PROD" -ForegroundColor Yellow Set-PAServer -DirectoryUrl LE_PROD } #Set-PAServer LE_STAGE $PAAccount = Get-PAAccount If ($PAAccount) { Write-host "ACME Account Found with Contact: "$($PAAccount).Contact.split(":")[1]"" } Else { Write-Host "ACME Account Not Found, Setting ACME Account with Contact $($EmailContact)" New-PAAccount -Contact $EmailContact -AcceptTOS -Force -Confirm:$false } 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 } [ServerCertificateValidationCallback]::Ignore() $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password)) $head = @{ 'Authorization' = "Basic $auth" } $Params = @{ Method = "POST" Headers = $head Uri = "https://$vCenterURL/rest/com/vmware/cis/session" } if ($IsCoreCLR) { $Params.Add("SkipCertificateCheck", $true) } try { $RestApi = Invoke-WebRequest @Params $token = (ConvertFrom-Json $RestApi.Content).value $session = @{'vmware-api-session-id' = $token } Write-Host "Session Token Created Successfully" -ForegroundColor Green } catch { Write-Error "Unable to get Session Token, Terminating Script" Show-Failure } $Question = "No" $CheckSLL = Get-PACertificate -MainDomain $CommonName $RUN=$true If ((($CheckSLL).AllSANs) -eq $CommonName) { $daysUntilExpiration = (New-TimeSpan -Start (Get-Date) -End $CheckSLL.NotAfter).Days If ($daysUntilExpiration -lt 30) { Write-Host "Renewing cert for '$("$CommonName")' " -ForegroundColor Yellow Submit-Renewal $CommonName } else { Write-Host "Cert '$("$CommonName")' not ready for renewal" -ForegroundColor Yellow $RUN=$false } } else { # --- Generate Free Let's Encrypt 90 Day SSL - Requires you to Validatr Domain Ownership. If ($Question -match '^(No|N)$') { If ($EmailContact) { New-PACertificate $CommonName -AcceptTOS -Contact $EmailContact -PreferredChain "ISRG Root X1" -Plugin PowerDNS -PluginArgs $pArgs -Force Write-Host "Requesting SSL for '$($CommonName)'" -ForegroundColor Green } else { New-PACertificate $CommonName -AcceptTOS -PreferredChain "ISRG Root X1" -Plugin PowerDNS -PluginArgs $pArgs -Force Write-Host "Requesting SSL for '$($CommonName)' Without Contact Email" -ForegroundColor Green } } } If ($RUN -eq $true) { Write-Host "Downloading ROOT CA" -ForegroundColor Green $wc = [System.Net.WebClient]::new() $rootCaPath = 'https://letsencrypt.org/certs/isrgrootx1.pem.txt' $publishedHash = '22B557A27055B33606B6559F37703928D3E4AD79F110B407D04986E1843543D1' $FileHash = Get-FileHash -InputStream ($wc.OpenRead($rootCaPath)) If ($FileHash.Hash -eq $publishedHash) { $root_CA = (New-Object System.Net.WebClient).DownloadString($rootCaPath) Write-Host "Successfully Validated ROOT CA" -ForegroundColor Green } else { Throw "Could not validate ROOT CA - Please Raise an Issue at https://github.com/virtuallywired/Install-vCenterSSL" } Write-Host "Loading Certificate Files" -ForegroundColor Green $sslcert = ((Get-Content ((Get-PACertificate).FullChainFile)) + $root_CA) -replace "`t|`n|`r", "" $privatekey = Get-Content ((Get-PACertificate).KeyFile) $fullchain = ((Get-Content ((Get-PACertificate).ChainFile)) + $root_CA) -replace "`t|`n|`r", "" Write-Host "Reformating Certificates to String" -ForegroundColor Green $cert = ((([string]$sslcert).Replace(" ", "")` ).Replace("-----BEGINCERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n")` ).Replace("-----ENDCERTIFICATE-----", "\n-----END CERTIFICATE-----") $key = ((([string]$privatekey).Replace(" ", "")` ).Replace("-----BEGINPRIVATEKEY-----", "-----BEGIN PRIVATE KEY-----\n")` ).Replace("-----ENDPRIVATEKEY-----", "\n-----END PRIVATE KEY-----") $chain = ((([string]$fullchain).Replace(" ", "")` ).Replace("-----BEGINCERTIFICATE-----", "-----BEGIN CERTIFICATE-----\n")` ).Replace("-----ENDCERTIFICATE-----", "\n-----END CERTIFICATE-----"` ).Replace("----------", "-----\n-----") Write-Host "Creating Payload" -ForegroundColor Green $json = @" { "cert": "$cert", "key": "$key", "root_cert": "$chain" } "@ $Params = @{ Method = "PUT" Headers = $session Uri = "https://$vCenterURL/api/vcenter/certificate-management/vcenter/tls" ContentType = "application/json" Body = $json } if ($IsCoreCLR) { $Params.Add("SkipCertificateCheck", $true) } Write-Host "Preparing to Replace Certificate." -ForegroundColor Green try { $Response = Invoke-WebRequest @Params Write-Host "Response Code: $($Response.StatusCode)" -ForegroundColor Blue } catch { Write-Error "Failed to Replace Certificate, Terminating Script" Show-Failure } If ($Response.StatusCode -eq "204") { Write-Host "Successfully Replaced Certificate" -ForegroundColor Green Write-Host "After this operation completes, the services using the certificate will be restarted for the new certificate to take effect." -ForegroundColor Green } else { Write-Error "Failed to Replace Certificate, Please verify Correct Configuration and Retry" } Import-Module VMware.VimAutomation.Core Rescan-VBREntity -AllHosts }