This commit is contained in:
2025-08-26 18:46:54 -05:00
parent 41b2131f16
commit 44ca72482b
2 changed files with 335 additions and 210 deletions

View File

@@ -2,246 +2,124 @@
. /opt/idssys/nodemgmt/conf/powerwall/settings.ps1
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"
param($ErrorRecord)
try {
$response = $ErrorRecord.Exception.Response
if ($response -is [System.Net.Http.HttpResponseMessage]) {
# PowerShell 7 (.NET HttpClient)
$global:responseBody = $response.Content.ReadAsStringAsync().Result
}
elseif ($response -is [System.Net.WebResponse]) {
# Legacy (.NET Framework)
$stream = $response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$global:responseBody = $reader.ReadToEnd()
}
else {
$global:responseBody = $ErrorRecord.Exception.Message
}
}
catch {
$global:responseBody = $_.Exception.Message
}
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
# ----------------------------
# Variables
# ----------------------------
$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'
PowerDNSApiHost = $WDNSHOST
PowerDNSApiKey = $PDNSAPI | ConvertTo-SecureString -AsPlainText -Force
PowerDNSUseTLS = $true
PowerDNSPort = 443
PowerDNSServerName = 'localhost'
}
# ----------------------------
# Ensure Posh-ACME Module
# ----------------------------
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
Write-Host "Posh-ACME Module Not Found, Installing..." -ForegroundColor Yellow
Install-Module -Name Posh-ACME -Force -Confirm:$false
Return
Write-Host "Please restart this script after module install." -ForegroundColor Yellow
return
}
Do {
Write-host "Waiting to for Posh-ACME Module to be Loaded" -ForegroundColor Cyan
Do {
Write-Host "Waiting for Posh-ACME Module to load..." -ForegroundColor Cyan
$PoshACME = Get-Module -ListAvailable -Name Posh-ACME
Start-Sleep -Seconds 5
}
While ( $PoshACME -eq $null )
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_PROD
$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)
#}
# ----------------------------
# vCenter API Session
# ----------------------------
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
$loginParams = @{
Uri = "https://$vCenterURL/rest/com/vmware/cis/session"
Method = 'Post'
Credential = $Credential
SslProtocol = 'Tls12'
ErrorAction = 'Stop'
}
$session = Invoke-RestMethod @loginParams
$sessionToken = $session.value
if (-not $sessionToken) {
throw "Unable to get Session Token"
}
Write-Host "Connected to vCenter API. Session established." -ForegroundColor Green
}
catch {
Write-Error "Unable to get Session Token, Terminating Script"
Show-Failure
Show-Failure -ErrorRecord $_
exit 1
}
$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
# ----------------------------
# Example REST Call (replace with actual logic)
# ----------------------------
try {
$Response = Invoke-WebRequest @Params
Write-Host "Response Code: $($Response.StatusCode)" -ForegroundColor Blue
$headers = @{ 'vmware-api-session-id' = $sessionToken }
$vmListParams = @{
Uri = "https://$vCenterURL/rest/vcenter/vm"
Method = 'Get'
Headers = $headers
SslProtocol = 'Tls12'
ErrorAction = 'Stop'
}
$vmList = Invoke-RestMethod @vmListParams
Write-Host "Retrieved VM list from vCenter:" -ForegroundColor Cyan
$vmList.value | ForEach-Object { Write-Host " - $($_.name)" }
}
catch {
Write-Error "Failed to Replace Certificate, Terminating Script"
Show-Failure
Show-Failure -ErrorRecord $_
exit 1
}
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 {
# ----------------------------
# (Continue with ACME + certificate automation)
# ----------------------------
# At this point, all network calls use Invoke-RestMethod/Invoke-WebRequest with modern TLS.
# Extend with your ACME challenge/PowerDNS automation here.
Write-Error "Failed to Replace Certificate, Please verify Correct Configuration and Retry"
}
ssh -tq -o ConnectTimeout=3 -o ConnectionAttempts=1 $VEEAMHOSTSSH "Rescan-VBREntity -AllHosts"
}

247
inc/vCenter-SSL.ps1.bak Normal file
View File

@@ -0,0 +1,247 @@
#!/usr/bin/env pwsh
. /opt/idssys/nodemgmt/conf/powerwall/settings.ps1
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 -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_PROD
$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"
}
ssh -tq -o ConnectTimeout=3 -o ConnectionAttempts=1 $VEEAMHOSTSSH "Rescan-VBREntity -AllHosts"
}