VMware.CloudFoundation.CertificateManagement.psm1
# © Broadcom. All Rights Reserved. # The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. # SPDX-License-Identifier: BSD-2 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # Allow communication with self-signed certificates when using Powershell Core. If you require all communications to be # secure and do not wish to allow communication with self-signed certificates, remove lines 20-40 before importing the # module. if ($PSEdition -eq 'Core') { $PSDefaultParameterValues.Add("Invoke-RestMethod:SkipCertificateCheck", $true) [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false | Out-Null } if ($PSEdition -eq 'Desktop') { # Allow communication with self-signed certificates when using Windows PowerShell [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false | Out-Null if ("TrustAllCertificatePolicy" -as [type]) {} else { Add-Type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertificatePolicy : ICertificatePolicy { public TrustAllCertificatePolicy() {} public bool CheckValidationResult( ServicePoint sPoint, X509Certificate certificate, WebRequest wRequest, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertificatePolicy } } ########################################################################## #Region Non Exported Functions ###### Function Get-Password { param ( [string]$user, [string]$password ) if ([string]::IsNullOrEmpty($password)) { $secureString = Read-Host -Prompt "Enter the password for $user" -AsSecureString $password = ConvertFrom-SecureString $secureString -AsPlainText } return $password } Function Get-VcenterService { <# .DESCRIPTION The Get-VcenterService retrieves the service's current status and health from vCenter and returns with an ordered hash object with the service name and health. .EXAMPLE Get-VcenterService -serviceName "certificateauthority" This example retrieves the status and health of the vCenter service named "certificateauthority" .PARAMETER serviceName The name of the vCenter service. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $serviceName ) $serviceExists = Invoke-GetService -Service $serviceName -ErrorAction SilentlyContinue if ($serviceExists -eq $null) { Write-Error "Service $serviceName does not exist." -ErrorAction Stop Exit } else { return [ordered]@{ name = $serviceName status = $serviceExists.state health = $serviceExists.health } } } Function Restart-VcenterService { <# .DESCRIPTION The Restart-VcenterService restart the vCenter service taken from parameter value and returns a hash object with the service name, the service status, and the result from restart operation. .EXAMPLE Restart-VcenterService -serviceName "certificateauthority" This example restart the vCenter service named "certificateauthority" .PARAMETER serviceName The name of the vCenter service. #> param ( [string]$serviceName ) Invoke-RestartService -Service $serviceName | Out-Null for ($count = 0; $count -lt 16; $count++) { $serviceStatus = Get-VcenterService -Service $serviceName if ($serviceStatus.status -eq "STARTED" -and $serviceStatus.health -eq "HEALTHY") { return [ordered]@{ name = $serviceName status = "GREEN" result = "Successfully restarted service." } } elseif ($serviceStatus.status -eq "STARTING" -or $serviceStatus.status -eq "STOPPING") { # Service is still starting or stopped state; sleep for 20 seconds before retry. Sleep-Time -Seconds 20 } elseif ($serviceStatus.status -eq "STARTED" -and $serviceStatus.health -eq "HEALTHY_WITH_WARNINGS") { return [ordered]@{ name = $serviceName status = "YELLOW" result = "Issues restarting service: the health state is HEALTHY_WITH_WARNINGS." } } elseif (($serviceStatus.status -eq "STARTED") -and ($serviceStatus.health -eq "DEGRADED")) { return [ordered]@{ name = $serviceName status = "RED" result = "Failed restarting service: the health state is DEGRADED." } } elseif ($serviceStatus.status -eq "STOPPED") { return [ordered]@{ name = $serviceName status = "RED" result = "Failed restarting service: the service status is STOPPED." } } elseif ($count -gt 14) { # Operation timed out return [ordered]@{ name = $serviceName status = "RED" result = "Failed restarting service: unable to retrieve service status. Operation timed out." } } } } #EndRegion Non Exported Functions ###### ########################################################################## ####################################################################################################################### ##################################################### FUNCTIONS ##################################################### Function Get-vCenterServer { <# .SYNOPSIS Retrieves the vCenter details and connection object from SDDC Manager using either a workload domain name or ESX host FQDN. .DESCRIPTION The Get-vCenterServer retrieves the vCenter details and connection object from SDDC Manager using either a workload domain name or ESX host FQDN. The cmdlet connects to the SDDC Manager using the -server, -user, and -password values. - Validates that network connectivity and authentication is possible to SDDC Manager. - Validates that network connectivity and authentication is possible to vCenter. - Validates that the workload domain exists in the SDDC Manager inventory. - Connects to vCenter and returns its details and connection in a single object. .EXAMPLE Get-vCenterServer -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -esxiFqdn [esx_host_fqdn] This example retrieves the vCenter details and connection object to which the ESX host with the fully qualified domain name belongs. .EXAMPLE Get-vCenterServer -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] This example retrieves the vCenter details and connection object belonging to the domain. .PARAMETER server The fully qualified domain name of the SDDC Manager appliance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain to retrieve the vCenter details from SDDC Manager for the connection object. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host to validate against the SDDC Manager inventory. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true, ParameterSetName = "domain")] [String] $domain, [Parameter (Mandatory = $true, ParameterSetName = "esxifqdn")] [String] $esxiFqdn ) if (Test-VCFConnection -server $server) { if (Test-VCFAuthentication -server $server -user $user -pass $pass) { if ($PsBoundParameters.ContainsKey("domain")) { $domain = $(Get-VCFWorkloadDomain | Where-Object { $_.name -eq $domain }).name } else { $esxiHost = Get-VCFHost -fqdn $esxiFqdn if (!$esxiHost) { Throw "ESX host not found. Please check the provided FQDN: $esxiFqdn." } $domain = $(Get-VCFWorkloadDomain -id $($esxiHost.domain.id)).name } if ($vcfvCenterDetails = Get-vCenterServerDetail -server $server -user $user -pass $pass -domain $domain) { if (Test-VsphereConnection -server $($vcfvCenterDetails.fqdn)) { if ($connection = Connect-VIServer -server $vcfvCenterDetails.fqdn -user $vcfvCenterDetails.ssoAdmin -pass $vcfvCenterDetails.ssoAdminPass) { $vcfvCenterServerObject = New-Object -TypeName psobject $vcfvCenterServerObject | Add-Member -NotePropertyName 'details' -NotePropertyValue $vcfvCenterDetails $vcfvCenterServerObject | Add-Member -NotePropertyName 'connection' -NotePropertyValue $connection return $vcfvCenterServerObject } } } else { Throw "Unable to return vCenter details: PRE_VALIDATION_FAILED" } } else { Throw "Unable to obtain access token from SDDC Manager ($server), check credentials: PRE_VALIDATION_FAILED" } } else { Throw "Unable to connect to ($server): PRE_VALIDATION_FAILED" } } Function Get-VcfCertificateThumbprint { <# .SYNOPSIS Retrieves certificate thumbprints for ESX hosts or vCenter instances. .DESCRIPTION The Get-VcfCertificateThumbprint cmdlet retrieves certificate thumbprints for ESX hosts or vCenter instances. .EXAMPLE Get-VcfCertificateThumbprint -esxi -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -esxiFqdn [esx_host_fqdn] This example retrieves the ESX host's certificate thumbprint for an ESX host. .EXAMPLE Get-VcfCertificateThumbprint -vcenter -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -issuer [issuer_name] This example retrieves the vCenter instance's certificate thumbprints for the vCenter instance belonging to domain and a matching issuer. .PARAMETER esxi Switch to retrieve the certificate thumbprint for an ESX host. .PARAMETER vcenter Switch to retrieve the certificate thumbprints for a vCenter instance. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain (only required when using the "vCenter" parameter). .PARAMETER issuer The name of the issuer to match with the vCenter instance's certificate thumbprints (only required when using the "vCenter" parameter). #> Param ( [Parameter (Mandatory = $true, ParameterSetName = "ESX")] [ValidateNotNullOrEmpty()] [Switch] $esxi, [Parameter (Mandatory = $true, ParameterSetName = "vCenter")] [ValidateNotNullOrEmpty()] [Switch] $vcenter, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $false, ParameterSetName = "ESX")] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $false, ParameterSetName = "vCenter")] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $false, ParameterSetName = "vCenter")] [ValidateNotNullOrEmpty()] [String] $issuer ) $pass = Get-Password -User $user -Password $pass Try { if ($PsBoundParameters.ContainsKey("esxi")) { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -esxiFqdn $esxiFqdn $esxiCertificateThumbprint = $(Get-VIMachineCertificate -Server $($vCenterServer.details.fqdn) -VMHost $esxiFqdn).Certificate.Thumbprint return $esxiCertificateThumbprint } else { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain $vcTrustedCert = Get-VITrustedCertificate -Server $vCenterServer.details.fqdn if ($vcTrustedCert) { if ($PsBoundParameters.ContainsKey("issuer")) { $vcTrustedCert = $vcTrustedCert | Where-Object { $_.issuer -match $issuer } } $vcCertificateThumbprint = $vcTrustedCert.Certificate.Thumbprint return $vcCertificateThumbprint } else { Write-Error "Unable to retrieve certificates from vCenter instance $($vCenterServer.details.fqdn)." -ErrorAction Stop } } } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Test-EsxiCertMgmtChecks { <# .SYNOPSIS Run the checks required for ESX Certificate Management for a given cluster or an ESX host. .DESCRIPTION The Test-EsxiCertMgmtChecks runs the checks required for ESX Certificate Management for a given cluster or an ESX host. The following checks are run: - Check ESX Certificate Mode - Check ESX Lockdown Mode - Confirm CA In vCenter - Check vSAN Health Status .EXAMPLE Test-EsxiCertMgmtChecks -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -issuer [issuer_name] -signedCertificate [full_certificate_file_path] This example runs the checks required for ESX Certificate Management for the cluster belonging to the domain. .EXAMPLE Test-EsxiCertMgmtChecks -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -esxiFqdn [esx_host_fqdn] -issuer [issuer_name] -signedCertificate [full_certificate_file_path] This example runs the checks required for ESX Certificate Management for an ESX host belonging to the domain. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain to retrieve the vCenter instance's certificate thumbprints from. .PARAMETER cluster The name of the cluster in which the ESX host is located. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host to verify the certificate thumbprint against. .PARAMETER signedCertificate The complete path for the signed certificate file. .PARAMETER issuer The name of the issuer to match with the vCenter instance's certificate thumbprints. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $signedCertificate, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $issuer ) $pass = Get-Password -User $user -Password $pass $errorMessage = @() $warningMessage = @() $statusMessage = @() Try { Write-Output "############## Running Prechecks for ESX Certificate Management ###############" $status = "FAILED" $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain $mode = Get-EsxiCertificateMode -server $server -user $user -pass $pass -domain $domain if ($mode -ne "custom") { $msg = "Certificate Management Mode is not set to $mode on the vCenter instance $($vCenterServer.details.fqdn)." $errorMessage += $msg } else { $msg = "Certificate Management Mode is set to $mode on the vCenter instance $($vCenterServer.details.fqdn)." $statusMessage += $statusMessage $status = "PASSED" } Write-Output "Check ESX Certificate Mode: $status" $status = "FAILED" if ($PsBoundParameters.ContainsKey("esxiFqdn")) { $lockdownModes = Get-EsxiLockdownMode -server $server -user $user -pass $pass -domain $domain -cluster $cluster -esxiFqdn $esxiFqdn } else { $lockdownModes = Get-EsxiLockdownMode -server $server -user $user -pass $pass -domain $domain -cluster $cluster } foreach ($lockdownMode in $lockdownModes) { if ($lockdownMode -like "*lockdownDisabled*") { $statusMessage += $lockdownMode $status = "PASSED" } else { $errorMessage += $lockdownMode } } Write-Output "Check ESX Lockdown Mode: $status" $status = "FAILED" $caStatus = Confirm-CAInvCenterServer -server $server -user $user -pass $pass -domain $domain -issuer $issuer -signedCertificate $signedCertificate if ($caStatus -eq $true) { $msg = "Signed certificate thumbprint matches with the vCenter certificate authority thumbprint." $statusMessage += $msg $status = "PASSED" } elseif ($caStatus -eq $false) { $msg = "Signed certificate thumbprint does not match any of the vCenter certificate authority thumbprints." $errorMessage += $msg } else { $msg = "Error: Unable to Confirm CA In vCenter." $msg = $msg + $caStatus $errorMessage += $msg } Write-Output "Confirm CA In vCenter: $status" $status = "FAILED" $vsanStatus = Get-vSANHealthSummary -server $server -user $user -pass $pass -domain $domain -cluster $cluster -errorAction SilentlyContinue -ErrorVariable errorMsg -WarningAction SilentlyContinue -WarningVariable warnMsg if ($warnMsg) { $warningMessage += $warnMsg $status = "WARNING" } if ($errorMsg) { $errorMessage += $errorMsg } if ($vsanStatus -eq 0) { $status = "PASSED" $statusMessage += $vsanStatus } Write-Output "Check vSAN Health Status: $status" Write-Output "############## Finished Running Prechecks for ESX Certificate Management ###############" if ($statusMessage) { Write-Debug "############## Status of ESX Certificate Management Prechecks : ###############" foreach ($msg in $statusMessage) { Write-Debug $msg } } if ($warningMessage) { Write-Output "############## Warnings Raised While Running Prechecks for ESX Certificate Management : ###############" foreach ($msg in $warningMessage) { Write-Warning $msg } } if ($errorMessage) { Write-Output "############## Issues Found While Running Prechecks for ESX Certificate Management : ###############" foreach ($msg in $errorMessage) { Write-Error $msg } } } Catch { Debug-ExceptionWriter -object $_ } } Function Confirm-EsxiCertificateInstalled { <# .SYNOPSIS Verifies if the provided certificate is already on the ESX host. .DESCRIPTION The Confirm-EsxiCertificateInstalled cmdlet will get the thumbprint from the provided signed certificate and matches it with the certificate thumbprint from ESX host. You need to pass in the complete path for the certificate file. Returns true if certificate is already installed, else returns false. .EXAMPLE Confirm-EsxiCertificateInstalled -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -esxiFqdn [esx_host_fqdn] -signedCertificate [full_certificate_file_path] This example checks the thumbprint of the provided signed certificate with the thumbprint on ESX host. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host to verify the certificate thumbprint against. .PARAMETER signedCertificate The complete path for the signed certificate file. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $signedCertificate ) $pass = Get-Password -User $user -Password $pass Try { if (Test-Path $signedCertificate -PathType Leaf ) { Write-Debug "Certificate file found - $signedCertificate" } else { Write-Error "Could not find certificate in $signedCertificate." -ErrorAction Stop return } $esxiCertificateThumbprint = Get-VcfCertificateThumbprint -esxi -server $server -user $user -pass $pass -esxiFqdn $esxiFqdn $crt = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2($signedCertificate) $signedCertThumbprint = $crt.Thumbprint if ($esxiCertificateThumbprint -eq $signedCertThumbprint) { Write-Debug "Signed certificate thumbprint matches with the ESX host certificate thumbprint." Write-Warning "Certificate is already installed on ESX host $esxiFqdn : SKIPPED" return $true } else { Write-Debug "ESX host's certificate thumbprint ($esxiCertificateThumbprint) does not match with the thumbprint of provided certificate ($signedCertThumbprint)" Write-Debug "Provided certificate is not installed on ESX host $esxiFqdn." return $false } } Catch { Debug-ExceptionWriter -object $_ } } Function Confirm-CAInvCenterServer { <# .SYNOPSIS Verifies the root certificate thumbprint matches with one of the CA thumbprints from vCenter instance. .DESCRIPTION The Confirm-CAInvCenterServer cmdlet gets the thumbprint from the root certificate and matches it with the CA thumbprint from the vCenter instance.You need to pass in the complete path for the certificate file. Returns true if thumbprint matches, else returns false. .EXAMPLE Confirm-CAInvCenterServer -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -issuer [issuer_name] -signedCertificate [certificate_path] This example matches the thumbprint of provided root certificate file with the thumbprints on the vCenter instance matching the issuer. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain to retrieve the vCenter instance's certificate thumbprints from. .PARAMETER signedCertificate The complete path for the root certificate file. .PARAMETER issuer The name of the issuer to match with the thumbprint. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $signedCertificate, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $issuer ) $pass = Get-Password -User $user -Password $pass Try { if ($PsBoundParameters.ContainsKey("issuer")) { $vcThumbprints = Get-VcfCertificateThumbprint -vcenter -server $server -user $user -pass $pass -domain $domain -issuer $issuer } else { $vcThumbprints = Get-VcfCertificateThumbprint -vcenter -server $server -user $user -pass $pass -domain $domain } if (Test-Path $signedCertificate -PathType Leaf ) { Write-Output "Certificate file found - $signedCertificate." } else { Write-Error "Could not find certificate in $signedCertificate." -ErrorAction Stop return } $crt = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2($signedCertificate) $signedCertThumbprint = $crt.Thumbprint $match = $false foreach ($vcThumbprint in $vcThumbprints) { if ($vcThumbprint -eq $signedCertThumbprint) { Write-Output "Signed certificate thumbprint matches with the vCenter certificate authority thumbprint." $match = $true break } } if (!$match) { Write-Error "Signed certificate thumbprint does not match any of the vCenter certificate authority thumbprints." } return $match } Catch { Debug-ExceptionWriter -object $_ } } Function Get-EsxiCertificateMode { <# .SYNOPSIS Retrieves the certificate management mode value from the vCenter instance for a workload domain. .DESCRIPTION The Get-EsxiCertificateMode cmdlet retrieves the certificate management mode value from vCenter instance for a workload domain. .EXAMPLE Get-EsxiCertificateMode -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] This example retrieves the certificate management mode value for the vCenter instance for the workload domain. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain to retrieve the certificate management mode value for. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain ) $pass = Get-Password -User $user -Password $pass Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain $certModeSetting = Get-AdvancedSetting "vpxd.certmgmt.mode" -Entity $vCenterServer.connection return $certModeSetting.value } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Set-EsxiCertificateMode { <# .SYNOPSIS Sets the certificate management mode in vCenter for the ESX hosts in a workload domain. .DESCRIPTION The Set-EsxiCertificateMode cmdlet sets the certificate management mode in vCenter for the ESX hosts in a workload domain. .EXAMPLE Set-EsxiCertificateMode -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -mode custom This example sets the certificate management mode to custom in vCenter for the ESX hosts in workload domain. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain to set the vCenter instance certificate management mode setting for. .PARAMETER mode The certificate management mode to set in vCenter. One of "custom" or "vmca". #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true)] [ValidateSet ("custom", "vmca")] [String] $mode ) $pass = Get-Password -User $user -Password $pass Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain $certModeSetting = Get-AdvancedSetting "vpxd.certmgmt.mode" -Entity $vCenterServer.connection if ($certModeSetting.value -ne $mode) { Set-AdvancedSetting $certModeSetting -Value $mode -confirm:$false # Restart "VMware Certificate Authority" and "VMware Certificate Management" services. Write-Output 'Restarting vCenter services ("VMware Certificate Authority" and "VMware Certificate Management") for the change to take effect.' $services = @("certificateauthority", "certificatemanagement") $failedServices = @() foreach ($service in $services) { $serviceStatus = Restart-VcenterService -serviceName $service if ($serviceStatus.status -ne "GREEN") { $failedServices += $serviceStatus } } if ($failedServices.Count -gt 0) { $failedServicesErrorString = "" foreach ($failedItem in $failedServices) { $failedServicesErrorString += "$($failedItem.name): $($failedItem.result). `n" } Write-Error "The following services failed to restart successfully:`n$failedServicesErrorString`nSet-EsxiCertificateMode operation Failed." -ErrorAction Stop } else { Write-Output 'vCenter services ("VMware Certificate Authority" and "VMware Certificate Management") restarted successfully.' } } else { Write-Warning "Certificate Management Mode already set to $mode on the vCenter instance $($vCenterServer.details.fqdn): SKIPPED" } } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Get-vSANHealthSummary { <# .SYNOPSIS Retrieves the vSAN health summary from vCenter for a cluster. .DESCRIPTION The Get-vSANHealthSummary cmdlet gets the vSAN health summary from vCenter for a cluster. If any status is YELLOW or RED, a WARNING or ERROR will be raised. .EXAMPLE Get-vSANHealthSummary -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] This example gets the vSAN health summary for cluster. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the cluster is located. .PARAMETER cluster The name of the cluster to retrieve the vSAN health summary for. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $cluster ) $pass = Get-Password -User $user -Password $pass Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain $vSANClusterHealthSystem = Get-VSANView -Id "VsanVcClusterHealthSystem-vsan-cluster-health-system" $overallStatus = 0 if (!$vSANClusterHealthSystem) { Write-Error "Cannot run the Get-vSANHealthSummary cmdlet because the vSAN health service is not running." return 2 } $cluster_view = (Get-Cluster -Name $cluster).ExtensionData.MoRef $results = $vSANClusterHealthSystem.VsanQueryVcClusterHealthSummary($cluster_view, $null, $null, $true, $null, $null, 'defaultView') $healthCheckGroups = $results.groups foreach ($healthCheckGroup in $healthCheckGroups) { $health = @("Yellow", "Red") $output = $healthCheckGroup.grouptests | Where-Object TestHealth -in $health | Select-Object TestHealth, @{l = "TestId"; e = { $_.testid.split(".") | Select-Object -last 1 } }, TestName, TestShortDescription, @{l = "Group"; e = { $healthCheckGroup.GroupName } } $healthCheckTestHealth = $output.TestHealth $healthCheckTestName = $output.TestName $healthCheckTestShortDescription = $output.TestShortDescription if ($healthCheckTestName) { if ($healthCheckTestHealth -eq "yellow") { $overallStatus = ($overallStatus, 1 | Measure-Object -Max).Maximum Write-Warning "$($vCenterServer.details.fqdn) - vSAN cluster $cluster | vSAN Alarm Name - $healthCheckTestName | Alarm Description - $healthCheckTestShortDescription" } if ($healthCheckTestHealth -eq "red") { $overallStatus = ($overallStatus, 2 | Measure-Object -Max).Maximum Write-Error "vSAN status is RED. Please check the vSAN health before continuing." Write-Error "$($vCenterServer.details.fqdn) - vSAN Clustername $cluster | vSAN Alarm Name - $healthCheckTestName | Alarm Description - $healthCheckTestShortDescription" } } } if ($overallStatus -eq 0) { Write-Output "The vSAN health status for $cluster is GREEN." } return $overallStatus } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Get-EsxiConnectionState { <# .SYNOPSIS Retrieves the ESX host connection state from vCenter. .DESCRIPTION The Get-EsxiConnectionState cmdlet gets the connection state of an ESX host. One of "Connected", "Disconnected", "Maintenance", or "NotResponding" Depends on a connection to a vCenter instance. .EXAMPLE Get-EsxiConnectionState -esxiFqdn [esx_host_fqdn] This example gets an ESX host's connection state. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $esxiFqdn ) $response = Get-VMHost -name $esxiFqdn return $response.ConnectionState } Function Get-EsxiHostVsanMaintenanceModePrecheck { <# .SYNOPSIS Checks for any issues when the ESX H=host enters a particular vSAN maintenance mode. .DESCRIPTION The Get-EsxiHostVsanMaintenanceModePrecheck cmdlet checks if there's any issues for the ESX host entering a particular vSAN maintenance mode. The cmdlet will halt the script if the pre check fails. .EXAMPLE Get-EsxiHostVsanMaintenanceModePrecheck -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -vsanDataMigrationMode Full This example checks each ESX host within a cluster within the workload domain for any issues when entering a particular vSAN maintenance mode Get-EsxiHostVsanMaintenanceModePrecheck -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -host [esx_host_fqdn] -vsanDataMigrationMode Full This example checks each ESX host within a cluster within the workload domain for any issues when entering a particular vSAN maintenance mode .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the cluster is located. .PARAMETER cluster The name of the cluster containing the ESX hosts. .PARAMETER esxiFqdn The name of the FQDN of an ESX host. .PARAMETER vsanDataMigrationMode The type of vSAN maintenance mode. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true, ParameterSetName = "cluster")] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $true, ParameterSetName = "esxiFqdn")] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true)] [ValidateSet ("Full", "EnsureAccessibility", "NoDataMigration")] [String] $vsanDataMigrationMode ) if ($vsanDataMigrationMode -eq "Full") { $vsanMigrationMode = "evacuateAllData" } elseif ($vsanDataMigrationMode -eq "EnsureAccessibility") { $vsanMigrationMode = "ensureObjectAccessibility" } elseif ($vsanDataMigrationMode -eq "NoDataMigration") { $vsanMigrationMode = "noAction" } else { Write-Error "No validate vsan Data migration mode selected" -ErrorAction Stop } Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain if ($PsBoundParameters.ContainsKey("cluster")) { $clusterDetails = Get-VCFCluster -Name $cluster if ($clusterDetails) { $esxiHosts = Get-VCFHost | Where-Object { $_.cluster.id -eq $clusterDetails.id } | Sort-Object -Property fqdn if (!$esxiHosts) { Write-Warning "No ESX hosts found in cluster $cluster." } } else { Write-Error "Unable to locate cluster $cluster in $($vCenterServer.details.fqdn) vCenter: PRE_VALIDATION_FAILED" -ErrorAction Stop } } else { $esxiHosts = Get-VCFHost -fqdn $esxiFqdn if (!$esxiHosts) { Write-Error "No ESX host $esxiFqdn found in workload domain $domain." -ErrorAction Stop } } foreach ($esxiHost in $esxiHosts) { $vsanReport = Get-VsanEnterMaintenanceModeReport -VMHost $esxiHost.fqdn -VsanDataMigrationMode $vsanMigrationMode if ($vsanReport.OverallStatus -ne "green") { Write-Error "ESX host($($esxiHost.fqdn)) vSAN Data Migration($vsanDataMigrationMode) Pre-check failed with error $($vsanReport.OverallStatus)" -ErrorAction Stop } else { Write-Output "ESX host($($esxiHost.fqdn)) vSAN Data Migration($vsanDataMigrationMode) Pre-check: $($vsanReport.OverallStatus)" } } } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Set-EsxiConnectionState { <# .SYNOPSIS Sets the ESX host connection state in vCenter. .DESCRIPTION The Set-EsxiConnectionState cmdlet sets the connection state of an ESX host. One of "Connected", "Disconnected" or "Maintenance". If setting the connection state to Maintenance, provide the VsanDataMigrationMode for a vSAN environment. One of "Full", "EnsureAccessibility", or "NoDataMigration". Depends on a connection to a vCenter instance. .EXAMPLE Set-EsxiConnectionState -esxiFqdn [esx_host_fqdn] -state Connected This example sets an ESX host's connection state to Connected. .EXAMPLE Set-EsxiConnectionState -esxiFqdn [esx_host_fqdn] -state Maintenance -vsanDataMigrationMode Full This example sets an ESX host's connection state to Maintenance with a vSAN data migration mode set to Full data migration. .EXAMPLE Set-EsxiConnectionState -esxiFqdn [esx_host_fqdn] -state Maintenance -vsanDataMigrationMode EnsureAccessibility -migratePowerOffVMs This example sets an ESX host's connection state to Maintenance and will migrate any Power Off or Suspend VMs to other ESX hosts and will set vSAN data migration mode to Ensure Accessibility. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host. .PARAMETER state The connection state to set the ESX host to. One of "Connected", "Disconnected" or "Maintenance". .PARAMETER migratePowerOffVMs This optional switch argument will determined if power off and suspended VMs will be migrated off the ESX host when setting the ESX host to Maintenance. .PARAMETER vsanDataMigrationMode The vSAN data migration mode to use when setting the ESX host to Maintenance. One of "Full", "EnsureAccessibility", or "NoDataMigration". .PARAMETER timeout The timeout in seconds to wait for the ESX host to reach the desired connection state. Default is 18000 seconds (5 hours). .PARAMETER pollInterval The poll interval in seconds to check the ESX host connection state. Default is 60 seconds. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true)] [ValidateSet ("Connected", "Disconnected", "Maintenance")] [String] $state, [Parameter (Mandatory = $false)] [Switch] $migratePowerOffVMs, [Parameter (Mandatory = $false)] [ValidateSet ("Full", "EnsureAccessibility", "NoDataMigration")] [String] $vsanDataMigrationMode, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $timeout = 18000, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pollInterval = 60 ) if ($state -ieq (Get-EsxiConnectionState -esxiFqdn $esxiFqdn)) { Write-Warning "ESX host $esxiFqdn is already in the $state connection state: SKIPPED" return } if ($state -ieq "maintenance") { if ($PSBoundParameters.ContainsKey("vsanDataMigrationMode")) { if (($vsanDataMigrationMode -eq "EnsureAccessibility") -and !($migratePowerOffVMs.IsPresent)) { Write-Output "Entering $state connection state for ESX host $esxiFqdn with vSAN data migration mode set to $vsanDataMigrationMode." Write-Output "Power off VMs and suspended VMs are left on the ESX host $esxiFqdn." Set-VMHost -VMHost $esxiFqdn -State $state -VsanDataMigrationMode $vsanDataMigrationMode -confirm:$false } elseif (($vsanDataMigrationMode -eq "NoDataMigration") -and !($migratePowerOffVMs.IsPresent)) { Write-Output "Entering $state connection state for ESX host $esxiFqdn with vSAN data migration mode set to $vsanDataMigrationMode." Write-Output "Power off VMs and suspended VMs are left on the ESX host $esxiFqdn." Set-VMHost -VMHost $esxiFqdn -State $state -VsanDataMigrationMode $vsanDataMigrationMode -confirm:$false } else { Write-Output "Entering $state connection state for ESX host $esxiFqdn with vSAN data migration mode set to $vsanDataMigrationMode." Write-Output "Power off VMs and suspended VMs will be migrated off to other ESX hosts." Set-VMHost -VMHost $esxiFqdn -State $state -VsanDataMigrationMode $vsanDataMigrationMode -Evacuate -confirm:$false } } else { if ($migratePowerOffVMs.IsPresent) { Write-Output "Entering $state connection state for ESX host $esxiFqdn. (Power off VMs and suspended VMs will be migrated off to other ESX hosts)" Set-VMHost -VMHost $esxiFqdn -State $state -Evacuate -confirm:$false } else { Write-Output "Entering $state connection state for ESX host $esxiFqdn. (Power off VMs and suspended VMs are left on the ESX host)" Set-VMHost -VMHost $esxiFqdn -State $state -confirm:$false } } } else { Write-Output "Changing the connection state for ESX host $esxiFqdn to $state." Set-VMHost -VMHost $esxiFqdn -State $state -confirm:$false } $timeout = New-TimeSpan -Seconds $timeout $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() do { $currentState = Get-EsxiConnectionState -esxiFqdn $esxiFqdn if ($state -ieq $currentState) { Write-Output "Successfully changed the connection state for ESX host $esxiFqdn to $state." break } else { if ($state -ieq "Connected") { Set-VMHost -VMHost $esxiFqdn -State $state -confirm:$false -ErrorAction SilentlyContinue -ErrorVariable $errMsg -WarningAction SilentlyContinue } Write-Output "Polling the connection every $pollInterval seconds. Waiting for the connection state to change to $state." } Start-Sleep -Seconds $pollInterval } while ($stopwatch.elapsed -lt $timeout) } Function Get-EsxiLockdownMode { <# .SYNOPSIS Retrieves the ESX host lockdown mode state from a vCenter instance. .DESCRIPTION The Get-EsxiLockdownMode cmdlet gets the lockdown mode value for all ESX hosts in a given cluster or for a given ESX host within the cluster. If -esxiFqdn is provided, only the value for that host is returned. .EXAMPLE Get-EsxiLockdownMode -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] This example retrieves the lockdown mode for each ESX host in a cluster. .EXAMPLE Get-EsxiLockdownMode -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -esxiFqdn [esx_host_fqdn] This example retrieves the lockdown mode state for an ESX host in cluster. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the cluster is located. .PARAMETER cluster The name of the cluster in which the ESX host is located. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host to retrieve the lockdown mode state for. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $esxiFqdn ) $pass = Get-Password -User $user -Password $pass Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain if (Get-Cluster | Where-Object { $_.Name -eq $cluster }) { if ($PsBoundParameters.ContainsKey("esxiFqdn")) { $esxiHosts = Get-Cluster $cluster | Get-VMHost -Name $esxiFqdn } else { $esxiHosts = Get-Cluster $cluster | Get-VMHost | Sort-Object -Property Name } if (!$esxiHosts) { Write-Warning "No ESX hosts found within cluster $cluster." } } else { Write-Error "Unable to locate cluster $cluster in $($vCenterServer.details.fqdn) vCenter: PRE_VALIDATION_FAILED" -ErrorAction Stop } foreach ($esxiHost in $esxiHosts) { $lockdownMode = (Get-VMHost -name $esxiHost).ExtensionData.Config.LockdownMode Write-Output "ESX host $esxiHost lockdown mode is set to $lockdownMode." } if ($PsBoundParameters.ContainsKey("esxiFqdn")) { return $lockdownMode } } Catch { Debug-ExceptionWriter -object $_ } } Function Set-EsxiLockdownMode { <# .SYNOPSIS Sets the lockdown mode for all ESX hosts in a given cluster. .DESCRIPTION The Set-EsxiLockdownMode cmdlet sets the lockdown mode for all ESX hosts in a given cluster. .EXAMPLE Set-EsxiLockdownMode -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -enable This example will enable the lockdown mode for all ESX hosts in a cluster. .EXAMPLE Set-EsxiLockdownMode -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -disable This example will disable the lockdown mode for all ESX hosts in a cluster. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the cluster is located. .PARAMETER cluster The name of the cluster in which the ESX host is located. .PARAMETER enable Enable lockdown mode for the ESX host(s). .PARAMETER disable Disable lockdown mode for the ESX host(s). #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $true, ParameterSetName = "enable")] [ValidateNotNullOrEmpty()] [Switch] $enable, [Parameter (Mandatory = $true, ParameterSetName = "disable")] [ValidateNotNullOrEmpty()] [Switch] $disable ) $pass = Get-Password -User $user -Password $pass Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain if (Get-Cluster | Where-Object { $_.Name -eq $cluster }) { $esxiHosts = Get-Cluster $cluster | Get-VMHost | Sort-Object -Property Name if (!$esxiHosts) { Write-Warning "No ESX hosts found within $cluster cluster." } } else { Write-Error "Unable to locate Cluster $cluster in $($vCenterServer.details.fqdn) vCenter: PRE_VALIDATION_FAILED" -ErrorAction Stop } if ($PSBoundParameters.ContainsKey("enable")) { Write-Output "Enabling lockdown mode for each ESX host in $cluster cluster" foreach ($esxiHost in $esxiHosts) { $currentLockdownMode = (Get-VMHost -name $esxiHost).ExtensionData.Config.LockdownMode if ($currentLockdownMode -eq "lockdownDisabled") { ($esxiHost | Get-View).EnterLockdownMode() Write-Output "Changing lockdown mode for ESX host $esxiHost from $currentLockdownMode to lockdownNormal." $newLockdownMode = (Get-VMHost -name $esxiHost).ExtensionData.Config.LockdownMode if ($lockdownMode -eq $newLockdownMode) { Write-Error "Unable to change lockdown mode for ESX host $esxiHost from $currentLockdownMode to lockdownNormal. Lockdown mode is set to $newLockdownMode." -ErrorAction Stop } } else { Write-Warning "Lockdown mode for ESX host $esxiHost is already set to lockdownNormal: SKIPPED" } } } if ($PSBoundParameters.ContainsKey("disable")) { Write-Output "Disabling lockdown mode for each ESX host in $cluster cluster." foreach ($esxiHost in $esxiHosts) { $currentLockdownMode = (Get-VMHost -name $esxiHost).ExtensionData.Config.LockdownMode if ($currentLockdownMode -ne "lockdownDisabled") { ($esxiHost | Get-View).ExitLockdownMode() Write-Output "Changing lockdown mode for ESX host $esxiHost from $currentLockdownMode to lockdownDisabled." $newLockdownMode = (Get-VMHost -name $esxiHost).ExtensionData.Config.LockdownMode if ($currentLockdownMode -eq $newLockdownMode) { Write-Error "Unable to change lockdown mode for ESX host $esxiHost from $currentLockdownMode to lockdownDisabled. Lockdown mode is set to $newLockdownMode." -ErrorAction Stop } } else { Write-Warning "Lockdown mode for ESX host $esxiHost is already set to lockdownDisabled: SKIPPED" } } } } Catch { Debug-ExceptionWriter -object $_ } } Function Restart-EsxiHost { <# .SYNOPSIS Restarts an ESX host and poll for connection availability. .DESCRIPTION The Restart-EsxiHost cmdlet restarts an ESX host and polls for connection availability. Timeout value is in seconds. .EXAMPLE Restart-EsxiHost -esxiFqdn [esx_host_fqdn] -user [admin_username] -pass [admin_password] -poll $true -timeout 1800 -pollInterval 30 This example restarts an ESX host and polls the connection availability every 30 seconds. It will timeout after 1800 seconds. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host. .PARAMETER user The username to authenticate to the ESX host. .PARAMETER pass The password to authenticate to the ESX host. .PARAMETER poll Poll for connection availability after restarting the ESX host. Default is true. .PARAMETER timeout The timeout value in seconds. Default is 1800 seconds. .PARAMETER pollInterval The poll interval in seconds. Default is 30 seconds. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [bool] $poll = $true, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $timeout = 1800, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pollInterval = 30 ) $pass = Get-Password -User $user -Password $pass # Connect to the ESX host. Connect-VIServer $esxiFqdn -User $user -password $pass -Force $vmHost = Get-VMHost -Server $esxiFqdn if (!$vmHost) { Write-Error "Unable to locate ESX host with FQDN $esxiFqdn : PRE_VALIDATION_FAILED" -ErrorAction Stop return } else { Write-Output "Restarting $esxiFqdn" } # Retrieves the ESX host uptime before restart. $esxiUptime = New-TimeSpan -Start $vmHost.ExtensionData.Summary.Runtime.BootTime.ToLocalTime() -End (Get-Date) Restart-VMHost $esxiFqdn -server $esxiFqdn -Confirm:$false Disconnect-VIServer -server $esxiFqdn -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null if ($poll) { Write-Output "Waiting for ESX host $esxiFqdn to restart. Polling the connection every $pollInterval seconds." Start-Sleep -Seconds $pollInterval $timeout = New-TimeSpan -Seconds $timeout $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() do { if (Test-EsxiConnection -server $esxiFqdn) { if (Connect-VIServer $esxiFqdn -User $user -Password $pass -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue) { $vmHost = Get-VMHost -Server $esxiFqdn $currentUpTime = New-TimeSpan -Start $vmHost.ExtensionData.Summary.Runtime.BootTime.ToLocalTime() -End (Get-Date) if ($($esxiUptime.TotalSeconds) -gt $($currentUpTime.TotalSeconds)) { Write-Output "ESX host $esxiFqdn has been restarted and is now accessible." } else { Write-Output "ESX host $esxiFqdn uptime: $($esxiUptime.TotalSeconds) | Current Uptime - $($currentUpTime.TotalSeconds)" } Disconnect-VIServer -Server $esxiFqdn -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null return } } Write-Output "Waiting for ESX host $esxiFqdn to restart and become accessible." Start-Sleep -Seconds $pollInterval } while ($stopwatch.elapsed -lt $timeout) Write-Error "ESX host $esxiFqdn did not respond after $($timeout.TotalMinutes) seconds. Please verify that the ESX host is online and accessible." -ErrorAction Stop } else { Write-Warning "Restart of ESX host $esxiFqdn triggered without polling connection state. Please monitor the connection state in the vSphere Client." } } Function Install-EsxiCertificate { <# .SYNOPSIS Installs a certificate for an ESX host or for each ESX host in a cluster. .DESCRIPTION The Install-EsxiCertificate cmdlet will replace the certificate for an ESX host or for each ESX host in a cluster. You must provide the directory containing the signed certificate files. Certificate names should be in format <esx_host_fqdn>.crt. The workflow will put the ESX host in maintenance mode with full data migration, disconnect the ESX host from the vCenter, replace the certificate, restart the ESX host, and the exit maintenance mode once the ESX host is online. .EXAMPLE Install-EsxiCertificate -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -esxiFqdn [esx_host_fqdn] -certificateDirectory [certificate_directory_path] -certificateFileExt ".cer" This example will install the certificate to the ESX host in the workload domain from the provided path. .EXAMPLE Install-EsxiCertificate -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -certificateDirectory [certificate_directory_path] -certificateFileExt ".cer" This example will install certificates for each ESX host in cluster in the workload domain from the provided path. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the ESX host is located. .PARAMETER cluster The name of the cluster in which the ESX host is located. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host. .PARAMETER certificateDirectory The directory containing the signed certificate files. .PARAMETER certificateFileExt The file extension of the certificate files. One of ".crt", ".cer", ".pem", ".p7b", or ".p7c". .PARAMETER timeout The timeout in seconds for putting the ESX host in maintenance mode. Default is 18000 seconds (5 hours). .PARAMETER migratePowerOffVMs This optional switch argument will determined if power off and suspended VMs will be migrated off the ESX host when setting the ESX host to Maintenance. .PARAMETER vsanDataMigrationMode The vSAN data migration mode to use when setting the ESX host to Maintenance. One of "Full" or "EnsureAccessibility". .PARAMETER uploadPrivateKey Option to upload of a custom Private Key for the ESX host. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true, ParameterSetName = "cluster")] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $true, ParameterSetName = "host")] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true) ] [ValidateNotNullOrEmpty()] [String] $certificateDirectory, [Parameter (Mandatory = $false)] [Switch] $migratePowerOffVMs, [Parameter (Mandatory = $false)] [ValidateSet ("Full", "EnsureAccessibility")] [String] $vsanDataMigrationMode, [Parameter (Mandatory = $true)] [ValidateSet(".crt", ".cer", ".pem", ".p7b", ".p7c")] [String] $certificateFileExt, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [Switch] $uploadPrivateKey, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $timeout = 18000 ) Try { $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain if ($PsBoundParameters.ContainsKey("cluster")) { $clusterDetails = Get-VCFCluster -Name $cluster if ($clusterDetails) { $esxiHosts = Get-VCFHost | Where-Object { $_.cluster.id -eq $clusterDetails.id } | Sort-Object -Property fqdn if (!$esxiHosts) { Write-Warning "No ESX hosts found in cluster $cluster." } } else { Write-Error "Unable to locate cluster $cluster in $($vCenterServer.details.fqdn) vCenter: PRE_VALIDATION_FAILED" -ErrorAction Stop } } else { $esxiHosts = Get-VCFHost -fqdn $esxiFqdn if (!$esxiHosts) { Write-Error "No ESX host $esxiFqdn found in workload domain $domain." -ErrorAction Stop } } $version = Get-VCFManager -version $vcfVersion = $version.Split('.')[0] + "." + $version.Split('.')[1] if ($vcfVersion -ge "5.2") { # get session ID $url = "https://$($vCenterServer.details.fqdn)/sdk/vim25/8.0.3.0/SessionManager/SessionManager/Login" $sessionId = (Invoke-WebRequest -Uri "$url" -Body ( @{'userName' = "$($vCenterServer.details.ssoAdmin)"; 'password' = "$($vCenterServer.details.ssoAdminPass)" } | ConvertTo-Json ) -Method:POST -ContentType:'application/json').Headers.'vmware-api-session-id' if ($sessionId[0].length -eq 40) { $sessionId = $sessionId[0] } else { Write-Error "Unable to retrieve session ID from $($vcenter.details.fqdn)'s API: PRE_VALIDATION_FAILED" -ErrorAction Stop } } else { # Perform ESX host vSAN data migration pre-check. if ($PsBoundParameters.ContainsKey("cluster")) { Write-Output "Performing Data Migration Pre-check on the cluster $cluster" Get-EsxiHostVsanMaintenanceModePrecheck -server $server -user $user -pass $pass -domain $domain -cluster $cluster -vsanDataMigrationMode $vsanDataMigrationMode } else { Write-Output "Performing Data Migration Pre-check on the ESX host $esxiFqdn" Get-EsxiHostVsanMaintenanceModePrecheck -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -vsanDataMigrationMode $vsanDataMigrationMode } } # Certificate replacement starts here. $replacedHosts = New-Object Collections.Generic.List[String] $skippedHosts = New-Object Collections.Generic.List[String] foreach ($esxiHost in $esxiHosts) { $esxiFqdn = $esxiHost.fqdn $crtPath = Join-Path -Path $certificateDirectory -childPath $esxiFqdn$certificateFileExt if (!(Test-Path $crtPath -PathType Leaf )) { Write-Error "Certificate not found at $crtPath. Skipping certificate replacement for ESX host $esxiFqdn." $skippedHosts.Add($esxiFqdn) continue } if ($vcfVersion -ge "5.2") { $keyPath = Join-Path -Path $certificateDirectory -childPath ($esxiFqdn + ".key") if (!(Test-Path $keyPath -PathType Leaf) -and ($PSBoundParameters.ContainsKey("uploadPrivateKey"))) { Write-Error "Private key not found at $keyPath. Skipping certificate replacement for ESX host $esxiFqdn." $skippedHosts.Add($esxiFqdn) continue } } if (Confirm-EsxiCertificateInstalled -server $server -user $user -pass $pass -esxiFqdn $esxiFqdn -signedCertificate $crtPath) { $skippedHosts.Add($esxiFqdn) continue } elseif ($vcfVersion -ge "5.2") { Write-Output "Starting certificate replacement for ESX host $esxiFqdn." $esxCertificatePem = Get-Content $crtPath -Raw $esxiConfig = Get-View -ViewType HostSystem -Filter @{"Name" = "$esxiFqdn" } $esxiHostConfig = Get-View -Id $esxiConfig.ConfigManager.CertificateManager $esxiHostConfigMoid = $esxiConfig.ConfigManager.CertificateManager.value if ($PSBoundParameters.ContainsKey("uploadPrivateKey")) { $esxCertificateKey = Get-Content $keyPath -Raw $url = "https://$($vCenterServer.details.fqdn)/sdk/vim25/8.0.3.0/HostCertificateManager/$esxiHostConfigMoid/ProvisionServerPrivateKey" # Install ESX Private Key $body = @{'key' = "$esxCertificateKey" } | ConvertTo-Json $respond = Invoke-WebRequest -Headers @{'vmware-api-session-id' = "$sessionId" } -Uri $url -Body $body -Method:POST -ContentType:'application/json' if (!($respond.StatusCode -eq 204)) { Write-Error "Upload private key to ESX host $esxiFqdn failed. " -ErrorAction Stop } } # Install ESX Certificate $esxiHostConfig.InstallServerCertificate($esxCertificatePem) # trigger refresh on affected services $url = "https://$($vCenterServer.details.fqdn)/sdk/vim25/8.0.3.0/HostCertificateManager/$esxiHostConfigMoid/NotifyAffectedServices" $respond = Invoke-WebRequest -Headers @{'vmware-api-session-id' = "$sessionId" } -Uri $url -Method:POST -ContentType:'application/json' $replacedHosts.Add($esxiFqdn) } else { $esxiCredential = (Get-VCFCredential -resourcename $esxiFqdn | Where-Object { $_.username -eq "root" }) if ($esxiCredential) { if ($clusterDetails.primaryDatastoreType -ieq "vsan" -or $esxiHost.datastoreType -ieq "vsan" ) { if (($vsanDataMigrationMode -eq "EnsureAccessibility") -and !($migratePowerOffVMs.IsPresent)) { Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Maintenance" -vsanDataMigrationMode $vsanDataMigrationMode -timeout $timeout } elseif (($vsanDataMigrationMode -eq "EnsureAccessibility") -and ($migratePowerOffVMs.IsPresent)) { Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Maintenance" -vsanDataMigrationMode $vsanDataMigrationMode -migratePowerOffVMs -timeout $timeout } else { Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Maintenance" -vsanDataMigrationMode "Full" -migratePowerOffVMs -timeout $timeout } } else { Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Maintenance" -timeout $timeout } Write-Output "Starting certificate replacement for ESX host $esxiFqdn." $esxCertificatePem = Get-Content $crtPath -Raw Set-VIMachineCertificate -PemCertificate $esxCertificatePem -VMHost $esxiFqdn -ErrorAction Stop -Confirm:$false $replacedHosts.Add($esxiFqdn) # Disconnect ESX host from vCenter prior to restarting an ESX host. Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Disconnected" -timeout $timeout Restart-ESXiHost -esxiFqdn $esxiFqdn -user $($esxiCredential.username) -pass $($esxiCredential.password) # Connect to vCenter, set the ESX host connection state, and exit maintenance mode. Write-Output "Connecting to vCenter instance $($vCenterServer.details.fqdn) and exiting ESX host $esxiFqdn from maintenance mode." $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain if ($vCenterServer) { Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Connected" -timeout $timeout Start-Sleep -Seconds 30 Set-EsxiConnectionState -esxiFqdn $esxiFqdn -state "Connected" } else { Write-Error "Could not connect to vCenter instance $($vCenterServer.details.fqdn). Check the state of ESX host $esxiFqdn using the Get-EsxiConnectionState cmdlet." -ErrorAction Stop break } } else { Write-Error "Unable to get credentials for ESX host $esxiFqdn from SDDC Manager." $skippedHosts.Add($esxiFqdn) } } } Write-Output "--------------------------------------------------------------------------------" Write-Output "ESX Host Certificate Replacement Summary:" Write-Output "--------------------------------------------------------------------------------" Write-Output "Succesfully completed certificate replacement for $($replacedHosts.Count) ESX hosts:" foreach ($replacedHost in $replacedHosts) { Write-Output "$replacedHost" } Write-Warning "Skipped certificate replacement for $($skippedHosts.Count) ESX hosts:" foreach ($skippedHost in $skippedHosts) { Write-Warning "$skippedHost : SKIPPED" } Write-Output "--------------------------------------------------------------------------------" } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Set-VcfCertificateAuthority { <# .SYNOPSIS Sets the certificate authority in SDDC Manager to use a Microsoft Certificate Authority or an OpenSSL Certificate Authority. .DESCRIPTION The Set-VcfCertificateAuthority will configure Microsoft Certificate Authority or OpenSSL Certificate Authority as SDDC Manager's Certificate Authority. .EXAMPLE Set-VcfCertificateAuthority -certAuthority Microsoft -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -certAuthorityFqdn [certificate_authority_fqdn] -certAuthorityUser [certificate_authority_username] -certAuthorityPass [certificate_authority_password] -certAuthorityTemplate [certificate_authority_template_name] This example will configure Microsoft Certificate Authority in SDDC Manager. Set-VcfCertificateAuthority -certAuthority OpenSSL -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -commonName []common_name] -organization [organization] -organizationUnit [organization_unit] -locality [locality] -state [state] -country [country] This example will configure an OpenSSL Certificate Authority in SDDC Manager. .PARAMETER certAuthority The type of Certificate Authority to be configured Microsoft or OpenSSL .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER certAuthorityFqdn The fully qualified domain name of the Microsoft Certificate Authority. .PARAMETER certAuthorityUser The username to authenticate to the Microsoft Certificate Authority. .PARAMETER certAuthorityPass The password to authenticate to the Microsoft Certificate Authority. .PARAMETER certAuthorityTemplate The Certificate Template Name to be used with the Microsoft Certificate Authority. .PARAMETER commonName Specifies the common name for the OpenSSL Certificate Authority. .PARAMETER organization Specifies the organization name for the OpenSSL Certificate Authority. .PARAMETER organizationUnit Specifies the organization unit for the OpenSSL Certificate Authority. .PARAMETER locality Specifies the locality for the OpenSSL Certificate Authority. .PARAMETER state Specifies the state for the OpenSSL Certificate Authority. .PARAMETER country Specifies the country for the OpenSSL Certificate Authority. #> Param ( [Parameter (Mandatory = $true)] [ValidateSet ("Microsoft", "OpenSSL")] [String] $certAuthority, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true, ParameterSetName = "microsoft")] [ValidateNotNullOrEmpty()] [String] $certAuthorityFqdn, [Parameter (Mandatory = $true, ParameterSetName = "microsoft")] [ValidateNotNullOrEmpty()] [String] $certAuthorityUser, [Parameter (Mandatory = $true, ParameterSetName = "microsoft")] [ValidateNotNullOrEmpty()] [String] $certAuthorityPass, [Parameter (Mandatory = $true, ParameterSetName = "microsoft")] [ValidateNotNullOrEmpty()] [String] $certAuthorityTemplate, [Parameter (Mandatory = $true, ParameterSetName = "openssl")] [ValidateNotNullOrEmpty()] [String] $commonName, [Parameter (Mandatory = $true, ParameterSetName = "openssl")] [ValidateNotNullOrEmpty()] [String] $organization, [Parameter (Mandatory = $true, ParameterSetName = "openssl")] [ValidateNotNullOrEmpty()] [String] $organizationUnit, [Parameter (Mandatory = $true, ParameterSetName = "openssl")] [ValidateNotNullOrEmpty()] [String] $locality, [Parameter (Mandatory = $true, ParameterSetName = "openssl")] [ValidateNotNullOrEmpty()] [String] $state, [Parameter (Mandatory = $true, ParameterSetName = "openssl")] [ValidateSet ("US", "CA", "AX", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", ` "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BZ", "CA", "CC", "CF", "CH", "CI", "CK", ` "CL", "CM", "CN", "CO", "CR", "CS", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", ` "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", ` "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KR", "KW", "KY", "KZ", "LA", ` "LC", "LI", "LK", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", ` "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NT", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", ` "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SR", "ST", ` "SU", "SV", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", ` "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "COM", "EDU", "GOV", "INT", "MIL", "NET", "ORG", "ARPA")] [String] $country ) $pass = Get-Password -User $user -Password $pass if (Test-VCFConnection -server $server) { if (Test-VCFAuthentication -server $server -user $user -pass $pass) { if ($certAuthority -eq "OpenSSL") { if (Test-EndpointConnection -server $commonName -port 443) { Try { Write-Output "Starting configuration of the OpenSSL Certificate Authority in SDDC Manager..." Write-Output "Checking status of the OpenSSL Certificate Authority configuration..." if ((Get-VCFCertificateAuthority).id -eq "OpenSSL") { $vcfCommonName = (Get-VCFCertificateAuthority -caType OpenSSL).commonName Write-Output "OpenSSL Certificate Authority is currently configured on SDDC Manager using $($vcfCommonName)." } else { Write-Output "OpenSSL Certificate Authority is currently not configured on SDDC Manager." } if ($vcfCommonName -ne $commonName) { Write-Output "Configuring the OpenSSL Certificate Authority in SDDC Manager using $($commonName)..." Set-VCFOpensslCa -commonName $commonName -organization $organization -organizationUnit $organizationUnit -locality $locality -state $state -country $country Write-Output "Configuration of the OpenSSL Certificate Authority in SDDC Manager using $($commonName): SUCCESSFUL." } else { Write-Warning "Configuration of the OpenSSL Certificate Authority in SDDC Manager using $($commonName), already exists: SKIPPED." } Write-Output "Configuration the OpenSSL Certificate Authority in SDDC Manager completed." } Catch { $ErrorMessage = $_.Exception.Message Write-Output "Error was: $ErrorMessage." } } else { Write-Error "Unable to connect to Openssl Certificate Authority ($commonName)." } } else { if (Test-EndpointConnection -server $certAuthorityFqdn -port 443) { $caServerUrl = "https://$certAuthorityFqdn/certsrv" Try { Write-Output "Starting configuration of the Microsoft Certificate Authority in SDDC Manager..." Write-Output "Checking status of the Microsoft Certificate Authority configuration..." $vcfCertCa = Get-VCFCertificateAuthority if ($vcfCertCa.username -ne "$certAuthorityUser") { Write-Output "Configuring the Microsoft Certificate Authority in SDDC Manager using $($certAuthorityUser)..." Set-VCFMicrosoftCA -serverUrl $caServerUrl -username $certAuthorityUser -password $certAuthorityPass -templateName $certAuthorityTemplate | Out-Null Write-Output "Configuration of the Microsoft Certificate Authority in SDDC Manager using ($($certAuthorityUser)): SUCCESSFUL." } else { Write-Warning "Configuration of the Microsoft Certificate Authority in SDDC Manager using ($($certAuthorityUser)), already exists: SKIPPED." } Write-Output "Configuration a Microsoft Certificate Authority in SDDC Manager completed." } Catch { $ErrorMessage = $_.Exception.Message Write-Output "Error was: $ErrorMessage." } } else { Write-Error "Unable to connect to Microsoft Certificate Authority ($certAuthorityFqdn)." } } } else { Write-Error "Unable to authenticate to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } else { Write-Error "Unable to connect to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } Function gatherSddcInventory { Param ( [Parameter (Mandatory = $true)] $domainType, [Parameter (Mandatory = $true)] $workloadDomain ) # Gathers deployment details from SDDC Manager. $sddcMgr = Get-VCFManager $sddcMgrVersion = $sddcMgr.version.split(".")[0] $resourcesObject = @() # SDDC Manager if ($domainType -eq "Management") { $resourcesObject += [pscustomobject]@{ 'fqdn' = $sddcMgr.fqdn 'name' = $sddcMgr.fqdn.split(".")[0] 'resourceId' = $sddcMgr.id 'type' = "SDDC_MANAGER" } } # Aria Suite Lifecycle if ($domainType -eq "Management") { $vrslcmNode = Get-VCFvRSLCM if ($vrslcmNode.id -ne "") { $resourcesObject += [pscustomobject]@{ 'fqdn' = $vrslcmNode.fqdn 'name' = $vrslcmNode.fqdn.split(".")[0] 'resourceId' = $vrslcmNode.id 'type' = "VRSLCM" } } } # vCenter if (([float]$sddcMgrVersion -ge 4) -AND ($domainType -eq "Management")) { $domain = Get-VCFWorkloadDomain | Where-Object { $_.type -eq "MANAGEMENT" } $vCenterServer = Get-VCFvCenter | Where-Object { $_.domain.id -eq $domain.id } } else { $domain = Get-VCFWorkloadDomain | Where-Object { $_.name -eq $workloadDomain } $vCenterServer = Get-VCFvCenter | Where-Object { $_.domain.id -eq $domain.id } } foreach ($vCenter in $vCenterServer) { $resourcesObject += [pscustomobject]@{ 'fqdn' = $vCenter.fqdn 'name' = $vCenter.fqdn.split(".")[0] 'resourceId' = $vCenter.id 'type' = "VCENTER" } } # NSX if ([float]$sddcMgrVersion -ge 4) { $nsxtManager = Get-VCFNsxtCluster | Where-Object { $_.domains.id -eq $domain.id } $nsxtSans = @() foreach ($nodeFqdn in $nsxtManager.nodes.fqdn) { $nsxtSans += $nodeFqdn } $nsxtSans += $nsxtManager.vipFqdn $nsxtvip = $nsxtManager.vipfqdn foreach ($nsxManager in $nsxtManager) { $resourcesObject += [pscustomobject]@{ 'fqdn' = $nsxtvip 'name' = $nsxtvip.split(".")[0] 'resourceId' = $nsxManager.id 'sans' = $nsxtSans 'type' = "NSXT_MANAGER" } } foreach ($nsxNode in $nsxtManager.nodes) { $resourcesObject += [pscustomobject]@{ 'fqdn' = $nsxNode.fqdn 'name' = $nsxNode.name 'resourceId' = $nsxNode.id 'type' = "NSXT_MANAGER" } } } Return $resourcesObject } Function Request-VcfCsr { <# .SYNOPSIS Requests SDDC Manager to generate and store certificate signing request (CSR) files or requests a certificate signing request for either an ESX host or a for each ESX host in a cluster and saves it to file(s) in a directory. .DESCRIPTION The Request-VcfCsr will request SDDC Manager to generate certificate signing request files for all components associated with the given domain when used with -sddcManager switch. The Request-VcfCsr cmdlet will generate the certificate signing request for ESX host(s) and saves it to file(s) in an output directory when used with the -esxi switch. The cmdlet connects to the SDDC Manager using the -server, -user, and -password values. - Validates that network connectivity and authentication is possible to SDDC Manager. - Validates that the workload domain exists in the SDDC Manager inventory. - Validates that network connectivity and authentication is possible to vCenter. When used with -esxi switch, this cmdlet - Gathers the ESX hosts from the cluster - Requests the ESX host CSR and saves it in the output directory as <esxi-host-fqdn>.csr. e.g. sfo01-m01-esx01.sfo.rainpole.io.csr - Defines possible country codes. Reference: https://www.digicert.com/kb/ssl-certificate-country-codes.htm .EXAMPLE Request-VcfCsr -esxi -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -country [country] -locality [locality] -organization [organization] -organizationUnit [organization_unit] -stateOrProvince [state_or_province] -outputDirectory [output_path] This example generates CSRs and stores them in the provided output directory for all ESX hosts in the cluster with the specified fields. .EXAMPLE Request-VcfCsr -sddcManager -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -country [country] -keysize [keysize] -locality [locality] -organization [organization] -organizationUnit [organization_unit] -stateOrProvince [state_or_province] -email [email_address] This example will request SDDC Manager to generate certificate signing request files for all components associated with the given workload domain. .PARAMETER esxi Switch to request and save certificate signing request files for ESX hosts. .PARAMETER sddcManager Switch to request and store certificate signing request files on SDDC Manager. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the cluster is located. .PARAMETER cluster The name of the cluster in which the ESX host is located. (Only required when using -esxi parameter) .PARAMETER esxiFqdn The fully qualified domain name of the ESX host to request certificate signing request (CSR) for. (Only required when using -esxi parameter) .PARAMETER country The country code for the certificate signing request (CSR). .PARAMETER locality The locality for the certificate signing request (CSR). .PARAMETER keySize The key size for the certificate signing request (CSR). (Only required when using -sddcManager parameter) .PARAMETER organization The organization for the certificate signing request (CSR). .PARAMETER organizationUnit The organization unit for the certificate signing request (CSR). .PARAMETER stateOrProvince The state or province for the certificate signing request (CSR). .PARAMETER outputDirectory The directory to save the certificate signing request (CSR) files. (Only required when using -esxi parameter) .PARAMETER email The contact email for the certificate signing request (CSR). (Only required when using -sddcManager parameter) #> Param ( [Parameter (Mandatory = $true, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [Switch] $esxi, [Parameter (Mandatory = $true, ParameterSetName = "sddc")] [ValidateNotNullOrEmpty()] [Switch] $sddcManager, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $false, ParameterSetName = "esxi")][ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [String] $outputDirectory, [Parameter (Mandatory = $true, ParameterSetName = "sddc")] [ValidateSet ("2048", "3072", "4096")] [String] $keySize, [Parameter (Mandatory = $true)] [ValidateSet ("US", "CA", "AX", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", ` "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BZ", "CA", "CC", "CF", "CH", "CI", "CK", ` "CL", "CM", "CN", "CO", "CR", "CS", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", ` "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", ` "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KR", "KW", "KY", "KZ", "LA", ` "LC", "LI", "LK", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", ` "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NT", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", ` "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SR", "ST", ` "SU", "SV", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", ` "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "COM", "EDU", "GOV", "INT", "MIL", "NET", "ORG", "ARPA")] [String] $country, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $locality, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $organization, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $organizationUnit, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $stateOrProvince, [Parameter (Mandatory = $true, ParameterSetName = "sddc")] [ValidateNotNullOrEmpty()] [String] $email ) $pass = Get-Password -User $user -Password $pass if ($PSBoundParameters.ContainsKey("esxi")) { if (!$PSBoundParameters.ContainsKey("cluster") -and !$PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Please provide either -cluster or -esxiFqdn paramater." } elseif ($PSBoundParameters.ContainsKey("cluster") -and $PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Only one of -esxiFqdn or -cluster parameter can be provided at a time." } elseif ($PSBoundParameters.ContainsKey("cluster")) { Request-EsxiCsr -server $server -user $user -pass $pass -domain $domain -cluster $cluster -country $country -locality $locality -organization $organization -organizationUnit $organizationUnit -stateOrProvince $stateOrProvince -outputDirectory $outputDirectory } else { Request-EsxiCsr -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -country $country -locality $locality -organization $organization -organizationUnit $organizationUnit -stateOrProvince $stateOrProvince -outputDirectory $outputDirectory } } else { Request-SddcCsr -server $server -user $user -pass $pass -keysize $keySize -workloadDomain $domain -country $country -locality $locality -organization $organization -organizationUnit $organizationUnit -stateOrProvince $stateOrProvince -email $email } } Function Request-EsxiCsr { <# .SYNOPSIS Requests a certificate signing request (CSR) for an ESX host or a for each ESX host in a cluster and saves it to file(s) in a directory. .DESCRIPTION The Request-EsxiCsr cmdlet will generate the certificate signing request for ESX host(s) and saves it to file(s) in an output directory. The cmdlet connects to the SDDC Manager using the -server, -user, and -password values. - Validates that network connectivity and authentication is possible to SDDC Manager. - Validates that the workload domain exists in the SDDC Manager inventory. - Validates that network connectivity and authentication is possible to vCenter. - Gathers the ESX hosts from the cluster. - Requests the ESX host CSR and saves it in the output directory as <esxi-host-fqdn>.csr. e.g. sfo01-m01-esx01.sfo.rainpole.io.csr - Defines possible country codes. Reference: https://www.digicert.com/kb/ssl-certificate-country-codes.htm .EXAMPLE Request-EsxiCsr -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -country [country] -locality [locality] -organization [organization] -organizationUnit [organization_unit] -stateOrProvince [state_or_province] -outputDirectory [output_path] This example generates CSRs and stores them in the provided output directory for all ESX hosts in the cluster with the specified fields. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the workload domain in which the cluster is located. .PARAMETER cluster The name of the cluster in which the ESX host is located. .PARAMETER esxiFqdn The fully qualified domain name of the ESX host to request certificate signing request (CSR) for. .PARAMETER country The country code for the certificate signing request (CSR). .PARAMETER locality The locality for the certificate signing request (CSR). .PARAMETER organization The organization for the certificate signing request (CSR). .PARAMETER organizationUnit The organization unit for the certificate signing request (CSR). .PARAMETER stateOrProvince The state or province for the certificate signing request (CSR). .PARAMETER outputDirectory The directory to save the certificate signing request (CSR) files. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $true, ParameterSetName = "cluster")] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $true, ParameterSetName = "host")] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $outputDirectory, [Parameter (Mandatory = $true)] [ValidateSet ("US", "CA", "AX", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", ` "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BZ", "CA", "CC", "CF", "CH", "CI", "CK", ` "CL", "CM", "CN", "CO", "CR", "CS", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", ` "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", ` "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KR", "KW", "KY", "KZ", "LA", ` "LC", "LI", "LK", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", ` "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NT", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", ` "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SR", "ST", ` "SU", "SV", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", ` "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "COM", "EDU", "GOV", "INT", "MIL", "NET", "ORG", "ARPA")] [String] $country, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $locality, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $organization, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $organizationUnit, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $stateOrProvince ) Try { if (!(Test-Path $outputDirectory)) { Write-Error "Please specify a valid directory to save the CSR files." -ErrorAction Stop return } $vCenterServer = Get-vCenterServer -server $server -user $user -pass $pass -domain $domain if ($PsBoundParameters.ContainsKey("cluster")) { if (Get-Cluster | Where-Object { $_.Name -eq $cluster }) { $esxiHosts = Get-Cluster $cluster | Get-VMHost | Sort-Object -Property Name if (!$esxiHosts) { Write-Warning "No ESX hosts found within $cluster cluster." } } else { Write-Error "Unable to locate cluster $cluster in vCenter instance $($vCenterServer.details.fqdn): PRE_VALIDATION_FAILED" Throw "Unable to locate cluster $cluster in vCenter $($vCenterServer.details.fqdn): PRE_VALIDATION_FAILED" } } else { $esxiHosts = Get-VMHost -Name $esxiFqdn if (!$esxiHosts) { Write-Warning "No ESX host $esxiFqdn found within workload domain $domain." } } if ($esxiHosts) { foreach ($esxiHost in $esxiHosts) { $csrPath = Join-Path -Path $outputDirectory -childPath "$($esxiHost.Name).csr" $esxRequest = New-VIMachineCertificateSigningRequest -Server $vCenterServer.details.fqdn -VMHost $esxiHost.Name -Country "$country" -Locality "$locality" -Organization "$organization" -OrganizationUnit "$organizationUnit" -StateOrProvince "$stateOrProvince" -CommonName $esxiHost.Name $esxRequest.CertificateRequestPEM | Out-File $csrPath -Force if (Test-Path $csrPath -PathType Leaf ) { Write-Output "CSR for $($esxiHost.Name) has been generated and saved to $csrPath." } else { Write-Error "Unable to generate CSR for $($esxiHost.name)." Throw "Unable to generate CSR for $($esxiHost.name)." } } } } Catch { Debug-ExceptionWriter -object $_ } Finally { if ($vCenterServer) { Disconnect-VIServer -server $vCenterServer.details.fqdn -Confirm:$false -WarningAction SilentlyContinue } } } Function Request-SddcCsr { <# .SYNOPSIS Requests SDDC Manager to generate and store certificate signing request files. .DESCRIPTION The Request-SddcCsr will request SDDC Manager to generate certificate signing request files for all components associated with the given workload domain. The cmdlet connects to the SDDC Manager using the -server, -user, and -password values. - Validates that network connectivity and authentication is possible to SDDC Manager. - Validates that the workload domain exists in the SDDC Manager inventory. - Defines possible country codes. Reference: https://www.digicert.com/kb/ssl-certificate-country-codes.htm .EXAMPLE Request-SddcCsr -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -workloadDomain [workload_domain_name] -country [country] -keysize [keysize] -locality [locality] -organization [organization] -organizationUnit [organization_unit] -stateOrProvince [state_or_province] -email [email_address] This example will request SDDC Manager to generate certificate signing request files for all components associated with the given workload domain. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER workloadDomain The name of the workload domain in which the certificate is requested to be generated. .PARAMETER country The country code for the certificate signing request (CSR). .PARAMETER keySize The key size for the certificate signing request (CSR). .PARAMETER locality The locality for the certificate signing request (CSR). .PARAMETER organization The organization for the certificate signing request (CSR). .PARAMETER organizationUnit The organization unit for the certificate signing request (CSR). .PARAMETER stateOrProvince The state or province for the certificate signing request (CSR). .PARAMETER email The contact email for the certificate signing request (CSR). #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $workloadDomain, [Parameter (Mandatory = $true)] [ValidateSet ("US", "CA", "AX", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", ` "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BZ", "CA", "CC", "CF", "CH", "CI", "CK", ` "CL", "CM", "CN", "CO", "CR", "CS", "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", ` "FM", "FO", "FR", "FX", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", ` "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KR", "KW", "KY", "KZ", "LA", ` "LC", "LI", "LK", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", ` "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NT", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", ` "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SR", "ST", ` "SU", "SV", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TP", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", ` "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "ZA", "ZM", "COM", "EDU", "GOV", "INT", "MIL", "NET", "ORG", "ARPA")] [String] $country, [Parameter (Mandatory = $true)] [ValidateSet ("2048", "3072", "4096")] [String] $keySize, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $locality, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $organization, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $organizationUnit, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $stateOrProvince, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $email ) if (Test-VCFConnection -server $server) { if (Test-VCFAuthentication -server $server -user $user -pass $pass) { $domainType = Get-VCFWorkloadDomain -name $workloadDomain $resourcesObject = gatherSddcInventory -domainType $domainType.type -workloadDomain $workloadDomain # Create a temporary directory under current directory for ($createPathCounter = 0; $createPathCounter -lt 4; $createPathCounter++) { $randomOutput = -join (((48..57) + (65..90) + (97..122)) * 80 | Get-Random -Count 6 | % { [char]$_ }) $tempPath = Join-Path -Path $pwd -childPath $randomOutput if (!(Test-Path -Path $tempPath)) { Break } else { if ($createPathCounter -eq 3) { Write-Error "Unable to write to ($tempPath): PRE_VALIDATION_FAILED.." Exit } } } New-Item -Path $tempPath -ItemType Directory | Out-NULL $tempPath = Join-Path $tempPath "" # Generate a temporay JSON configuration file $csrGenerationSpecJson = '{ "csrGenerationSpec": { "country": "'+ $country + '", "email": "'+ $email + '", "keyAlgorithm": "'+ "RSA" + '", "keySize": "'+ $keySize + '", "locality": "'+ $locality + '", "organization": "'+ $organization + '", "organizationUnit": "'+ $organizationUnit + '", "state": "'+ $stateOrProvince + '" }, ' $resourcesBodyObject += [pscustomobject]@{ resources = $resourcesObject } $resourcesBodyObject | ConvertTo-Json -Depth 10 | Out-File -FilePath $tempPath"temp.json" Get-Content $tempPath"temp.json" | Select-Object -Skip 1 | Set-Content $tempPath"temp1.json" $resouresJson = Get-Content $tempPath"temp1.json" -Raw $requestCsrSpecJson = $csrGenerationSpecJson + $resouresJson $requestCsrSpecJson | Out-File $tempPath"$($workloadDomain)-requestCsrSpec.json" Write-Output "Requesting certificate signing requests for components associated with workload domain ($($workloadDomain))..." $myTask = Request-VCFCertificateCSR -domainName $($workloadDomain) -json $tempPath"$($workloadDomain)-requestCsrSpec.json" Do { Write-Output "Checking status for the generation of certificate signing requests for components associated with workload domain ($($workloadDomain))..." Start-Sleep 6 $response = Get-VCFTask $myTask.id } While ($response.status -eq "IN_PROGRESS") if ($response.status -eq "FAILED") { Write-Output "Workflow completed with status: $($response.status)." } elseif ($response.status -eq "SUCCESSFUL") { Write-Output "Workflow completed with status: $($response.status)." } else { Write-Warning "Workflow completed with an unrecognized status: $($response.status). Please check before proceeding." } Write-Output "Generate certificate signing requests for components associated with workload domain $($workloadDomain)." # Remove the temporary directory. Remove-Item -Recurse -Force $tempPath | Out-NULL } else { Write-Error "Unable to authenticate to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } else { Write-Error "Unable to connect to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } Function Request-VcfSignedCertificate { <# .SYNOPSIS Requests SDDC Manager to connect to certificate authority to sign the certificate signing request files and to store the signed certificates. .DESCRIPTION The Request-VcfSignedCertificate will request SDDC Manager to connect to the certificate authority to sign the generated certificate signing request files for all components associated with the given workload domain .EXAMPLE Request-VcfSignedCertificate -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -workloadDomain [workload_domain_name] -certAuthority Microsoft This example will connect to SDDC Manager to request to have the certificate signing request files for a given workload domain to be signed by Microsoft CA. .EXAMPLE Request-VcfSignedCertificate -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -workloadDomain [workload_domain_name] -certAuthority OpenSSL This example will connect to SDDC Manager to request to have the certificate signing request files for a given workload domain to be signed by OpenSSL CA. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER workloadDomain The name of the workload domain in which the certificate is requested to be signed. .PARAMETER certAuthority The type of Certificate Authority to be used for signing certificates. One of: Microsoft, OpenSSL. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $workloadDomain, [Parameter (Mandatory = $true)] [ValidateSet ("Microsoft", "OpenSSL")] [String] $certAuthority ) $pass = Get-Password -User $user -Password $pass if (Test-VCFConnection -server $server) { if (Test-VCFAuthentication -server $server -user $user -pass $pass) { $domainType = Get-VCFWorkloadDomain -name $workloadDomain $resourcesObject = gatherSddcInventory -domainType $domainType.type -workloadDomain $workloadDomain # Create a temporary directory under current directory for ($createPathCounter = 0; $createPathCounter -lt 4; $createPathCounter++) { $randomOutput = -join (((48..57) + (65..90) + (97..122)) * 80 | Get-Random -Count 6 | % { [char]$_ }) $tempPath = Join-Path -Path $pwd -childPath $randomOutput if (!(Test-Path -Path $tempPath)) { Break } else { if ($createPathCounter -eq 3) { Write-Error "Unable to write to $tempPath." Exit } } } New-Item -Path $tempPath -ItemType Directory | Out-NULL $tempPath = Join-Path $tempPath "" # Generate a temporay JSON configuration file $requestCertificateSpec = [pscustomobject]@{ caType = $certAuthority resources = $resourcesObject } $requestCertificateSpec | ConvertTo-Json -Depth 10 | Out-File $tempPath"$($workloadDomain)-requestCertificateSpec.json" Write-Output "Requesting certificates for components associated with workload domain $($workloadDomain)." $myTask = Request-VCFCertificate -domainName $($workloadDomain) -json $tempPath"$($workloadDomain)-requestCertificateSpec.json" Do { Write-Output "Checking status for the generation of signed certificates for components associated with workload domain ($($workloadDomain))..." Start-Sleep 6 $response = Get-VCFTask $myTask.id } While ($response.status -eq "IN_PROGRESS") if ($response.status -eq "FAILED") { Write-Error "Workflow completed with status: $($response.status)." } elseif ($response.status -eq "SUCCESSFUL") { Write-Output "Workflow completed with status: $($response.status)." } else { Write-Warning "Workflow completed with an unrecognized status: $($response.status). Please check the state before proceeding." } Write-Output "Request signed certficates for the components associated with workload domain $($workloadDomain) completed with status: $($response.status)." # Remove the temporary directory. Remove-Item -Recurse -Force $tempPath | Out-NULL } else { Write-Error "Unable to authenticate to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } else { Write-Error "Unable to connect to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } Function Install-VcfCertificate { <# .SYNOPSIS Installs the signed certificates for all components associated with the given workload domain, or an ESX Host or for each ESX host in a given cluster. .DESCRIPTION The Install-VcfCertificate will install the signed certificates for all components associated with the given workload domain when used with the -sddcManager switch. The Install-VcfCertificate cmdlet will replace the certificate for an ESX host or for each ESX host in a cluster when used with the -esxi switch. When used with the -esxi switch: - You must provide the directory containing the signed certificate files. - Certificate names should be in format <esx_host_fqdn>.crt. - The workflow will put the ESX host in maintenance mode with full data migration, disconnect the ESX host from the vCenter, replace the certificate, restart the ESX host, and the exit maintenance mode once the ESX host is online. .EXAMPLE Install-VcfCertificate -sddcManager -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] This example will connect to SDDC Manager to install the signed certificates for a given workload domain. .EXAMPLE Install-VcfCertificate -esxi -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -esxiFqdn [esx_host_fqdn] -migratePowerOffVMs -vsanDataMigrationMode EnsureAccessibility -certificateDirectory [certificate_directory_path] -certificateFileExt ".cer" This example will install the certificate to the ESX host in the workload domain using the provided path. For VMware Cloud Foundation version 5.1 and earlier, the ESX hosts will enter maintenance mode with vSAN data migration Mode set to 'EnsureAccessibility'. Any powered off virtual machines will be migrated off the ESX hosts prior to entering maintenance mode. .EXAMPLE Install-VcfCertificate -esxi -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -certificateDirectory [certificate_directory_path] -certificateFileExt ".cer" This example will install certificates for each ESX host in the cluster within the workload domain, using the provided path. For VMware Cloud Foundation 5.2 or later, the vsanDataMigrationMode option is no longer applicable. For VMware Cloud Foundation 5.1 and earlier, by default the ESX hosts will enter maintenance mode with vSAN data migration Mode set to 'Full data migration'. Any powered off virtual machines will not be migrated off the ESX hosts prior to entering maintenance mode. .EXAMPLE Install-VcfCertificate -esxi -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -domain [workload_domain_name] -cluster [cluster_name] -certificateDirectory [certificate_directory_path] -certificateFileExt ".cer" -uploadPrivateKey This example will install private keys and certificates for each ESX host in the cluster within the workload domain, using the provided path. The 'uploadprivatekey' parameter is only validated for VMware Cloud Foundation version is 5.2 or later. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER domain The name of the domain in which the certificate is requested to be installed or in which the ESX hosts are located. .PARAMETER cluster The name of the cluster in which the ESX host is located. (Only required when -esxi switch is used) .PARAMETER esxiFqdn The fully qualified domain name of the ESX host. (Only required when -esxi switch is used) .PARAMETER certificateDirectory The directory containing the signed certificate files. (Only required when -esxi switch is used) .PARAMETER certificateFileExt The file extension of the certificate files. One of ".crt", ".cer", ".pem", ".p7b", or ".p7c". (Only required when -esxi switch is used) .PARAMETER timeout The timeout in seconds for putting the ESX host in maintenance mode. Default is 18000 seconds (5 hours). (Only required when -esxi switch is used) .PARAMETER esxi Switch to indicate that the certificate is to be installed on an ESX host. .PARAMETER sddcManager Switch to indicate that the certificate is to be installed for all components associated with the given workload domain, excluding ESX hosts. .PARAMETER migratePowerOffVMs Option to decide if power off virtual machines and suspended virtual machines will be migrated to other ESX hosts when the ESX host goes into maintenance mode. .PARAMETER uploadPrivateKey Option to upload of a custom Private Key for the ESX host. .PARAMETER vsanDataMigrationMode The vSAN data migration mode to use when setting the ESX host to Maintenance. One of "Full" or "EnsureAccessibility". .PARAMETER NoConfirmation The cmdlet will not ask for confirmation. #> Param ( [Parameter (Mandatory = $true, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [Switch] $esxi, [Parameter (Mandatory = $true, ParameterSetName = "sddc")] [ValidateNotNullOrEmpty()] [Switch] $sddcManager, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $domain, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [String] $cluster, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [String] $esxiFqdn, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [Switch] $migratePowerOffVMs, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [Switch] $uploadPrivateKey, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [ValidateSet ("Full", "EnsureAccessibility")] [String] $vsanDataMigrationMode, [Parameter (Mandatory = $true, ParameterSetName = "esxi") ] [ValidateNotNullOrEmpty()] [String] $certificateDirectory, [Parameter (Mandatory = $true, ParameterSetName = "esxi")] [ValidateSet(".crt", ".cer", ".pem", ".p7b", ".p7c")] [String] $certificateFileExt, [Parameter (Mandatory = $false)] [Switch] $NoConfirmation, [Parameter (Mandatory = $false, ParameterSetName = "esxi")] [ValidateNotNullOrEmpty()] [String] $timeout = 18000 ) $pass = Get-Password -User $user -Password $pass if ($PSBoundParameters.ContainsKey("esxi")) { # VCF version checks if (Test-VCFConnection -server $server) { if (Test-VCFAuthentication -server $server -user $user -pass $pass) { } else { Throw "Unable to return vCenter details: PRE_VALIDATION_FAILED" } } else { Throw "Unable to obtain access token from SDDC Manager ($server), check credentials: PRE_VALIDATION_FAILED" } $version = Get-VCFManager -version $vcfVersion = $version.Split('.')[0] + "." + $version.Split('.')[1] if ($vcfVersion -ge "5.2") { # VCF version >= 5.2 if (!$PSBoundParameters.ContainsKey("cluster") -and !$PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Please provide either -cluster or -esxiFqdn paramater." } elseif ($PSBoundParameters.ContainsKey("cluster") -and $PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Only one of -esxiFqdn or -cluster parameter can be provided at a time." } elseif ($PSBoundParameters.ContainsKey("cluster")) { if ($PSBoundParameters.ContainsKey("uploadPrivateKey")) { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -uploadPrivateKey } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt } } else { if ($PSBoundParameters.ContainsKey("uploadPrivateKey")) { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -uploadPrivateKey } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt } } } else { # VCF version < 5.2 if ($PSBoundParameters.ContainsKey("uploadPrivateKey")) { Write-Error "upload Private key is only supported for VCF version 5.2 and later. Please remove this parameter and try again." -ErrorAction Stop } # Warning Message on using EnsureAccessibility instead of Full Migration if (!($PSBoundParameters.ContainsKey("NoConfirmation")) -and ($vsanDataMigrationMode -eq "EnsureAccessibility")) { $warningMessage = "Please ensure sufficient backups of the cluster exists. Please ensure the ESX`n" $warningMessage += " hosts activities are minimumized during certificate replacement process. `n" $warningMessage += "Please enter yes to confirm: " $proceed = Read-Host $warningMessage if (($proceed -match "no") -or ($proceed -match "yes")) { if ($proceed -match "no") { return "Stopping script execution. (confirmation is $proceed)." } } else { return "None of the options is selected. Default is 'No', hence stopping script execution." } } if (!$PSBoundParameters.ContainsKey("cluster") -and !$PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Please provide either -cluster or -esxiFqdn paramater." } elseif ($PSBoundParameters.ContainsKey("cluster") -and $PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Only one of -esxiFqdn or -cluster parameter can be provided at a time." } elseif ($PSBoundParameters.ContainsKey("cluster")) { if ($vsanDataMigrationMode.IsPresent) { if ($migratePowerOffVMs.IsPresent) { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode -migratePowerOffVMs } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode } } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode Full -migratePowerOffVMs } } else { if ($vsanDataMigrationMode.IsPresent) { if ($migratePowerOffVMs.IsPresent) { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode -migratePowerOffVMs } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode } } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode Full -migratePowerOffVMs } if (!$PSBoundParameters.ContainsKey("cluster") -and !$PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Please provide either -cluster or -esxiFqdn paramater." } elseif ($PSBoundParameters.ContainsKey("cluster") -and $PSBoundParameters.ContainsKey("esxiFqdn")) { Write-Error "Only one of -esxiFqdn or -cluster parameter can be provided at a time." } elseif ($PSBoundParameters.ContainsKey("cluster")) { if ($vsanDataMigrationMode.IsPresent) { if ($migratePowerOffVMs.IsPresent) { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode -migratePowerOffVMs } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode } } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -cluster $cluster -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode Full -migratePowerOffVMs } } else { if ($vsanDataMigrationMode.IsPresent) { if ($migratePowerOffVMs.IsPresent) { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode -migratePowerOffVMs } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode $vsanDataMigrationMode } } else { Install-EsxiCertificate -server $server -user $user -pass $pass -domain $domain -esxiFqdn $esxiFqdn -certificateDirectory $certificateDirectory -certificateFileExt $certificateFileExt -vsanDataMigrationMode Full -migratePowerOffVMs } } } } } else { Install-SddcCertificate -server $server -user $user -pass $pass -workloadDomain $domain } } Function Install-SddcCertificate { <# .SYNOPSIS Installs the signed certificates for all components associated with the given workload domain. .DESCRIPTION The Install-SddcCertificate will install the signed certificates for all components associated with the given workload domain. .EXAMPLE Install-SddcCertificate -server [sddc_manager_fqdn] -user [admin_username] -pass [admin_password] -workloadDomain [workload_domain_name] This example will connect to SDDC Manager to install the signed certificates for a given workload domain. .PARAMETER server The fully qualified domain name of the SDDC Manager instance. .PARAMETER user The username to authenticate to the SDDC Manager instance. .PARAMETER pass The password to authenticate to the SDDC Manager instance. .PARAMETER workloadDomain The name of the workload domain in which the certificate is requested to be installed. #> Param ( [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $user, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $pass, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $workloadDomain ) if (Test-VCFConnection -server $server) { if (Test-VCFAuthentication -server $server -user $user -pass $pass) { $domainType = Get-VCFWorkloadDomain -name $workloadDomain $resourcesObject = gatherSddcInventory -domainType $domainType.type -workloadDomain $workloadDomain # Create a temporary directory under current directory for ($createPathCounter = 0; $createPathCounter -lt 4; $createPathCounter++) { $randomOutput = -join (((48..57) + (65..90) + (97..122)) * 80 | Get-Random -Count 6 | % { [char]$_ }) $tempPath = Join-Path -Path $pwd -childPath $randomOutput if (!(Test-Path -Path $tempPath)) { Break } else { if ($createPathCounter -eq 3) { Write-Error "Unable to write to $tempPath." Exit } } } New-Item -Path $tempPath -ItemType Directory | Out-NULL $tempPath = Join-Path $tempPath "" # Generate a temporay JSON configuration file $operationTypeJson = '{ "operationType": "INSTALL", ' $resourcesBodyObject += [pscustomobject]@{ resources = $resourcesObject } $resourcesBodyObject | ConvertTo-Json -Depth 10 | Out-File -FilePath $tempPath"temp.json" Get-Content $tempPath"temp.json" | Select-Object -Skip 1 | Set-Content $tempPath"temp1.json" $resouresJson = Get-Content $tempPath"temp1.json" -Raw $requestCertificateSpecJson = $operationTypeJson + $resouresJson $requestCertificateSpecJson | Out-File $tempPath"$($workloadDomain)-updateCertificateSpec.json" # Install Certificates Try { Write-Output "Installing signed certificates for components associated with workload domain $($workloadDomain). This process may take some time to complete (60 minutes or greater)..." $myTaskId = Set-VCFCertificate -domainName $($workloadDomain) -json $tempPath"$($workloadDomain)-updateCertificateSpec.json" $pollLoopCounter = 0 Do { if ($pollLoopCounter % 10 -eq 0) { Write-Output "Checking status for the Installation of signed certificates for components associated with workload domain ($($workloadDomain))..." } $response = Get-VCFTask $myTaskId.id if ($response.status -in "In Progress", "IN_PROGRESS") { if (($pollLoopCounter % 10 -eq 0) -AND ($pollLoopCounter -gt 9)) { Write-Output "Installation of signed certificates is still in progress for workload domain ($($workloadDomain))..." } Start-Sleep 60 $pollLoopCounter ++ } } While ($response.status -in "In Progress", "IN_PROGRESS") if ($response.status -eq "FAILED") { Write-Error "Workflow completed with status: $($response.status)." } elseif ($response.status -eq "SUCCESSFUL") { Write-Output "Workflow completed with status: $($response.status)." } else { Write-Warning "Workflow completed with an unrecognized status: $($response.status). Please review the state before proceeding." } Write-Output "Installation of signed certificates for components associated with workload domain $($workloadDomain) completed with status: $($response.status)." # Remove the temporary directory. Remove-Item -Recurse -Force $tempPath | Out-NULL } Catch { $ErrorMessage = $_.Exception.Message Write-Error "Error was: $ErrorMessage" } } else { Write-Error "Unable to authenticate to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } else { Write-Error "Unable to connect to SDDC Manager ($($server)): PRE_VALIDATION_FAILED." } } ################################################### END FUNCTIONS ################################################### ####################################################################################################################### |