From eb8b34d3f4a4c9086f48c10e2396ef227908b596 Mon Sep 17 00:00:00 2001 From: Ivaylo Ivanov Date: Tue, 23 Jul 2024 16:05:04 +0300 Subject: [PATCH] chore: add common formatting - Introduced common formatting for the project. - Applied common formatting to all files. - Fixed camel case for variables. Signed-off-by: Ivaylo Ivanov --- .vscode/extensions.json | 10 + .vscode/settings.json | 51 ++ .../PowerManagement-ManagementDomain.ps1 | 377 +++++---- .../PowerManagement-WorkloadDomain.ps1 | 530 ++++++------ VMware.CloudFoundation.PowerManagement.psd1 | 26 +- VMware.CloudFoundation.PowerManagement.psm1 | 768 +++++++----------- 6 files changed, 811 insertions(+), 951 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..0d37b11 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "vscode.json-language-features", // JSON + "davidanson.vscode-markdownlint", // Markdown Lint + "eamodio.gitlens", // GitLens + "esbenp.prettier-vscode", // Prettier + "ms-vscode.powershell", // PowerShell + "trunk.io" // Trunk + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..99fae01 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,51 @@ +{ + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features", + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "editor.trimAutoWhitespace": true + }, + "[md]": { + "editor.defaultFormatter": "DavidAnson.vscode-markdownlint", + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "editor.trimAutoWhitespace": true, + "editor.wordWrap": "bounded", + "editor.wordWrapColumn": 100 + }, + "[powershell]": { + "editor.defaultFormatter": "ms-vscode.powershell", + "editor.formatOnPaste": true, + "editor.formatOnSave": false, + "editor.formatOnType": true, + "editor.trimAutoWhitespace": true, + "editor.wordWrap": "off" + }, + "editor.bracketPairColorization.enabled": true, + "editor.bracketPairColorization.independentColorPoolPerBracketType": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSaveMode": "modificationsIfAvailable", + "editor.guides.bracketPairs": true, + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, + "files.watcherExclude": { + "**/.DS_Store": true, + "**/.site/**": true, + "**/.trunk/**": true + }, + "powershell.analyzeOpenDocumentsOnly": true, + "powershell.codeFormatting.pipelineIndentationStyle": "IncreaseIndentationAfterEveryPipeline", + "powershell.codeFormatting.preset": "OTBS", + "powershell.codeFormatting.trimWhitespaceAroundPipe": true, + "powershell.codeFormatting.whitespaceBetweenParameters": true, + "powershell.integratedConsole.suppressStartupBanner": true, + "powershell.scriptAnalysis.enable": true, + "extensions.ignoreRecommendations": false, + "cSpell.words": [ + "sddcm", + "VCFIR", + "rainpole", + ] +} diff --git a/SampleScripts/PowerManagement-ManagementDomain.ps1 b/SampleScripts/PowerManagement-ManagementDomain.ps1 index 11deea8..c4c7eef 100644 --- a/SampleScripts/PowerManagement-ManagementDomain.ps1 +++ b/SampleScripts/PowerManagement-ManagementDomain.ps1 @@ -9,18 +9,8 @@ <# .NOTES =============================================================================================================== - .Created By: Gary Blake / Sowjanya V - .Organization: Broadcom - .Version: 1.1 (Build 1000) - .Date: 2022-08-12 - =============================================================================================================== - .CHANGE_LOG - - - 0.6.0 (Gary Blake / 2022-02-22) - Initial release - - 1.0.0.1000 (Gary Blake / 2022-28-06) - GA version - - 1.1.0.1000 (Sowjanya V / 2022-08-12) - Support for VCF 4.5 - + Check the CHANGELOG.md file for the latest changes and updates made to this script. =============================================================================================================== .SYNOPSIS @@ -37,7 +27,7 @@ continue shutdown manually, following the VCF documentation. .EXAMPLE - PowerManagement-ManagementDomain.ps1 -server sfo-vcf01.sfo.rainpole.io -user administrator@vsphere.local -pass VMw@re1! -genjson + PowerManagement-ManagementDomain.ps1 -server sfo-vcf01.sfo.rainpole.io -user administrator@vsphere.local -pass VMw@re1! -genJson Initiates a ManagementStartupInput.json generation that could be used for startup. Notes: File generated earlier may not have all needed details for startup, since the environment may have changed (e.g. ESXi hosts that vCenter Server is running on) @@ -63,7 +53,7 @@ Param ( [Parameter (Mandatory = $true, ParameterSetName = "shutdown")] [ValidateNotNullOrEmpty()] [String]$user, [Parameter (Mandatory = $false, ParameterSetName = "genjson")] [Parameter (Mandatory = $false, ParameterSetName = "shutdown")] [ValidateNotNullOrEmpty()] [String]$pass, - [Parameter (Mandatory = $true, ParameterSetName = "genjson")] [ValidateNotNullOrEmpty()] [Switch]$genjson, + [Parameter (Mandatory = $true, ParameterSetName = "genjson")] [ValidateNotNullOrEmpty()] [Switch]$genJson, # Startup [Parameter (Mandatory = $false, ParameterSetName = "startup")] [ValidateNotNullOrEmpty()] [String]$json, [Parameter (Mandatory = $true, ParameterSetName = "startup")] [ValidateNotNullOrEmpty()] [Switch]$startup @@ -128,7 +118,7 @@ Try { Write-PowerManagementLogMessage -Type WARNING -Message "JSON input file is not provided. Cannot proceed! Exiting! " Exit } - Write-Host ""; + Write-Host "" $proceed = Read-Host "The following JSON file $inputFile will be used for the operation, please confirm (Yes or No)[default:No]" if (-Not $proceed) { Write-PowerManagementLogMessage -Type WARNING -Message "None of the options is selected. Default is 'No', hence stopping script execution." @@ -180,10 +170,10 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Write-PowerManagementLogMessage -Type ERROR -Message "Cannot communicate with SDDC Manager ($server). Check the FQDN or IP address or the power state of '$server'." Exit } - $StatusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg - if ( $StatusMsg ) { Write-PowerManagementLogMessage -Type INFO -Message $StatusMsg } - if ( $WarnMsg ) { Write-PowerManagementLogMessage -Type WARNING -Message $WarnMsg } - if ( $ErrorMsg ) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } + $statusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg + if ( $statusMsg ) { Write-PowerManagementLogMessage -Type INFO -Message $statusMsg } + if ( $warnMsg ) { Write-PowerManagementLogMessage -Type WARNING -Message $warnMsg } + if ( $errorMsg ) { Write-PowerManagementLogMessage -Type ERROR -Message $errorMsg } if ($accessToken) { Write-PowerManagementLogMessage -Type INFO -Message "Connection to SDDC Manager has been validated successfully." Write-PowerManagementLogMessage -Type INFO -Message "Gathering system details from the SDDC Manager inventory. It will take some time." @@ -196,16 +186,16 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Write-PowerManagementLogMessage -Type INFO -Message "More than one cluster exists in the management domain." $mgmtClusterIds = @() $mgmtClusterIds = (Get-VCFWorkloadDomain | Select-Object Type -ExpandProperty clusters | Where-Object { $_.type -eq "MANAGEMENT" }).id - foreach ($clusterid in $mgmtClusterIds) { - $clusterid = (Get-VCFCluster | Select-Object name, id, isdefault | Where-Object { $_.id -eq $clusterid }) - $clustername_extra = $Clusterid.name + foreach ($clusterId in $mgmtClusterIds) { + $clusterId = (Get-VCFCluster | Select-Object name, id, isdefault | Where-Object { $_.id -eq $clusterId }) + $clusterNameExtra = $clusterId.name if (!$isDefault) { - $answer = Read-Host -Prompt "Shutdown cluster $clustername_extra. Do you want to continue? Y/N" + $answer = Read-Host -Prompt "Shutdown cluster $clusterNameExtra. Do you want to continue? Y/N" if ($answer -Match "N") { - Write-PowerManagementLogMessage -Type WARNING "Cancelling shutdown of $clustername. Exiting..." + Write-PowerManagementLogMessage -Type WARNING "Cancelling shutdown of $clusterName. Exiting..." Exit } else { - Write-PowerManagementLogMessage -Type INFO "Shutting down $clustername..." + Write-PowerManagementLogMessage -Type INFO "Shutting down $clusterName..." } # Shut Down the vSphere Cluster Services Virtual Machines $domain = Get-VCFWorkloadDomain | Select-Object name, type | Where-Object { $_.type -eq "MANAGEMENT" } @@ -213,29 +203,30 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe if (Test-vSphereConnection -server $($vcfVcenterDetails.fqdn)) { if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { # Set DRS Automation Level to Manual in the Management Domain - Set-DrsAutomationLevel -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -level Manual + Set-DrsAutomationLevel -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -level Manual if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { - $listofVmsnotvCLS = (Get-VM -Location $clustername_extra | Select-Object Name, PowerState, @{N = "ToolsStatus"; E = { $_.ExtensionData.Guest.ToolsStatus } } | Where-Object { $_.name -inotmatch "vCLS" -and $_.PowerState -eq "PoweredOn" }) - $vmnames = $listofVmsnotvCLS.Name - $tools = $listofVmsnotvCLS.ToolsStatus - foreach ($vmname in $vmnames) { - if ($tools[$vmnames.IndexOf($vmname)] -eq "toolsOK") { - Stop-CloudComponent -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -nodes $vmname -timeout 300 + # TODO Fix variable name and matching condition + $listOfVMsNotVcls = (Get-VM -Location $clusterNameExtra | Select-Object Name, PowerState, @{N = "ToolsStatus"; E = { $_.ExtensionData.Guest.ToolsStatus } } | Where-Object { $_.name -inotmatch "vCLS" -and $_.PowerState -eq "PoweredOn" }) + $vmNames = $listOfVMsNotVcls.Name + $toolsStatus = $listOfVMsNotVcls.ToolsStatus + foreach ($vmName in $vmNames) { + if ($toolsStatus[$vmNames.IndexOf($vmName)] -eq "toolsOK") { + Stop-CloudComponent -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -nodes $vmName -timeout 300 } else { - Write-Error "Unable to shutdown virtual machines $vmname. VMware Tools is not running, Please shutdown the virtual machines before retrying. Exiting..." + Write-Error "Unable to shutdown virtual machines $vmName. VMware Tools is not running, Please shutdown the virtual machines before retrying. Exiting..." Exit } } # Shut Down the vSphere Cluster Services Virtual Machines - Set-Retreatmode -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -mode enable + Set-Retreatmode -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -mode enable $counter = 0 $retries = 10 Write-PowerManagementLogMessage -Type INFO -Message "vCLS retreat mode has been set. vCLS shutdown will take time. Please wait..." while ($counter -ne $retries) { if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { - $powerOnVMcount = (Get-VM -Location $clustername_extra | Where-Object { $_.name -match "vCLS" }).count + $powerOnVMcount = (Get-VM -Location $clusterNameExtra | Where-Object { $_.name -match "vCLS" }).count if ( $powerOnVMcount ) { Write-PowerManagementLogMessage -Type INFO -Message "Some vCLS virtual machines are still running. Sleeping for $sleepTime seconds until the next check..." Start-Sleep -s $sleepTime @@ -250,27 +241,27 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe # Stop vSphere HA to avoid "orphaned" VMs during vSAN shutdown if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { - if (!$(Set-VsphereHA -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -disableHA)) { - Write-PowerManagementLogMessage -Type ERROR -Message "Unable to disable vSphere High Availability for cluster '$clustername'. Exiting..." + if (!$(Set-VsphereHA -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -disableHA)) { + Write-PowerManagementLogMessage -Type ERROR -Message "Unable to disable vSphere High Availability for cluster '$clusterName'. Exiting..." Exit } } if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { - $RemoteVMs = @() - $RemoteVMs = Get-poweronVMsOnRemoteDS $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -clustertocheck $clustername + $remoteVMs = @() + $remoteVMs = Get-PowerOnVMsOnRemoteDS $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -clustertocheck $clusterName Write-PowerManagementLogMessage -Type INFO -Message "All remote virtual machines are powered off." } else { - Write-PowerManagementLogMessage -Type ERROR -Message "Some remote virtual machines are still powered-on : $($RemoteVMs.Name). Unable to proceed until these are are shutdown. Exiting..." + Write-PowerManagementLogMessage -Type ERROR -Message "Some remote virtual machines are still powered-on : $($remoteVMs.Name). Unable to proceed until these are are shutdown. Exiting..." Exit } # Testing VSAN health - if ( (Test-VsanHealth -cluster $clustername_extra -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -eq 0) { + if ( (Test-VsanHealth -cluster $clusterNameExtra -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "vSAN cluster is in a healthy state." } else { - Write-PowerManagementLogMessage -Type ERROR -Message "vSAN cluster is in an unhealthy state. Check the vSAN status in cluster '$($clustername)'. Retry after resolving the vSAN health state. Exiting..." + Write-PowerManagementLogMessage -Type ERROR -Message "vSAN cluster is in an unhealthy state. Check the vSAN status in cluster '$($clusterName)'. Retry after resolving the vSAN health state. Exiting..." Exit } - if ((Test-VsanObjectResync -cluster $clustername_extra -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -eq 0) { + if ((Test-VsanObjectResync -cluster $clusterNameExtra -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "vSAN object resynchronization successful." } else { Write-PowerManagementLogMessage -Type ERROR -Message "vSAN object resynchronization is running. Retry after the vSAN object resynchronization is completed. Exiting..." @@ -280,30 +271,30 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { if ([float]$vcfVersion -lt [float]4.5) { # Disable cluster member updates from vCenter Server - $esxihosts = (Get-VCFHost | Select-Object fqdn -ExpandProperty cluster | Where-Object { $_.id -eq $clusterid.id }).fqdn - foreach ($esxi in $esxihosts) { + $esxiHosts = (Get-VCFHost | Select-Object fqdn -ExpandProperty cluster | Where-Object { $_.id -eq $clusterId.id }).fqdn + foreach ($esxi in $esxiHosts) { if (-Not (Test-VsphereConnection -server $esxiNode)) { Write-PowerManagementLogMessage -Type ERROR "ESXi host $esxi is not accessible. Exiting..." Exit } else { $password = (Get-VCFCredential -resourceName $esxi | Select-Object password) - $esxihostpassword = $password.password[1] - $status = Get-SSHEnabledStatus -server $esxi -user root -pass $esxihostpassword + $esxiHostPassword = $password.password[1] + $status = Get-SSHEnabledStatus -server $esxi -user root -pass $esxiHostPassword if (-Not $status) { - if (Test-vSphereAuthentication -server $esxi -user root -pass $esxihostpassword) { + if (Test-vSphereAuthentication -server $esxi -user root -pass $esxiHostPassword) { Write-PowerManagementLogMessage -Type WARNING "SSH is not enabled on ESXi host $esx. Enabling SSH..." Get-VmHostService -VMHost $esxi | Where-Object { $_.key -eq "TSM-SSH" } | Start-VMHostService Start-Sleep -s 10 Write-PowerManagementLogMessage -Type INFO "Setting ESXi host $esxi to ignoreClusterMemberListUpdates..." - Invoke-EsxCommand -server $esxi -user root -pass $esxihostpassword -expected "Value of IgnoreClusterMemberListUpdates is 1" -cmd "esxcfg-advcfg -s 1 /VSAN/IgnoreClusterMemberListUpdates" + Invoke-EsxCommand -server $esxi -user root -pass $esxiHostPassword -expected "Value of IgnoreClusterMemberListUpdates is 1" -cmd "esxcfg-advcfg -s 1 /VSAN/IgnoreClusterMemberListUpdates" } else { Write-PowerManagementLogMessage -Type ERROR "Unable to authenticate to ESXi host $esxi. Exiting..." Exit } } else { - if (Test-vSphereAuthentication -server $esxi -user root -pass $esxihostpassword) { + if (Test-vSphereAuthentication -server $esxi -user root -pass $esxiHostPassword) { Write-PowerManagementLogMessage -Type INFO "Setting ESXi host $esxi to ignoreClusterMemberListUpdates..." - Invoke-EsxCommand -server $esxi -user root -pass $esxihostpassword -expected "Value of IgnoreClusterMemberListUpdates is 1" -cmd "esxcfg-advcfg -s 1 /VSAN/IgnoreClusterMemberListUpdates" + Invoke-EsxCommand -server $esxi -user root -pass $esxiHostPassword -expected "Value of IgnoreClusterMemberListUpdates is 1" -cmd "esxcfg-advcfg -s 1 /VSAN/IgnoreClusterMemberListUpdates" } else { Write-PowerManagementLogMessage -Type ERROR "Unable to authenticate to ESXi host $esxi. Exiting..." Exit @@ -314,39 +305,39 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe # Run vSAN cluster preparation on one ESXi host per cluster. Write-PowerManagementLogMessage -Type INFO -Message "Pausing for 60 seconds before preparing ESXi hosts for vSAN shutdown..." Start-Sleep -s 60 - $password = (Get-VCFCredential -resourceName $esxihosts[0] | Select-Object password) - $esxihostpassword = $password.password[1] - Invoke-EsxCommand -server $esxihosts[0] -user root -pass $esxihostpassword -expected "Cluster preparation is done" -cmd "python /usr/lib/vmware/vsan/bin/reboot_helper.py prepare" + $password = (Get-VCFCredential -resourceName $esxiHosts[0] | Select-Object password) + $esxiHostPassword = $password.password[1] + Invoke-EsxCommand -server $esxiHosts[0] -user root -pass $esxiHostPassword -expected "Cluster preparation is done" -cmd "python /usr/lib/vmware/vsan/bin/reboot_helper.py prepare" # Putting hosts in maintenance mode Write-PowerManagementLogMessage -Type INFO -Message "Pausing for 30 seconds before putting ESXi hosts in maintenance mode..." Start-Sleep -s 30 - foreach ($esxiNode in $esxihosts) { + foreach ($esxiNode in $esxiHosts) { $password = (Get-VCFCredential -resourceName $esxi | Select-Object password) - $esxihostpassword = $password.password[1] - Set-MaintenanceMode -server $esxiNode -user root -pass $esxihostpassword -state ENABLE + $esxiHostPassword = $password.password[1] + Set-MaintenanceMode -server $esxiNode -user root -pass $esxiHostPassword -state ENABLE } # End of shutdown Write-PowerManagementLogMessage -Type INFO -Message "End of the shutdown sequence!" Write-PowerManagementLogMessage -Type INFO -Message "You can now shut down the ESXi hosts." } else { # vSAN shutdown wizard automation. - Set-VsanClusterPowerStatus -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -PowerStatus clusterPoweredOff -mgmt + Set-VsanClusterPowerStatus -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -PowerStatus clusterPoweredOff -mgmt Write-PowerManagementLogMessage -Type INFO -Message "Pausing for 60 seconds before checking ESXi hosts' shutdown status..." Start-Sleep -s 60 $counter = 0 $sleepTime = 60 # in seconds while ($counter -lt 1800) { - $successcount = 0 + $successCount = 0 # Verify all ESXi hosts are shut down to conclude the sequence - foreach ($esxiNode in $esxihosts) { + foreach ($esxiNode in $esxiHosts) { if (Test-VsphereConnection -server $esxiNode) { - Write-PowerManagementLogMessage -Type WARNING -Message "Some ESXi hosts are still up. Pausing for 60 seconds before next check..." + Write-PowerManagementLogMessage -Type WARNING -Message "Some ESXi hosts are still up. Pausing for $sleepTime seconds before next check..." Break } else { - $successcount++ + $successCount++ } } - if ($successcount -eq $esxiWorkloadDomain.count) { + if ($successCount -eq $esxiWorkloadDomain.count) { Write-PowerManagementLogMessage -Type INFO -Message "All ESXi hosts have been shut down successfully!" Write-PowerManagementLogMessage -Type INFO -Message "Successfully completed the shutdown sequence!" Exit @@ -367,9 +358,6 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Write-PowerManagementLogMessage -Type INFO -Message "A single cluster exists in the management domain." $cluster = Get-VCFCluster | Where-Object { $_.domain.id -eq $workloadDomain.id } } - <<<<<<< HEAD - - ======= $cluster = Get-VCFCluster | Where-Object { $_.id -eq ($workloadDomain.clusters.id) } @@ -410,28 +398,28 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe } if ($vcPass) { - $vcPass_encrypted = $vcPass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString + $vcPassEncrypted = $vcPass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString } else { - $vcPass_encrypted = $null + $vcPassEncrypted = $null } - [Array]$allvms = @() - [Array]$vcfvms = @() + [Array]$allVMs = @() + [Array]$vcfVMs = @() # Checks to see if the server parameter is provided as an IP address or FQDN. if ($server -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') { $fqdn = (Get-VCFManager | Select-Object fqdn, ipAddress | Where-Object { $_.ipAddress -eq $server }).fqdn - [Array]$vcfvms += $fqdn.Split(".")[0] + [Array]$vcfVMs += $fqdn.Split(".")[0] } else { - [Array]$vcfvms += $server.Split(".")[0] + [Array]$vcfVMs += $server.Split(".")[0] } - [Array]$vcfvms += ($vcServer.fqdn).Split(".")[0] + [Array]$vcfVMs += ($vcServer.fqdn).Split(".")[0] $var["Server"] = @{} $var["Server"]["name"] = $vcServer.fqdn.Split(".")[0] $var["Server"]["fqdn"] = $vcServer.fqdn $var["Server"]["user"] = $vcUser - $var["Server"]["password"] = $vcPass_encrypted + $var["Server"]["password"] = $vcPassEncrypted $var["Hosts"] = @() # Gather ESXi Host Details for the Management Workload Domain @@ -449,9 +437,9 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe $esxi_block["user"] = $esxDetails.username $Pass = $esxDetails.password if ($Pass) { - $Pass_encrypted = $Pass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString + $PassEncrypted = $Pass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString } else { - $Pass_encrypted = $null + $PassEncrypted = $null } $esxi_block["password"] = $Pass_encrypted $var["Hosts"] += $esxi_block @@ -459,35 +447,35 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe # Gather NSX Manager Cluster Details $nsxtCluster = Get-VCFNsxtCluster -id $workloadDomain.nsxtCluster.id - $nsxtMgrfqdn = $nsxtCluster.vipFqdn - $nsxMgrVIP = New-Object -TypeName PSCustomObject - $nsxMgrVIP | Add-Member -Type NoteProperty -Name adminUser -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtMgrfqdn -and $_.credentialType -eq "API" })).username - $nsxMgrPass = (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtMgrfqdn -and $_.credentialType -eq "API" })).password - if ($nsxMgrPass) { - $nsxMgrPassEncrypted = $nsxMgrPass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString + $nsxtManagerFQDN = $nsxtCluster.vipFqdn + $nsxtManagerVIP = New-Object -TypeName PSCustomObject + $nsxtManagerVIP | Add-Member -Type NoteProperty -Name adminUser -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtManagerFQDN -and $_.credentialType -eq "API" })).username + $nsxtManagerPass = (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtManagerFQDN -and $_.credentialType -eq "API" })).password + if ($nsxtManagerPass) { + $nsxtManagerPassEncrypted = $nsxtManagerPass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString } else { - $nsxMgrPassEncrypted = $null + $nsxtManagerPassEncrypted = $null } - $nsxMgrVIP | Add-Member -Type NoteProperty -Name adminPassword -Value $nsxmgrPass - $nsxtNodesfqdn = $nsxtCluster.nodes.fqdn + $nsxtManagerVIP | Add-Member -Type NoteProperty -Name adminPassword -Value $nsxmgrPass + $nsxtNodesFQDN = $nsxtCluster.nodes.fqdn $nsxtNodes = @() - foreach ($node in $nsxtNodesfqdn) { + foreach ($node in $nsxtNodesFQDN) { [Array]$nsxtNodes += $node.Split(".")[0] - [Array]$vcfvms += $node.Split(".")[0] + [Array]$vcfVMs += $node.Split(".")[0] } $var["NsxtManager"] = @{} - $var["NsxtManager"]["vipfqdn"] = $nsxtMgrfqdn - $var["NsxtManager"]["nodes"] = $nsxtNodesfqdn - $var["NsxtManager"]["user"] = $nsxMgrVIP.adminUser - $var["NsxtManager"]["password"] = $nsxMgrPassEncrypted + $var["NsxtManager"]["vipfqdn"] = $nsxtManagerFQDN + $var["NsxtManager"]["nodes"] = $nsxtNodesFQDN + $var["NsxtManager"]["user"] = $nsxtManagerVIP.adminUser + $var["NsxtManager"]["password"] = $nsxtManagerPassEncrypted # Gather NSX-T Edge Node Details - $nsxManagerPowerOnVMs = 0 + $nsxtManagerPowerOnVMs = 0 foreach ($nsxtManager in $nsxtNodes) { $state = Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -pattern $nsxtManager -exactMatch -silence - if ($state) { $nsxManagerPowerOnVMs += 1 } + if ($state) { $nsxtManagerPowerOnVMs += 1 } # If we have all NSX-T managers running, or minimum 2 nodes up - query NSX-T for edges. - if (($nsxManagerPowerOnVMs -eq $nsxtNodes.count) -or ($nsxManagerPowerOnVMs -eq 2)) { + if (($nsxtManagerPowerOnVMs -eq $nsxtNodes.count) -or ($nsxtManagerPowerOnVMs -eq 2)) { $statusOfNsxtClusterVMs = 'running' } } @@ -495,13 +483,13 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Write-PowerManagementLogMessage -Type WARNING -Message "NSX Manager VMs have been stopped. NSX Edge VMs will not be handled automatically." } else { Try { - Write-output "adminpssword: $nsxMgrVIP.adminPassword" + Write-Output "adminpssword: $nsxtManagerVIP.adminPassword" Write-PowerManagementLogMessage -Type INFO -Message "NSX Manager VMs are in running state. Trying to fetch information about the NSX Edge VMs..." - [Array]$edgeNodes = (Get-EdgeNodeFromNSXManager -server $nsxtMgrfqdn -user $nsxMgrVIP.adminUser -pass $nsxMgrVIP.adminPassword -VCfqdn $VcServer.fqdn) - $edgenodesstring = $edgeNodes -join "," - Write-PowerManagementLogMessage -Type INFO -Message "The NSX Edge VMs are $edgenodesstring." - } catch { - Write-PowerManagementLogMessage -Type ERROR -Message "Something went wrong! Cannot fetch NSX Edge nodes information from NSX Manager '$nsxtMgrfqdn'. Exiting!" + [Array]$edgeNodes = (Get-EdgeNodeFromNSXManager -server $nsxtManagerFQDN -user $nsxtManagerVIP.adminUser -pass $nsxtManagerVIP.adminPassword -VCfqdn $VcServer.fqdn) + $edgeNodesToString = $edgeNodes -join "," + Write-PowerManagementLogMessage -Type INFO -Message "The NSX Edge VMs are $edgeNodesToString." + } Catch { + Write-PowerManagementLogMessage -Type ERROR -Message "Something went wrong! Cannot fetch NSX Edge nodes information from NSX Manager '$nsxtManagerFQDN'. Exiting!" } } @@ -510,8 +498,8 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe $var["NsxEdge"] = @{} $var["NsxEdge"]["nodes"] = New-Object System.Collections.ArrayList foreach ($val in $edgeNodes) { - $var["NsxEdge"]["nodes"].add($val) | out-null - [Array]$vcfvms += $val + $var["NsxEdge"]["nodes"].add($val) | Out-Null + [Array]$vcfVMs += $val } } @@ -526,10 +514,9 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue | Out-Null } Connect-VIServer -server $vcServer.fqdn -user $vcUser -password $vcPass | Out-Null - #$sddcManagerIP = (Test-NetConnection -ComputerName $server).RemoteAddress.IPAddressToString $sddcManagerIP = (Get-VCFManager | Select-Object ipAddress).ipAddress $sddcmVMName = (Get-VM * | Where-Object { $_.Guest.IPAddress -eq $sddcManagerIP }).Name - $vcHost = (get-vm | where Name -eq $vcServer.fqdn.Split(".")[0] | Select-Object VMHost).VMHost.Name + $vcHost = (get-vm | Where-Object Name -EQ $vcServer.fqdn.Split(".")[0] | Select-Object VMHost).VMHost.Name $vcHostUser = (Get-VCFCredential -resourceType ESXI -resourceName $vcHost | Where-Object { $_.accountType -eq "USER" }).username $vcHostPass = (Get-VCFCredential -resourceType ESXI -resourceName $vcHost | Where-Object { $_.accountType -eq "USER" }).password $vcHostPass_encrypted = $vcHostPass | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString @@ -588,7 +575,7 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Exit } } - } catch { + } Catch { Write-PowerManagementLogMessage -Type ERROR -Message $_.Exception.Message Exit } @@ -610,7 +597,7 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe $pass = $sddcManagerPassword if (Test-VCFAuthentication -server $server -user $user -pass $pass) { $allWorkloadvCenters = @() - $allWorkloadvCenters = (Get-VCFWorkloadDomain | Select-object type -ExpandProperty vcenters | Where-Object { $_.type -eq "VI" }).fqdn + $allWorkloadvCenters = (Get-VCFWorkloadDomain | Select-Object type -ExpandProperty vcenters | Where-Object { $_.type -eq "VI" }).fqdn if ($allWorkloadvCenters) { $domain = Get-VCFWorkloadDomain | Select-Object name, type | Where-Object { $_.type -eq "MANAGEMENT" } if (($vcfVcenterDetails = Get-vCenterServerDetail -server $server -user $user -pass $pass -domain $domain.name)) { @@ -637,27 +624,27 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe } Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch all powered-on virtual machines from server $($vcServer.fqdn)..." - [Array]$allvms = Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -silence - $customervms = @() + [Array]$allVMs = Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -silence + $customerVMs = @() Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch all powered-on vCLS virtual machines from server $($vcServer.fqdn)..." [Array]$vclsvms += Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -pattern "(^vCLS-\w{8}-\w{4}-\w{4}-\w{4}-\w{12})|(^vCLS\s*\(\d+\))|(^vCLS\s*$)" -silence foreach ($vm in $vclsvms) { - [Array]$vcfvms += $vm + [Array]$vcfVMs += $vm } Write-PowerManagementLogMessage -Type INFO -Message "Fetching all powered on vSAN File Services virtual machines from vCenter Server instance $($vcenter)..." [Array]$vsanfsvms += Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -pattern "(vSAN File)" -silence foreach ($vm in $vsanfsvms) { - [Array]$vcfvms += $vm + [Array]$vcfVMs += $vm } - $customervms = $allvms | ? { $vcfvms -notcontains $_ } - $vcfvms_string = $vcfvms -join "; " - Write-PowerManagementLogMessage -Type INFO -Message "Management virtual machines covered by the script: '$($vcfvms_string)' ." - if ($customervms.count -ne 0) { - $customervms_string = $customervms -join "; " - Write-PowerManagementLogMessage -Type INFO -Message "Virtual machines not covered by the script: '$($customervms_string)' . Those VMs will be stopped in a random order if the 'shutdownCustomerVm' flag is passed." + $customerVMs = $allVMs | Where-Object { $vcfVMs -notcontains $_ } + $vcfVMs_string = $vcfVMs -join "; " + Write-PowerManagementLogMessage -Type INFO -Message "Management virtual machines covered by the script: '$($vcfVMs_string)' ." + if ($customerVMs.count -ne 0) { + $customerVMs_string = $customerVMs -join "; " + Write-PowerManagementLogMessage -Type INFO -Message "Virtual machines not covered by the script: '$($customerVMs_string)' . Those VMs will be stopped in a random order if the 'shutdownCustomerVm' flag is passed." } # Check if VMware Tools are running in the customer VMs - if not we could not stop them gracefully @@ -671,9 +658,9 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$($vcServer.fqdn)' ..." Connect-VIServer -Server $vcServer.fqdn -Protocol https -User $vcUser -Password $vcPass -ErrorVariable $vcConnectError | Out-Null if ($DefaultVIServer.Name -eq $vcServer.fqdn) { - Write-PowerManagementLogMessage -type INFO -Message "Connected to server '$($vcServer.fqdn)' and trying to get VMwareTools Status." - foreach ($vm in $customervms) { - Write-PowerManagementLogMessage -type INFO -Message "Checking VMwareTools Status for '$vm'..." + Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$($vcServer.fqdn)' and trying to get VMwareTools Status." + foreach ($vm in $customerVMs) { + Write-PowerManagementLogMessage -Type INFO -Message "Checking VMwareTools Status for '$vm'..." $vm_data = Get-VM -Name $vm if ($vm_data.ExtensionData.Guest.ToolsRunningStatus -eq "guestToolsRunning") { [Array]$VMwareToolsRunningVMs += $vm @@ -697,17 +684,17 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe } } - if ($customervms.count -ne 0) { - $customervms_string = $customervms -join "; " + if ($customerVMs.count -ne 0) { + $customerVMs_string = $customerVMs -join "; " if ($PsBoundParameters.ContainsKey("shutdownCustomerVm")) { Write-PowerManagementLogMessage -Type WARNING -Message "Some VMs are still in powered-on state. -shutdownCustomerVm is passed to the script." Write-PowerManagementLogMessage -Type WARNING -Message "Hence shutting down VMs not managed by SDDC Manager to put the host in maintenance mode." - Write-PowerManagementLogMessage -Type WARNING -Message "The list of Non VCF management VMs: '$customervms_string'." + Write-PowerManagementLogMessage -Type WARNING -Message "The list of Non VCF management VMs: '$customerVMs_string'." # Stop Customer VMs with one call to VC: - Stop-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $customervms -timeout 300 + Stop-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $customerVMs -timeout 300 } else { Write-PowerManagementLogMessage -Type WARNING -Message "Some VMs are still in powered-on state. -shutdownCustomerVm is not passed to the script." - Write-PowerManagementLogMessage -Type WARNING -Message "Hence not shutting down management VMs not managed by SDDC Manager: $($customervms_string) ." + Write-PowerManagementLogMessage -Type WARNING -Message "Hence not shutting down management VMs not managed by SDDC Manager: $($customerVMs_string) ." Write-PowerManagementLogMessage -Type ERROR -Message "The script cannot proceed unless these VMs are shut down manually or the -shutdownCustomerVm option is present. Take the necessary action and run the script again." Exit } @@ -720,14 +707,14 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe if (($vcfVrslcmDetails = Get-vRSLCMServerDetail -fqdn $server -username $user -password $pass)) { if (Test-vRSLCMAuthentication -server $vcfVrslcmDetails.fqdn -user $vcfVrslcmDetails.adminUser -pass $vcfVrslcmDetails.adminPass) { $productid = "vrli" - $vmlist = Get-vRSLCMEnvironmentVMs -server $server -user $user -pass $pass -productid $productid - if ($vmlist -ne $null) { + $vmList = Get-vRSLCMEnvironmentVMs -server $server -user $user -pass $pass -productid $productid + if ($null -ne $vmList) { $domain = Get-VCFWorkloadDomain | Select-Object name, type | Where-Object { $_.type -eq "MANAGEMENT" } if (($vcfVcenterDetails = Get-vCenterServerDetail -server $server -user $user -pass $pass -domain $domain.name)) { if (Test-vSphereConnection -server $($vcfVcenterDetails.fqdn)) { if (Test-vSphereAuthentication -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) { Write-PowerManagementLogMessage -Type INFO -Message "Stopping the VMware Aria Operations for Logs nodes..." - Stop-CloudComponent -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -nodes $vmlist -timeout 600 + Stop-CloudComponent -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -nodes $vmList -timeout 600 } } } @@ -752,11 +739,11 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe $nsx_segments = Get-NsxtSegment | Select-Object display_name, type | Where-Object { $_.type -eq "ROUTED" } foreach ($segment in $nsx_segments) { $segmentName = $segment.display_name - $cloudvms = Get-VM | Get-NetworkAdapter | Where-Object { $_.NetworkName -eq $segmentName } | Select-Object Parent + $cloudVMs = Get-VM | Get-NetworkAdapter | Where-Object { $_.NetworkName -eq $segmentName } | Select-Object Parent } - $vmlist = $cloudvms.Parent + $vmList = $cloudVMs.Parent $stopExecuted = $false - foreach ($vm in $vmlist) { + foreach ($vm in $vmList) { $vmName = $vm.Name $powerState = $vm.PowerState if ($powerState -eq "PoweredOn") { @@ -841,12 +828,12 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe } # Check if there are VMs running on a vSAN HCI Mesh - $RemoteVMs = @() - $RemoteVMs = Get-poweronVMsOnRemoteDS -server $vcServer.fqdn -user $vcUser -pass $vcPass -clustertocheck $cluster.name - if ($RemoteVMs.count -eq 0) { + $remoteVMs = @() + $remoteVMs = Get-PowerOnVMsOnRemoteDS -server $vcServer.fqdn -user $vcUser -pass $vcPass -clustertocheck $cluster.name + if ($remoteVMs.count -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "All remote VMs are powered off." } else { - Write-PowerManagementLogMessage -Type ERROR -Message "Some remote VMs are still powered-on : $($RemoteVMs.Name). Cannot proceed until the powered-on VMs are shut down. Check your environment." + Write-PowerManagementLogMessage -Type ERROR -Message "Some remote VMs are still powered-on : $($remoteVMs.Name). Cannot proceed until the powered-on VMs are shut down. Check your environment." } #Testing VSAN health after SDDC manager is stopped @@ -893,7 +880,7 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe $runningAllVMs = Get-VMsWithPowerStatus -powerstate "poweredon" -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password -silence [Array]$runningVclsVMs = Get-VMsWithPowerStatus -powerstate "poweredon" -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password -pattern "(^vCLS-\w{8}-\w{4}-\w{4}-\w{4}-\w{12})|(^vCLS\s*\(\d+\))|(^vCLS\s*$)" [Array]$runningVclsVMs += $vcServer.fqdn.Split(".")[0] - $runningVMs = $runningAllVMs | ? { $runningVclsVMs -notcontains $_ } + $runningVMs = $runningAllVMs | Where-Object { $runningVclsVMs -notcontains $_ } } if ($runningVMs.count) { Write-PowerManagementLogMessage -Type WARNING -Message "Some VMs are still in powered-on state." @@ -939,17 +926,17 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe $sleepTime = 60 # in seconds while ($counter -lt 1800) { - $successcount = 0 + $successCount = 0 #Verify if all ESXi hosts are down in here to conclude End of Shutdown sequence foreach ($esxiNode in $esxiWorkloadDomain) { if (Test-EndpointConnection -server $esxiNode.fqdn -Port 443) { Write-PowerManagementLogMessage -Type WARNING -Message "Some hosts are still up. Sleeping for 60 seconds before next check..." break } else { - $successcount++ + $successCount++ } } - if ($successcount -eq $esxiWorkloadDomain.count) { + if ($successCount -eq $esxiWorkloadDomain.count) { Write-PowerManagementLogMessage -Type INFO -Message "All hosts have been shut down successfully!" Write-PowerManagementLogMessage -Type INFO -Message "End of the shutdown sequence!" Exit @@ -970,7 +957,7 @@ if ($PsBoundParameters.ContainsKey("shutdown") -or $PsBoundParameters.ContainsKe # Startup procedures if ($PsBoundParameters.ContainsKey("startup")) { Try { - $MgmtInput = Get-Content -Path $inputFile | ConvertFrom-JSON + $MgmtInput = Get-Content -Path $inputFile | ConvertFrom-Json Write-PowerManagementLogMessage -Type INFO -Message "Gathering system details from JSON file..." # Gather Details from SDDC Manager $workloadDomain = $MgmtInput.Domain.name @@ -978,7 +965,7 @@ if ($PsBoundParameters.ContainsKey("startup")) { $cluster | Add-Member -Type NoteProperty -Name Name -Value $MgmtInput.Cluster.name #Get DRS automation level settings - $DrsAutomationLevel = $MgmtInput.cluster.DrsAutomationLevel + $drsAutomationLevel = $MgmtInput.cluster.DrsAutomationLevel #Getting SDDC manager VM name $sddcmVMName = $MgmtInput.SDDC.name @@ -989,18 +976,18 @@ if ($PsBoundParameters.ContainsKey("startup")) { $vcServer | Add-Member -Type NoteProperty -Name Name -Value $MgmtInput.Server.name $vcServer | Add-Member -Type NoteProperty -Name fqdn -Value $MgmtInput.Server.fqdn $vcUser = $MgmtInput.Server.user - $temp_pass = convertto-securestring -string $MgmtInput.Server.password + $temp_pass = ConvertTo-SecureString -String $MgmtInput.Server.password $temp_pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($temp_pass)))) $vcPass = $temp_pass $vcHost = $MgmtInput.Server.host $vcHostUser = $MgmtInput.Server.vchostuser if ($MgmtInput.Server.vchostpassword) { - $vchostpassword = convertto-securestring -string $MgmtInput.Server.vchostpassword - $vchostpassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($vchostpassword)))) + $vcHostPassword = ConvertTo-SecureString -String $MgmtInput.Server.vchostpassword + $vcHostPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($vcHostPassword)))) } else { - $vchostpassword = $null + $vcHostPassword = $null } - $vcHostPass = $vchostpassword + $vcHostPass = $vcHostPassword # Gather ESXi Host Details for the Management Workload Domain $esxiWorkloadDomain = @() @@ -1010,30 +997,30 @@ if ($PsBoundParameters.ContainsKey("startup")) { $esxDetails | Add-Member -Type NoteProperty -Name fqdn -Value $esxiHost.fqdn $esxDetails | Add-Member -Type NoteProperty -Name username -Value $esxiHost.user if ($esxiHost.password) { - $esxpassword = convertto-securestring -string $esxiHost.password - $esxpassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($esxpassword)))) + $esxPassword = ConvertTo-SecureString -String $esxiHost.password + $esxPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($esxPassword)))) } else { - $esxpassword = $null + $esxPassword = $null } - $esxDetails | Add-Member -Type NoteProperty -Name password -Value $esxpassword + $esxDetails | Add-Member -Type NoteProperty -Name password -Value $esxPassword $esxiWorkloadDomain += $esxDetails } # Gather NSX Manager Cluster Details $nsxtCluster = $MgmtInput.NsxtManager - $nsxtMgrfqdn = $MgmtInput.NsxtManager.vipfqdn - $nsxMgrVIP = New-Object -TypeName PSCustomObject - $nsxMgrVIP | Add-Member -Type NoteProperty -Name adminUser -Value $MgmtInput.NsxtManager.user + $nsxtManagerFQDN = $MgmtInput.NsxtManager.vipfqdn + $nsxtManagerVIP = New-Object -TypeName PSCustomObject + $nsxtManagerVIP | Add-Member -Type NoteProperty -Name adminUser -Value $MgmtInput.NsxtManager.user if ($MgmtInput.NsxtManager.password) { - $nsxpassword = convertto-securestring -string $MgmtInput.NsxtManager.password - $nsxpassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($nsxpassword)))) + $nsxPassword = ConvertTo-SecureString -String $MgmtInput.NsxtManager.password + $nsxPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR((($nsxPassword)))) } else { - $nsxpassword = $null + $nsxPassword = $null } - $nsxMgrVIP | Add-Member -Type NoteProperty -Name adminPassword -Value $nsxpassword - $nsxtNodesfqdn = $MgmtInput.NsxtManager.nodes + $nsxtManagerVIP | Add-Member -Type NoteProperty -Name adminPassword -Value $nsxPassword + $nsxtNodesFQDN = $MgmtInput.NsxtManager.nodes $nsxtNodes = @() - foreach ($node in $nsxtNodesfqdn) { + foreach ($node in $nsxtNodesFQDN) { [Array]$nsxtNodes += $node.Split(".")[0] } @@ -1048,7 +1035,7 @@ if ($PsBoundParameters.ContainsKey("startup")) { Write-PowerManagementLogMessage -Type INFO -Message "Could not connect to $($vcServer.fqdn). Starting vSAN..." if ([float]$vcfVersion -gt [float]4.4) { #TODO add check if hosts are up and running. If so, do not display this message - Write-Host ""; + Write-Host "" $proceed = Read-Host "Please start all the ESXi host belonging to the cluster '$($cluster.name)' and wait for the host console to come up. Once done, please enter yes." if (-Not $proceed) { Write-PowerManagementLogMessage -Type WARNING -Message "None of the options is selected. Default is 'No', hence, stopping script execution..." @@ -1086,7 +1073,7 @@ if ($PsBoundParameters.ContainsKey("startup")) { Exit } } - } catch { + } Catch { Write-PowerManagementLogMessage -Type ERROR -Message $_.Exception.Message Exit } @@ -1187,11 +1174,11 @@ if ($PsBoundParameters.ContainsKey("startup")) { } # Restore the DRS Automation Level to the mode backed up for Management Domain Cluster during shutdown - if ([string]::IsNullOrEmpty($DrsAutomationLevel)) { + if ([string]::IsNullOrEmpty($drsAutomationLevel)) { Write-PowerManagementLogMessage -Type ERROR -Message "The DrsAutomationLevel value in the JSON file is empty. Exiting!" Exit } else { - Set-DrsAutomationLevel -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -level $DrsAutomationLevel + Set-DrsAutomationLevel -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -level $drsAutomationLevel } } @@ -1222,7 +1209,7 @@ if ($PsBoundParameters.ContainsKey("startup")) { # Startup the NSX Manager Nodes in the Management Workload Domain Start-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $nsxtNodes -timeout 600 - if (!(Wait-ForStableNsxtClusterStatus -server $nsxtMgrfqdn -user $nsxMgrVIP.adminUser -pass $nsxMgrVIP.adminPassword)) { + if (!(Wait-ForStableNsxtClusterStatus -server $nsxtManagerFQDN -user $nsxtManagerVIP.adminUser -pass $nsxtManagerVIP.adminPassword)) { Write-PowerManagementLogMessage -Type ERROR -Message "The NSX Manager cluster is not in 'STABLE' state. Exiting!" Exit } @@ -1241,42 +1228,42 @@ if ($PsBoundParameters.ContainsKey("startup")) { $mgmtClusterIds = (Get-VCFWorkloadDomain | Select-Object Type -ExpandProperty clusters | Where-Object { $_.type -eq "MANAGEMENT" }).id # Checks to see how many Clusters are in Management Domain if ($mgmtClusterIds.Count -ge 2) { - foreach ($clusterid in $mgmtClusterIds) { - $clusterid = (Get-VCFCluster | Select-Object name, id, isdefault | Where-Object { $_.id -eq $clusterid }) - $clustername = $Clusterid.name - $isDefault = $clusterid.isDefault + foreach ($clusterId in $mgmtClusterIds) { + $clusterId = (Get-VCFCluster | Select-Object name, id, isdefault | Where-Object { $_.id -eq $clusterId }) + $clusterName = $clusterId.name + $isDefault = $clusterId.isDefault if (!$isDefault) { - $answer = Read-Host -Prompt "Start up cluster $clustername, Do you want to continue? Y/N" + $answer = Read-Host -Prompt "Start up cluster $clusterName, Do you want to continue? Y/N" if ($answer -Match 'N') { - Write-PowerManagementLogMessage -Type WARNING "Cancelled start up of $clustername. Exiting..." + Write-PowerManagementLogMessage -Type WARNING "Cancelled start up of $clusterName. Exiting..." Exit } else { - Write-PowerManagementLogMessage -Type INFO "Will Move Forward with start up of $clustername" + Write-PowerManagementLogMessage -Type INFO "Will Move Forward with start up of $clusterName" } - $esxihosts = (Get-VCFHost | Select-Object fqdn -ExpandProperty cluster | Where-Object { $_.id -eq $clusterid.id }).fqdn - foreach ($esxiNode in $esxihosts) { + $esxiHosts = (Get-VCFHost | Select-Object fqdn -ExpandProperty cluster | Where-Object { $_.id -eq $clusterId.id }).fqdn + foreach ($esxiNode in $esxiHosts) { if (-Not (Test-VsphereConnection -server $esxiNode)) { Write-PowerManagementLogMessage -Type WARNING "ESXi host $esxiNode is not powered on...." } else { $password = (Get-VCFCredential -resourceName $esxiNode | Select-Object password) - $esxihostpassword = $password.password[1] - $status = Get-SSHEnabledStatus -server $esxiNode -user root -pass $esxihostpassword + $esxiHostPassword = $password.password[1] + $status = Get-SSHEnabledStatus -server $esxiNode -user root -pass $esxiHostPassword if (-Not $status) { - if (Test-vSphereAuthentication -server $esxi -user root -pass $esxihostpassword) { + if (Test-vSphereAuthentication -server $esxi -user root -pass $esxiHostPassword) { Write-PowerManagementLogMessage -Type WARNING "SSH is not enabled on $esxiNode, enabling it now..." Get-VmHostService -VMHost $esxiNode | Where-Object { $_.key -eq "TSM-SSH" } | Start-VMHostService Start-Sleep -s 10 Write-PowerManagementLogMessage -Type INFO "Attempting to Set Maintenance Mode on $esxiNode to DISABLE" - Set-MaintenanceMode -server $esxiNode -user root -pass $esxihostpassword -state DISABLE + Set-MaintenanceMode -server $esxiNode -user root -pass $esxiHostPassword -state DISABLE Start-Sleep -s 120 } else { Write-PowerManagementLogMessage -Type ERROR "Unable to authenticate to $esxiNode. Exiting..." Exit } } else { - if (Test-vSphereAuthentication -server $esxi -user root -pass $esxihostpassword) { + if (Test-vSphereAuthentication -server $esxi -user root -pass $esxiHostPassword) { Write-PowerManagementLogMessage -Type INFO "Attempting to Set Maintenance Mode on $esxiNode to DISABLE" - Set-MaintenanceMode -server $esxiNode -user root -pass $esxihostpassword -state DISABLE + Set-MaintenanceMode -server $esxiNode -user root -pass $esxiHostPassword -state DISABLE Start-Sleep -s 120 } else { Write-PowerManagementLogMessage -Type ERROR "Unable to authenticate to $esxiNode. Exiting..." @@ -1291,25 +1278,25 @@ if ($PsBoundParameters.ContainsKey("startup")) { # Prepare the vSAN cluster for startup - Performed on a single host only # We need some time before this step, setting hard sleep 30 sec Write-PowerManagementLogMessage -Type INFO -Message "Pausing for 30 seconds before starting vSAN..." - $password = (Get-VCFCredential -resourceName $esxihosts[0] | Select-Object password) - $esxihostpassword = $password.password[1] - Invoke-EsxCommand -server $esxihosts[0] -user root -pass $esxihostpassword -expected "Cluster reboot/poweron is completed successfully!" -cmd "python /usr/lib/vmware/vsan/bin/reboot_helper.py recover" + $password = (Get-VCFCredential -resourceName $esxiHosts[0] | Select-Object password) + $esxiHostPassword = $password.password[1] + Invoke-EsxCommand -server $esxiHosts[0] -user root -pass $esxiHostPassword -expected "Cluster reboot/poweron is completed successfully!" -cmd "python /usr/lib/vmware/vsan/bin/reboot_helper.py recover" # We need some time before this step, setting hard sleep 30 sec Write-PowerManagementLogMessage -Type INFO -Message "Pausing for 30 seconds before enabling vSAN updates..." Start-Sleep -s 30 - foreach ($esxi in $esxihosts) { + foreach ($esxi in $esxiHosts) { $password = (Get-VCFCredential -resourceName $esxi | Select-Object password) - $esxihostpassword = $password.password[1] - if (Test-vSphereAuthentication -server $esxi -user root -pass $esxihostpassword) { + $esxiHostPassword = $password.password[1] + if (Test-vSphereAuthentication -server $esxi -user root -pass $esxiHostPassword) { Write-PowerManagementLogMessage -Type INFO -Message "Set hosts to ignoreClusterMemberListUpdates" - Invoke-EsxCommand -server $esxi -user root -pass $esxihostpassword -expected "Value of IgnoreClusterMemberListUpdates is 0" -cmd "esxcfg-advcfg -s 0 /VSAN/IgnoreClusterMemberListUpdates" + Invoke-EsxCommand -server $esxi -user root -pass $esxiHostPassword -expected "Value of IgnoreClusterMemberListUpdates is 0" -cmd "esxcfg-advcfg -s 0 /VSAN/IgnoreClusterMemberListUpdates" } } Write-PowerManagementLogMessage -Type INFO -Message "Checking vSAN status of the ESXi hosts..." - foreach ($esxiNode in $esxihosts) { + foreach ($esxiNode in $esxiHosts) { $password = (Get-VCFCredential -resourceName $esxi | Select-Object password) - $esxihostpassword = $password.password[1] + $esxiHostPassword = $password.password[1] Invoke-EsxCommand -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password -expected "Local Node Health State: HEALTHY" -cmd "esxcli vsan cluster get" } } @@ -1320,37 +1307,37 @@ if ($PsBoundParameters.ContainsKey("startup")) { # Start the vSAN cluster wizard. if ([float]$vcfVersion -gt [float]4.5) { # Lockdown mode check - Test-LockdownMode -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername + Test-LockdownMode -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName # Restart cluster using wizard - Set-VsanClusterPowerStatus -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -PowerStatus clusterPoweredOn + Set-VsanClusterPowerStatus -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -PowerStatus clusterPoweredOn } # Check vSAN Status - if ( (Test-VsanHealth -cluster $clustername -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -ne 0) { - Write-PowerManagementLogMessage -Type WARNING -Message "vSAN cluster is in an unhealthy state. Check the vSAN status in cluster '$($clustername)'. Retry after resolving the vSAN health state. Exiting..." + if ( (Test-VsanHealth -cluster $clusterName -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -ne 0) { + Write-PowerManagementLogMessage -Type WARNING -Message "vSAN cluster is in an unhealthy state. Check the vSAN status in cluster '$($clusterName)'. Retry after resolving the vSAN health state. Exiting..." Exit } - if ( (Test-VsanObjectResync -cluster $clustername -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -ne 0) { + if ( (Test-VsanObjectResync -cluster $clusterName -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass) -ne 0) { Write-PowerManagementLogMessage -Type ERROR -Message "vSAN object resynchronization failed. Check your environment and run the script again." Exit } # Start workflow for VCF prior version 4.5 # Start vSphere HA - if (!$(Set-VsphereHA -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -enableHA)) { + if (!$(Set-VsphereHA -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -enableHA)) { Write-PowerManagementLogMessage -Type ERROR -Message "Unable to enable vSphere High Availability for cluster '$cluster'. Exiting..." Exit } # Restore the DRS Automation Level to the mode backed up for Management Domain Cluster during shutdown - if ([string]::IsNullOrEmpty($DrsAutomationLevel)) { + if ([string]::IsNullOrEmpty($drsAutomationLevel)) { Write-PowerManagementLogMessage -Type ERROR -Message "Unable to enable Drs Automation Level for cluster '$cluster'. Exiting..." Exit } else { - Set-DrsAutomationLevel -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -level $DrsAutomationLevel + Set-DrsAutomationLevel -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -level $drsAutomationLevel } # Startup the vSphere Cluster Services Virtual Machines in the Management Workload Domain - Set-Retreatmode -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clustername -mode disable + Set-Retreatmode -server $vcfVcenterDetails.fqdn -user $vcfVcenterDetails.ssoAdmin -pass $vcfVcenterDetails.ssoAdminPass -cluster $clusterName -mode disable # Waiting for vCLS VMs to be started for ($retries*10) seconds $counter = 0 $retries = 10 diff --git a/SampleScripts/PowerManagement-WorkloadDomain.ps1 b/SampleScripts/PowerManagement-WorkloadDomain.ps1 index e6884b4..b24c34c 100644 --- a/SampleScripts/PowerManagement-WorkloadDomain.ps1 +++ b/SampleScripts/PowerManagement-WorkloadDomain.ps1 @@ -9,18 +9,8 @@ <# .NOTES =============================================================================================================== - .Created By: Gary Blake / Sowjanya V - .Organization: Broadcom - .Version: 1.1 (Build 1000) - .Date: 2022-08-12 - =============================================================================================================== - .CHANGE_LOG - - - 0.6.0 (Gary Blake / 2022-02-22) - Initial release - - 1.0.0.1002 (Gary Blake / 2022-28-06) - GA version - - 1.1.0.1000 (Sowjanya V / 2022-08-12) - Add multi-cluster handling; NSX-T Manager that spans across Workload Domains; Support for VCF 4.5 - + Check the CHANGELOG.md file for the latest changes and updates made to this script. =============================================================================================================== .SYNOPSIS @@ -106,8 +96,7 @@ Try { if ($PsBoundParameters.ContainsKey("shutdownCustomerVm")) { $customerVmMessage = "Process WILL gracefully shutdown customer deployed Virtual Machines, if deployed within the Workload Domain." } else { $customerVmMessage = "Process WILL NOT gracefully shutdown customer deployed Virtual Machines not managed by VCF, if deployed within the Workload Domain." } } -} -Catch { +} Catch { Debug-CatchWriterForPowerManagement -object $_ } @@ -116,7 +105,7 @@ Try { $Global:ProgressPreference = 'SilentlyContinue' $str1 = "$PSCommandPath " $str2 = "-server $server -user $user -pass ******* -sddcDomain $sddcDomain" - if ($PsBoundParameters.ContainsKey("vsanCluster")) { $str2 = $str2 + " -vsanCluster " + ($vsanCluster -join ",")} + if ($PsBoundParameters.ContainsKey("vsanCluster")) { $str2 = $str2 + " -vsanCluster " + ($vsanCluster -join ",") } if ($PsBoundParameters.ContainsKey("startup")) { $str2 = $str2 + " -startup" } if ($PsBoundParameters.ContainsKey("shutdown")) { $str2 = $str2 + " -shutdown" } if ($PsBoundParameters.ContainsKey("shutdownCustomerVm")) { $str2 = $str2 + " -shutdownCustomerVm" } @@ -128,27 +117,24 @@ Try { if (!(Test-EndpointConnection -server $server -Port 443)) { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot communicate with SDDC Manager ($server). Check the FQDN or IP address or power state of the '$server'." Exit - } - else { - $StatusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg - if ( $StatusMsg ) { Write-PowerManagementLogMessage -Type INFO -Message $StatusMsg } - if ( $WarnMsg ) { Write-PowerManagementLogMessage -Type WARNING -Message $WarnMsg } - if ( $ErrorMsg ) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } + } else { + $statusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg + if ( $statusMsg ) { Write-PowerManagementLogMessage -Type INFO -Message $statusMsg } + if ( $warnMsg ) { Write-PowerManagementLogMessage -Type WARNING -Message $warnMsg } + if ( $ErrorMsg ) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } if ($accessToken) { Write-PowerManagementLogMessage -Type INFO -Message "Connection to SDDC Manager has been validated successfully." } } -} -Catch { +} Catch { Debug-CatchWriterForPowerManagement -object $_ } # Gather details from SDDC Manager Try { - $original_flow = $false Write-PowerManagementLogMessage -Type INFO -Message "Attempting to connect to VMware Cloud Foundation to gather system details..." - $StatusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg - if ($StatusMsg) { Write-PowerManagementLogMessage -Type INFO -Message $StatusMsg } if ($WarnMsg) { Write-PowerManagementLogMessage -Type WARNING -Message $WarnMsg } if ($ErrorMsg) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } + $statusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg + if ($statusMsg) { Write-PowerManagementLogMessage -Type INFO -Message $statusMsg } if ($warnMsg) { Write-PowerManagementLogMessage -Type WARNING -Message $warnMsg } if ($ErrorMsg) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } if ($accessToken) { Write-PowerManagementLogMessage -Type INFO -Message "Gathering system details from the SDDC Manager inventory... It will take some time." @@ -164,70 +150,65 @@ Try { # Check if there are multiple clusters in the WLD $sddcClusterDetails = @() $userClusterDetails = @() - $ClusterDetails = @() - $userClusterarray = @() - $SDDCclusterarray = @() + $clusterDetails = @() + $userClusterArray = @() + $sddcClusterArray = @() if ($vsanCluster) { - $userClusterarray = $vsanCluster.split(",") + $userClusterArray = $vsanCluster.split(",") #$userShutdownOrder = $true } - $multiClusterEnvironment = $false $allClusterShutdown = $false $hostsClusterMapping = @{} - $sddchostsClusterMapping = @{} + $sddcHostsClusterMapping = @{} $esxiWorkloadCluster = @{} $ClusterStatusMapping = @{} if ($workloadDomain.clusters.id.count -gt 1) { - $multiClusterEnvironment = $true Write-PowerManagementLogMessage -Type INFO -Message "There are multiple clusters in VI domain '$sddcDomain'." } - foreach ($id in $($workloadDomain.clusters.id)) { + foreach ($id in $($workloadDomain.clusters.id)) { $clusterData = (Get-VCFCluster | Where-Object { $_.id -eq ($id) }) $sddcClusterDetails += $clusterData - $sddchostsClusterMapping.($clusterData.name) = $clusterData.hosts.id - $sddcClusterarray += $clusterData.name + $sddcHostsClusterMapping.($clusterData.name) = $clusterData.hosts.id + $sddcClusterArray += $clusterData.name $esxiWorkloadCluster[$clusterData.name] = @() } - Write-PowerManagementLogMessage -Type INFO -Message "Clusters in SDDC Manager database: $($sddcClusterarray -join ",")" + Write-PowerManagementLogMessage -Type INFO -Message "Clusters in SDDC Manager database: $($sddcClusterArray -join ",")" - if($vsanCluster) { - foreach ($name in $userClusterarray) { + if ($vsanCluster) { + foreach ($name in $userClusterArray) { $clusterData = (Get-VCFCluster | Where-Object { $_.name -eq ($name) }) $hostsClusterMapping.($clusterData.name) = $clusterData.hosts.id - #$esxiWorkloadCluster[$clusterData.name] = @() $userClusterDetails += $clusterData } - $ClusterDetails = $userClusterDetails - if (($userClusterDetails.count -eq $sddcClusterDetails.count) -and (((Compare-Object $userClusterDetails $sddcClusterDetails -IncludeEqual | Where-Object -FilterScript {$_.SideIndicator -eq '=='}).InputObject).count -eq $sddcClusterDetails.count)) { + $clusterDetails = $userClusterDetails + if (($userClusterDetails.count -eq $sddcClusterDetails.count) -and (((Compare-Object $userClusterDetails $sddcClusterDetails -IncludeEqual | Where-Object -FilterScript { $_.SideIndicator -eq '==' }).InputObject).count -eq $sddcClusterDetails.count)) { Write-PowerManagementLogMessage -Type INFO -Message "All cluster-related information is correct." $allClusterShutdown = $true } - if(((Compare-Object $sddcClusterarray $userClusterarray -IncludeEqual | Where-Object -FilterScript {$_.SideIndicator -eq '=>'}).InputObject).count){ - $wrongClusterNames = (Compare-Object $sddcClusterarray $userClusterarray -IncludeEqual | Where-Object -FilterScript {$_.SideIndicator -eq '=>'}).InputObject + if (((Compare-Object $sddcClusterArray $userClusterArray -IncludeEqual | Where-Object -FilterScript { $_.SideIndicator -eq '=>' }).InputObject).count) { + $wrongClusterNames = (Compare-Object $sddcClusterArray $userClusterArray -IncludeEqual | Where-Object -FilterScript { $_.SideIndicator -eq '=>' }).InputObject Write-PowerManagementLogMessage -Type WARNING -Message "A wrong cluster name has been passed." Write-PowerManagementLogMessage -Type WARNING -Message "The known clusters, part of this workload domain are:$($sddcClusterDetails.name)" - Write-PowerManagementLogMessage -Type WARNING -Message "The cluster names passed are: $userClusterarray" + Write-PowerManagementLogMessage -Type WARNING -Message "The cluster names passed are: $userClusterArray" Write-PowerManagementLogMessage -Type WARNING -Message "Clusters not matching the SDDC Manager database: $wrongClusterNames" Write-PowerManagementLogMessage -Type ERROR -Message "Please cross check and run the script again. Exiting!" } Write-PowerManagementLogMessage -Type INFO -Message "All clusters to be taken care of: '$allClusterShutdown'" } else { - foreach ($id in $($workloadDomain.clusters.id)) { + foreach ($id in $($workloadDomain.clusters.id)) { $clusterData = (Get-VCFCluster | Where-Object { $_.id -eq ($id) }) $hostsClusterMapping.($clusterData.name) = $clusterData.hosts.id - #$esxiWorkloadCluster[$clusterData.name] = @() } - $ClusterDetails = $sddcClusterDetails + $clusterDetails = $sddcClusterDetails $allClusterShutdown = $true - #$sddcShutdownOrder = $true } # Check the SDDC Manager version if VCF less than or greater than VCF 5.0 - $vcfVersion = Get-VCFManager | select version | Select-String -Pattern '\d+\.\d+' -AllMatches | ForEach-Object {$_.matches.groups[0].value} + $vcfVersion = Get-VCFManager | Select-Object version | Select-String -Pattern '\d+\.\d+' -AllMatches | ForEach-Object { $_.matches.groups[0].value } if ([float]$vcfVersion -lt [float]5.0) { # Gather vCenter Server Details and Credentials $vcServer = (Get-VCFvCenter | Where-Object { $_.domain.id -eq ($workloadDomain.id) }) @@ -236,8 +217,8 @@ Try { # We are using same user name and password for both workload and management vc $mgmtVcServer = (Get-VCFvCenter | Where-Object { $_.domain.id -eq ($managementDomain.id) }) - $mgmtvcUser = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" }).username - $mgmtvcPass = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" }).password + $mgmtVcUser = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" }).username + $mgmtVcPass = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" }).password } else { # Gather Workload vCenter Server Details and Credentials $vcServer = (Get-VCFvCenter | Where-Object { $_.domain.id -eq ($workloadDomain.id) }) @@ -246,42 +227,40 @@ Try { # Gather Management vCenter Server Details and Credentials $mgmtVcServer = (Get-VCFvCenter | Where-Object { $_.domain.id -eq ($managementDomain.id) }) - $mgmtvcUser = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" -and $_.resource.resourceId -eq $($managementDomain.ssoId) }).username - $mgmtvcPass = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" -and $_.resource.resourceId -eq $($managementDomain.ssoId) }).password + $mgmtVcUser = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" -and $_.resource.resourceId -eq $($managementDomain.ssoId) }).username + $mgmtVcPass = (Get-VCFCredential | Where-Object { $_.accountType -eq "SYSTEM" -and $_.credentialType -eq "SSO" -and $_.resource.resourceId -eq $($managementDomain.ssoId) }).password } - #[Array]$allvms = @() - [Array]$vcfvms = @() - [Array]$vcfvms += ($vcServer.fqdn).Split(".")[0] + [Array]$vcfVMs = @() + [Array]$vcfVMs += ($vcServer.fqdn).Split(".")[0] # Gather VxRail Manager details for the VI workload domain, if it exists. if ($PsBoundParameters.ContainsKey("shutdown")) { $vxRailCred = (Get-VCFCredential | Where-Object { $_.resource.resourceType -eq "VXRAIL_MANAGER" -and $_.resource.domainName -eq ($workloadDomain.name) -and $_.username -eq "root" }) - if ($vxRailCred -ne $null) - { - # Connecting to vCenter Server to get the VxRail Manager virtual machine name. - if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue | Out-Null + if ($null -ne $vxRailCred) { + # Connecting to vCenter Server to get the VxRail Manager virtual machine name. + if ($DefaultVIServers) { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue | Out-Null } - if (Test-EndpointConnection -server $vcServer.fqdn -Port 443 ) { + if (Test-EndpointConnection -server $vcServer.fqdn -port 443 ) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$($vcServer.fqdn)' ..." Connect-VIServer -Server $vcServer.fqdn -Protocol https -User $vcUser -Password $vcPass -ErrorVariable $vcConnectError | Out-Null if ($DefaultVIServer.Name -eq $vcServer.fqdn) { - $vxrailVMObject = Get-VM | Where-Object {$_.Guest.Hostname -Match $vxRailCred.resource.resourceName -Or $_.Guest.Hostname -Match ($vxRailCred.resource.resourceName.Split("."))[0]} - if ($vxrailVMObject) { - $vxRailVmName = $vxrailVMObject.Name - } else { - Write-PowerManagementLogMessage -Type ERROR -Message "VxRail($($vxRailCred.resource.resourceName)) Virtual Machine object cannot be located within VC Server ($($vcServer.fqdn))" - } - } - } + $vxrailVMObject = Get-VM | Where-Object { $_.Guest.Hostname -Match $vxRailCred.resource.resourceName -Or $_.Guest.Hostname -Match ($vxRailCred.resource.resourceName.Split("."))[0] } + if ($vxrailVMObject) { + $vxRailVmName = $vxrailVMObject.Name + } else { + Write-PowerManagementLogMessage -Type ERROR -Message "VxRail($($vxRailCred.resource.resourceName)) Virtual Machine object cannot be located within VC Server ($($vcServer.fqdn))" + } + } + } $vxRailDetails = New-Object -TypeName PSCustomObject $vxRailDetails | Add-Member -Type NoteProperty -Name fqdn -Value $vxRailCred.resource.resourceName - $vxRailDetails | Add-Member -Type NoteProperty -Name vmName -Value $vxRailVmName + $vxRailDetails | Add-Member -Type NoteProperty -Name vmName -Value $vxRailVmName $vxRailDetails | Add-Member -Type NoteProperty -Name username -Value $vxRailCred.username $vxRailDetails | Add-Member -Type NoteProperty -Name password -Value $vxRailCred.password - [Array]$vcfvms += ($vxRailDetails.vmName) + [Array]$vcfVMs += ($vxRailDetails.vmName) Write-PowerManagementLogMessage -Type INFO -Message "VxRail Manager($vxRailVmName) found within VC Server ($($vcServer.fqdn))" } else { $vxRailDetails = "" @@ -297,56 +276,50 @@ Try { $esxDetails | Add-Member -Type NoteProperty -Name password -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $esxiHost.fqdn -and $_.accountType -eq "USER" })).password $esxiWorkloadDomain += $esxDetails #Gather ESXi Host to Cluster mapping info for the given VI Workload domain - foreach ($clustername in $sddchostsClusterMapping.keys) { - if ($sddchostsClusterMapping[$clustername] -contains $esxiHost.id) { - $esxiWorkloadCluster[$clustername] += $esxDetails + foreach ($clusterName in $sddcHostsClusterMapping.keys) { + if ($sddcHostsClusterMapping[$clusterName] -contains $esxiHost.id) { + $esxiWorkloadCluster[$clusterName] += $esxDetails } } } if ($PsBoundParameters.ContainsKey("shutdown")) { - foreach ($ClusterName in $sddchostsClusterMapping.keys) { - $name = $ClusterName + foreach ($clusterName in $sddcHostsClusterMapping.keys) { + $name = $clusterName $hostsName = @() - $hostsIds = $sddchostsClusterMapping[$ClusterName] + $hostsIds = $sddcHostsClusterMapping[$clusterName] foreach ($id in $hostsIds) { - $hostsName += (get-vcfhost | where id -eq $id).fqdn + $hostsName += (Get-VCFHost | Where-Object id -EQ $id).fqdn } if ($DefaultVIServers) { Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue | Out-Null } - if ( Test-EndpointConnection -server $vcServer.fqdn -Port 443 ) { + if ( Test-EndpointConnection -server $vcServer.fqdn -port 443 ) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$($vcServer.fqdn)' ..." Connect-VIServer -Server $vcServer.fqdn -Protocol https -User $vcUser -Password $vcPass -ErrorVariable $vcConnectError | Out-Null if ($DefaultVIServer.Name -eq $vcServer.fqdn) { - Write-PowerManagementLogMessage -type INFO -Message "Connected to server '$($vcServer.fqdn)' and trying to get host status..." - $HostsInMaintenanaceOrDisconnectedState = Get-VMHost $hostsName | Where-Object {($_.ConnectionState -eq 'Maintenance') -or ($_.ConnectionState -eq 'NotResponding') -or ($_.ConnectionState -eq 'Disconnected')} - $HostsInConnectedMode = Get-VMHost $hostsName | Where-Object {$_.ConnectionState -eq 'Connected'} - $HostsInDisconnectedMode = Get-VMHost $hostsName | Where-Object {$_.ConnectionState -eq 'Disconnected'} - if ( $HostsInMaintenanaceOrDisconnectedState.count -eq $sddchostsClusterMapping[$ClusterName].count) { - $ClusterStatusMapping[$ClusterName] = 'DOWN' + Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$($vcServer.fqdn)' and trying to get host status..." + $HostsInMaintenanaceOrDisconnectedState = Get-VMHost $hostsName | Where-Object { ($_.ConnectionState -eq 'Maintenance') -or ($_.ConnectionState -eq 'NotResponding') -or ($_.ConnectionState -eq 'Disconnected') } + if ( $HostsInMaintenanaceOrDisconnectedState.count -eq $sddcHostsClusterMapping[$clusterName].count) { + $ClusterStatusMapping[$clusterName] = 'DOWN' } else { - $ClusterStatusMapping[$ClusterName] = 'UP' + $ClusterStatusMapping[$clusterName] = 'UP' } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$($vcServer.fqdn)' has failed. Check the console output for more details." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$($vcServer.fqdn)' has failed. Check your environment and try again" } } } # We will get NSX-T details in the respective startup/shutdown sections below. - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to vCenter Server ($($vcServer.fqdn)). Check your credentials." Exit } -} -Catch { +} Catch { Debug-CatchWriterForPowerManagement -object $_ } @@ -356,78 +329,78 @@ Try { # Get NSX-T Details ## Gather NSX Manager Cluster Details $nsxtCluster = Get-VCFNsxtCluster -id $workloadDomain.nsxtCluster.id - $nsxtMgrfqdn = $nsxtCluster.vipFqdn - $nsxMgrVIP = New-Object -TypeName PSCustomObject - $nsxMgrVIP | Add-Member -Type NoteProperty -Name adminUser -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtMgrfqdn -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).username - $nsxMgrVIP | Add-Member -Type NoteProperty -Name adminPassword -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtMgrfqdn -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).password - $nsxtNodesfqdn = $nsxtCluster.nodes.fqdn + $nsxtManagerFQDN = $nsxtCluster.vipFqdn + $nsxtManagerVIP = New-Object -TypeName PSCustomObject + $nsxtManagerVIP | Add-Member -Type NoteProperty -Name adminUser -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtManagerFQDN -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).username + $nsxtManagerVIP | Add-Member -Type NoteProperty -Name adminPassword -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtManagerFQDN -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).password + $nsxtNodesFQDN = $nsxtCluster.nodes.fqdn $nsxtNodes = @() - foreach ($node in $nsxtNodesfqdn) { + foreach ($node in $nsxtNodesFQDN) { [Array]$nsxtNodes += $node.Split(".")[0] - [Array]$vcfvms += $node.Split(".")[0] + [Array]$vcfVMs += $node.Split(".")[0] } Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch information about all powered-on vCLS virtual machines from vCenter Server $($vcServer.fqdn)..." - [Array]$vclsvms += Get-VMsWithPowerStatus -server $vcServer.fqdn -user $vcUser -pass $vcPass -powerstate "poweredon"-pattern "(^vCLS-\w{8}-\w{4}-\w{4}-\w{4}-\w{12})|(^vCLS\s*\(\d+\))|(^vCLS\s*$)" -silence - foreach ($vm in $vclsvms) { - [Array]$vcfvms += $vm + [Array]$vclsVMs += Get-VMsWithPowerStatus -server $vcServer.fqdn -user $vcUser -pass $vcPass -powerstate "poweredon"-pattern "(^vCLS-\w{8}-\w{4}-\w{4}-\w{4}-\w{12})|(^vCLS\s*\(\d+\))|(^vCLS\s*$)" -silence + foreach ($vm in $vclsVMs) { + [Array]$vcfVMs += $vm } Write-PowerManagementLogMessage -Type INFO -Message "Fetching all powered on vSAN File Services virtual machines from vCenter Server instance $($vcenter)..." - [Array]$vsanfsvms += Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -pattern "(vSAN File)" -silence - foreach ($vm in $vsanfsvms) { - [Array]$vcfvms += $vm + [Array]$vsanFsVMs += Get-VMsWithPowerStatus -powerstate "poweredon" -server $vcServer.fqdn -user $vcUser -pass $vcPass -pattern "(vSAN File)" -silence + foreach ($vm in $vsanFsVMs) { + [Array]$vcfVMs += $vm } #Check if NSX-T manager VMs are running. If they are stopped skip NSX-T edge shutdown - $nsxManagerPowerOnVMs = 0 + $nsxtManagerPowerOnVMs = 0 foreach ($nsxtManager in $nsxtNodes) { - $state = Get-VMsWithPowerStatus -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -pattern $nsxtManager -exactMatch -powerstate "poweredon" - if ($state) { $nsxManagerPowerOnVMs += 1 } + $state = Get-VMsWithPowerStatus -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -pattern $nsxtManager -exactMatch -powerstate "poweredon" + if ($state) { $nsxtManagerPowerOnVMs += 1 } # If we have all NSX-T managers running or minimum of 2 nodes up - query NSX-T for edges. - if (($nsxManagerPowerOnVMs -eq $nsxtNodes.count) -or ($nsxManagerPowerOnVMs -eq 2)) { + if (($nsxtManagerPowerOnVMs -eq $nsxtNodes.count) -or ($nsxtManagerPowerOnVMs -eq 2)) { $statusOfNsxtClusterVMs = 'running' } } - $nxtClusterEdgeNodes = @() + $nsxtClusterEdgeNodes = @() if ($statusOfNsxtClusterVMs -ne 'running') { Write-PowerManagementLogMessage -Type WARNING -Message "The NSX Manager VMs have been stopped. The NSX Edge VMs will not be handled in an automatic way." - } - else { + Write-PowerManagementLogMessage -Type WARNING -Message "The NSX Manager VMs have been stopped. We could not check if this NSX Manager is spanned across Workload Domains." + } else { Try { - [Array]$nsxtEdgeNodes = Get-EdgeNodeFromNSXManager -server $nsxtMgrfqdn -user $nsxMgrVIP.adminUser -pass $nsxMgrVIP.adminPassword -VCfqdn $vcServer.fqdn + [Array]$nsxtEdgeNodes = Get-EdgeNodeFromNSXManager -server $nsxtManagerFQDN -user $nsxtManagerVIP.adminUser -pass $nsxtManagerVIP.adminPassword -VCfqdn $vcServer.fqdn foreach ($node in $nsxtEdgeNodes) { - [Array]$vcfvms += $node + [Array]$vcfVMs += $node } + } Catch { + Write-PowerManagementLogMessage -Type ERROR -Message "Something went wrong! Unable to fetch NSX Edge node information from NSX Manager '$nsxtManagerFQDN'. Exiting!" } - catch { - Write-PowerManagementLogMessage -Type ERROR -Message "Something went wrong! Unable to fetch NSX Edge node information from NSX Manager '$nsxtMgrfqdn'. Exiting!" - } - } - $vcfvms_string = $vcfvms -join "; " + # This variable holds True of False based on if NSX is spanned across workloads or not. + $nsxtSpannedAcrossWldVc = Get-NSXTComputeManagers -server $nsxtManagerFQDN -user $nsxtManagerVIP.adminUser -pass $nsxtManagerVIP.adminPassword + $NSXTSpannedAcrossWld = $nsxtSpannedAcrossWldVc.count -gt 1 + } - # This variable holds True of False based on if NSX is spanned across workloads or not. - $NSXTSpannedAcrossWldVCArray = Get-NSXTComputeManagers -server $nsxtMgrfqdn -user $nsxMgrVIP.adminUser -pass $nsxMgrVIP.adminPassword - $NSXTSpannedAcrossWld = $NSXTSpannedAcrossWldVCArray.count -gt 1 + $vcfVMs_string = $vcfVMs -join "; " # From here the looping of all clusters begin. $count = $sddcClusterDetails.count $index = 1 $DownCount = 0 - $lastelement = $false - + $lastElement = $false - foreach ($cluster in $ClusterDetails) { - foreach ($clusterdetail in $sddcClusterDetails) { - if ($ClusterStatusMapping[$clusterdetail.name] -eq 'DOWN') { + # TODO Add check if clusters are vSAN or not. + # TODO Add support for non-vSAN clusters. + foreach ($cluster in $clusterDetails) { + foreach ($clusterDetail in $sddcClusterDetails) { + if ($ClusterStatusMapping[$clusterDetail.name] -eq 'DOWN') { $DownCount += 1 } } - if (($DownCount -eq ($count -1)) -or ($DownCount -eq $count) ) { - $lastelement = $true - Write-PowerManagementLogMessage -Type INFO -Message "Last cluster of VSAN detected" + if (($DownCount -eq ($count - 1)) -or ($DownCount -eq $count) ) { + $lastElement = $true + Write-PowerManagementLogMessage -Type INFO -Message "Last cluster of VSAN detected" } if ($ClusterStatusMapping[$cluster.name] -eq 'DOWN') { @@ -435,13 +408,15 @@ Try { Continue } + Write-PowerManagementLogMessage -Type INFO -Message "Processing cluster '$($cluster.name)'..." + $esxiDetails = $esxiWorkloadCluster[$cluster.name] # Check the SDDC Manager version if VCF >=4.5 or vcf4.5 - $vcfVersion = Get-VCFManager | select version | Select-String -Pattern '\d+\.\d+' -AllMatches | ForEach-Object {$_.matches.groups[0].value} + $vcfVersion = Get-VCFManager | Select-Object version | Select-String -Pattern '\d+\.\d+' -AllMatches | ForEach-Object { $_.matches.groups[0].value } if ([float]$vcfVersion -lt [float]4.5) { # For versions prior VCF 4.5 - # Check if SSH is enabled on the esxi hosts before proceeding with startup procedure + # Check if SSH is enabled on the esxi hosts before proceeding with shutdown procedure Try { foreach ($esxiNode in $esxiWorkloadDomain) { if (Test-VsphereConnection -server $esxiNode) { @@ -455,13 +430,13 @@ Try { Exit } } - } catch { + } Catch { Write-PowerManagementLogMessage -Type ERROR -Message $_.Exception.Message Exit } } else { foreach ($esxiNode in $esxiDetails) { - if (!(Test-EndpointConnection -server $esxiNode.fqdn -Port 443)) { + if (!(Test-EndpointConnection -server $esxiNode.fqdn -port 443)) { Write-PowerManagementLogMessage -Type ERROR -Message "Unable to communicate with ESXi host $($esxiNode.fqdn). Check the FQDN or IP address, or the power state. Exiting..." Exit } @@ -478,6 +453,7 @@ Try { $clusterVcfVMs = @() $clusterVclsVMs = @() + # TODO If not specific cluster is passed - we should check for customer VMs in all clusters. In this way we will fail early if there are some VMs running and not managed by VCF. Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch information about all powered-on virtual machines for the specified vSphere cluster $($cluster.name)..." [Array]$clusterAllVMs = Get-VMToClusterMapping -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -folder "VM" -powerstate "poweredon" Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch information about all powered-on vCLS virtual machines for a the specified vSphere cluster $($cluster.name)..." @@ -490,8 +466,8 @@ Try { if ($nsxtEdgeNodes) { foreach ($node in $nsxtEdgeNodes) { foreach ($element in $clusterAllVMs) { - if( $element -like $node) { - $nxtClusterEdgeNodes += $node + if ( $element -like $node) { + $nsxtClusterEdgeNodes += $node [Array]$clusterVcfVMs += $node break } @@ -499,7 +475,7 @@ Try { } } Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch information about all powered-on customer virtual machines for the specified vSphere cluster $($cluster.name)..." - $clusterCustomerVMs = $clusterAllVMs | Where-Object { $vcfvms -notcontains $_ } + $clusterCustomerVMs = $clusterAllVMs | Where-Object { $vcfVMs -NotContains $_ } $clusterVcfVMs_string = $clusterVcfVMs -join "; " Write-PowerManagementLogMessage -Type INFO -Message "Management virtual machines covered by the script for the cluster $($cluster.name): '$($clusterVcfVMs_string)' ." if ($clusterCustomerVMs.count -ne 0) { @@ -514,23 +490,21 @@ Try { if ($DefaultVIServers) { Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue | Out-Null } - if ( Test-EndpointConnection -server $vcServer.fqdn -Port 443 ) { + if ( Test-EndpointConnection -server $vcServer.fqdn -port 443 ) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$($vcServer.fqdn)' ..." Connect-VIServer -Server $vcServer.fqdn -Protocol https -User $vcUser -Password $vcPass -ErrorVariable $vcConnectError | Out-Null if ($DefaultVIServer.Name -eq $vcServer.fqdn) { - Write-PowerManagementLogMessage -type INFO -Message "Connected to server '$($vcServer.fqdn)' and trying to get VMware Tools status." + Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$($vcServer.fqdn)' and trying to get VMware Tools status." foreach ($vm in $clusterCustomerVMs) { - Write-PowerManagementLogMessage -type INFO -Message "Checking VMware Tools status for '$vm'..." + Write-PowerManagementLogMessage -Type INFO -Message "Checking VMware Tools status for '$vm'..." $vm_data = Get-VM -Name $vm if ($vm_data.ExtensionData.Guest.ToolsRunningStatus -eq "guestToolsRunning") { [Array]$VMwareToolsRunningVMs += $vm - } - else { + } else { [Array]$VMwareToolsNotRunningVMs += $vm } } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot to connect to vCenter Server '$($vcServer.fqdn)'. The command returned the following error: '$vcConnectError'." } } @@ -563,15 +537,13 @@ Try { } ## Gather NSX Edge Node Details from NSX-T Manager - if (Test-EndpointConnection -server $vcServer.fqdn -Port 443) { - if ($nxtClusterEdgeNodes) { - Stop-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $nxtClusterEdgeNodes -timeout 600 - } - else { + if (Test-EndpointConnection -server $vcServer.fqdn -port 443) { + if ($nsxtClusterEdgeNodes) { + Stop-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $nsxtClusterEdgeNodes -timeout 600 + } else { Write-PowerManagementLogMessage -Type WARNING -Message "No NSX Edge nodes found for a given cluster '$($cluster.name)' . Skipping edge nodes shutdown..." } - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "'$($vcServer.fqdn)' might already be shut down. Skipping shutdown of $nsxtEdgeNodes..." } @@ -580,39 +552,38 @@ Try { # Get info if NSX Manager is spanned across workloads # Check if it is the last cluster of the domain to shutdown # The below condition tells that we need to go ahead with NSX-T shutdown only under - $allothervcdown = $true + $allOtherVcDown = $true if ($NSXTSpannedAcrossWld) { - foreach ($VCnode in $NSXTSpannedAcrossWldVCArray) { + foreach ($VCnode in $nsxtSpannedAcrossWldVc) { if ($VCnode -eq ($vcServer.fqdn)) { continue } else { - $checkServer = (Test-EndpointConnection -server $VCnode -Port 443) + $checkServer = (Test-EndpointConnection -server $VCnode -port 443) if ($checkServer) { - $allothervcdown = $false + $allOtherVcDown = $false break } } } - if (-not $allothervcdown) { + if (-not $allOtherVcDown) { Write-PowerManagementLogMessage -Type WARNING -Message "NSX Manager is shared across workload domains. Some of the vCenter Server instances for these workload domains are still running. Hence, not shutting down NSX Manager at this point." } else { - if ($lastelement) { - Stop-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -nodes $nsxtNodes -timeout 600 + if ($lastElement) { + Stop-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -nodes $nsxtNodes -timeout 600 } } } else { - if ($lastelement) { - Stop-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -nodes $nsxtNodes -timeout 600 + if ($lastElement) { + Stop-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -nodes $nsxtNodes -timeout 600 } } ## The below block was supposed to be only for verison < 4.5, but due to the bug in 4.5 ## vcls vms are not handled automatically though expected in vcf4.5 ## Shut Down the vSphere Cluster Services Virtual Machines in the Virtual Infrastructure Workload Domain - if (Test-EndpointConnection -server $vcServer.fqdn -Port 443) { + if (Test-EndpointConnection -server $vcServer.fqdn -port 443) { Set-Retreatmode -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -mode enable - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "'$($vcServer.fqdn)' might already be shut down. Skipping putting the cluster in retreat mode..." } @@ -627,8 +598,7 @@ Try { Write-PowerManagementLogMessage -Type INFO -Message "Some vCLS VMs are still running. Sleeping for $sleepTime seconds until next check..." Start-Sleep -s $sleepTime $counter += 1 - } - else { + } else { Break } } @@ -638,11 +608,11 @@ Try { } # Check the health and sync status of the vSAN cluster - if (Test-EndpointConnection -server $vcServer.fqdn -Port 443) { + if (Test-EndpointConnection -server $vcServer.fqdn -port 443) { if ([float]$vcfVersion -gt [float]4.4) { $RemoteVMs = @() $RemoteVMs = Get-poweronVMsOnRemoteDS -server $vcServer.fqdn -user $vcUser -pass $vcPass -clustertocheck $cluster.name - if($RemoteVMs.count -eq 0) { + if ($RemoteVMs.count -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "All remote VMs are powered off." } else { Write-PowerManagementLogMessage -Type ERROR -Message "Not all remote VMs are powered off : $($RemoteVMs.Name), Unable to proceed. Please stop the VMs running on vSAN HCI Mesh datastore shared by this cluster." @@ -650,8 +620,7 @@ Try { } if ( (Test-VsanHealth -cluster $cluster.name -server $vcServer.fqdn -user $vcUser -pass $vcPass) -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "vSAN health is good." - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "The vSAN cluster isn't in a healthy state. Check the vSAN health status in vCenter Server '$($vcServer.fqdn)'. After vSAN health is restored, run the script again." Write-PowerManagementLogMessage -Type WARNING -Message "If the script execution has reached ESXi vSAN shutdown previously, this warning is expected. Please continue by following the documentation of VMware Cloud Foundation. " Write-PowerManagementLogMessage -Type ERROR -Message "The vSAN cluster isn't in a healthy state. Check the messages above for a solution." @@ -659,13 +628,11 @@ Try { } if ( (Test-VsanObjectResync -cluster $cluster.name -server $vcServer.fqdn -user $vcUser -pass $vcPass) -eq 0) { # Write-PowerManagementLogMessage -Type INFO -Message "vSAN object resynchronization is successful." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "There is an active vSAN object resynchronization operation. Check your environment and run the script again." Exit } - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "'$($vcServer.fqdn)' might already be shut down. Skipping the vSAN health check for cluster $($cluster.name)." } @@ -676,17 +643,16 @@ Try { } else { $runningAllVMs = Get-VMToClusterMapping -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -folder "vm" -powerstate "poweredon" -silence $runningVclsVMs = Get-VMToClusterMapping -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -folder "vcls" -powerstate "poweredon" -silence - $runningVMs = $runningAllVMs | ? { $runningVclsVMs -notcontains $_ } - if($vxRailDetails -ne "") { - $runningVMs = $runningAllVMs | ? { $vcfvms -notcontains $_ } + $runningVMs = $runningAllVMs | Where-Object { $runningVclsVMs -NotContains $_ } + if ($vxRailDetails -ne "") { + $runningVMs = $runningAllVMs | Where-Object { $vcfVMs -NotContains $_ } } } if ($runningVMs.count) { Write-PowerManagementLogMessage -Type WARNING -Message "Some VMs are still in powered-on state." Write-PowerManagementLogMessage -Type WARNING -Message "Cannot proceed until all VMs are shut down. Shut them down manually and run the script again." Write-PowerManagementLogMessage -Type ERROR -Message "The environment has running VMs: $($runningVMs). Could not continue with vSAN shutdown while there are running VMs. Exiting! " - } - else { + } else { if ([float]$vcfVersion -lt [float]4.5) { # Stop vSphere HA to avoid "orphaned" VMs during vSAN shutdown @@ -709,18 +675,18 @@ Try { Set-MaintenanceMode -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password -state ENABLE } - ## TODO Add ESXi shutdown here + ## TODO Add ESXi shutdown here } else { # Check if hosts are in maintainence mode before cluster stop foreach ($esxiNode in $esxiDetails) { - $HostConnectionState = Get-MaintenanceMode -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password - if ($HostConnectionState -eq "Maintenance") { + $hostConnectionState = Get-MaintenanceMode -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password + if ($hostConnectionState -eq "Maintenance") { Write-PowerManagementLogMessage -Type ERROR -Message "$($esxiNode.fqdn) is in maintenance mode before cluster shutdown. Automation could not proceed. Check the vSphere Client for more details ." Exit } } - $esxiDetails = $esxiWorkloadCluster[$cluster.name] + $esxiDetails = $esxiWorkloadCluster[$cluster.name] # vSAN or VxRail Manager shutdown wizard automation. if ($vxRailDetails -ne "") { @@ -733,16 +699,16 @@ Try { $sleepTime = 60 # in seconds while ($counter -lt 1800) { - $successcount = 0 + $successCount = 0 #Verify if all ESXi hosts are down in here to conclude End of Shutdown sequence foreach ($esxiNode in $esxiDetails) { - if (Test-EndpointConnection -server $esxiNode.fqdn -Port 443) { + if (Test-EndpointConnection -server $esxiNode.fqdn -port 443) { Write-PowerManagementLogMessage -Type WARNING -Message "$($esxiNode.fqdn) is still up. Sleeping for $sleepTime seconds before next check..." } else { - $successcount++ + $successCount++ } } - if ($successcount -eq $esxiDetails.count) { + if ($successCount -eq $esxiDetails.count) { Write-PowerManagementLogMessage -Type INFO -Message "All Hosts have been shutdown successfully!" Write-PowerManagementLogMessage -Type INFO -Message "End of the shutdown sequence!" Exit @@ -755,15 +721,15 @@ Try { # vSAN shutdown wizard automation. Set-VsanClusterPowerStatus -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -PowerStatus clusterPoweredOff foreach ($esxiNode in $esxiDetails) { - if (Test-EndpointConnection -server $esxiNode.fqdn -Port 443) { + if (Test-EndpointConnection -server $esxiNode.fqdn -port 443) { Write-PowerManagementLogMessage -Type ERROR -Message "$($esxiNode.fqdn) is still up. Check the FQDN or IP address, or the power state of the '$($esxiNode.fqdn)'." Exit } } } } - if ($lastelement) { - Stop-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -nodes $vcServer.fqdn.Split(".")[0] -timeout 600 + if ($lastElement) { + Stop-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -nodes $vcServer.fqdn.Split(".")[0] -timeout 600 } $ClusterStatusMapping[$cluster.name] = 'DOWN' @@ -781,9 +747,8 @@ Try { } } $index += 1 - } -} -Catch { + } +} Catch { Debug-CatchWriterForPowerManagement -object $_ } @@ -796,12 +761,12 @@ Try { if ($PsBoundParameters.ContainsKey("startup")) { - $nsxMgrVIP = New-Object -TypeName PSCustomObject - $nsxtMgrfqdn = "" + $nsxtManagerVIP = New-Object -TypeName PSCustomObject + $nsxtManagerFQDN = "" $count = $sddcClusterDetails.count - $vcfVersion = Get-VCFManager | select version | Select-String -Pattern '\d+\.\d+' -AllMatches | ForEach-Object {$_.matches.groups[0].value} + $vcfVersion = Get-VCFManager | Select-Object version | Select-String -Pattern '\d+\.\d+' -AllMatches | ForEach-Object { $_.matches.groups[0].value } if ([float]$vcfVersion -lt [float]4.5) { - foreach ($cluster in $ClusterDetails) { + foreach ($cluster in $clusterDetails) { $esxiDetails = $esxiWorkloadCluster[$cluster.name] # Check if SSH is enabled on the esxi hosts before proceeding with startup procedure Try { @@ -812,8 +777,7 @@ Try { Exit } } - } - catch { + } Catch { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot open an SSH connection to host $($esxiNode.fqdn), If SSH is not enabled, follow the steps in the documentation to enable it." } @@ -823,19 +787,19 @@ Try { } } - foreach ($cluster in $ClusterDetails) { + foreach ($cluster in $clusterDetails) { # Prepare the vSAN cluster for startup - Performed on a single host only $esxiDetails = $esxiWorkloadCluster[$cluster.name] Invoke-EsxCommand -server $esxiDetails.fqdn[0] -user $esxiDetails.username[0] -pass $esxiDetails.password[0] -expected "Cluster reboot/poweron is completed successfully!" -cmd "python /usr/lib/vmware/vsan/bin/reboot_helper.py recover" } - foreach ($cluster in $ClusterDetails) { + foreach ($cluster in $clusterDetails) { # Enable vSAN cluster member updates $esxiDetails = $esxiWorkloadCluster[$cluster.name] foreach ($esxiNode in $esxiDetails) { Invoke-EsxCommand -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password -expected "Value of IgnoreClusterMemberListUpdates is 0" -cmd "esxcfg-advcfg -s 0 /VSAN/IgnoreClusterMemberListUpdates" } } - foreach ($cluster in $ClusterDetails) { + foreach ($cluster in $clusterDetails) { # Check ESXi status for each host Write-PowerManagementLogMessage -Type INFO -Message "Checking the vSAN status of the ESXi hosts...." $esxiDetails = $esxiWorkloadCluster[$cluster.name] @@ -844,16 +808,18 @@ Try { } } } - foreach ($cluster in $ClusterDetails) { + foreach ($cluster in $clusterDetails) { $esxiDetails = $esxiWorkloadCluster[$cluster.name] - # We are starting all vCenter Servers, since we need to get NSX details. SDDC Manager needs VC connection to build this knowlage - Write-PowerManagementLogMessage -Type INFO -Message "Trying to see if all vCenter Servers in a workload domain are already started" - $service_status = 0 + # TODO - Do not run this for each cluster - we need to run it once per WLD. + # We are starting all vCenter Servers, since we need to get NSX details. SDDC Manager needs VC connection to build this knowledge. + # NSX Manager should be started after the VC, so if NSX manager is spanned across WLDs, we need to start all VCs. + Write-PowerManagementLogMessage -Type INFO -Message "Checking if all vCenter Servers in all workload domains are started." + $serviceStatus = 0 foreach ($wldVC in $allWldVCs) { - $VcStarted = (Get-VMsWithPowerStatus -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -powerstate "poweredon" -pattern $wldVC.Split(".")[0] -silence).count - if (-not $VcStarted) { + $vcStarted = (Get-VMsWithPowerStatus -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -powerstate "poweredon" -pattern $wldVC.Split(".")[0] -silence).count + if (-not $vcStarted) { # Startup the Virtual Infrastructure Workload Domain vCenter Server - Start-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -nodes $wldVC.Split(".")[0] -timeout 600 + Start-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -nodes $wldVC.Split(".")[0] -timeout 600 Write-PowerManagementLogMessage -Type INFO -Message "Waiting for the vCenter Server services to start on '$($wldVC.Split(".")[0])'. It will take some time." } else { Write-PowerManagementLogMessage -Type INFO -Message "vCenter Server '$($wldVC.Split(".")[0])' is already started" @@ -863,16 +829,15 @@ Try { Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue | Out-Null } While ($retries) { - Connect-VIServer -server $wldVC -user $vcUser -pass $vcPass -ErrorAction SilentlyContinue | Out-Null + Connect-VIServer -Server $wldVC -User $vcUser -pass $vcPass -ErrorAction SilentlyContinue | Out-Null if ($DefaultVIServer.Name -eq $wldVC) { # Max wait time for services to come up is 10 mins. for ($i = 0; $i -le 10; $i++) { - $status = Get-VAMIServiceStatus -server $wldVC -user $vcUser -pass $vcPass -service 'vsphere-ui' -nolog + $status = Get-VamiServiceStatus -server $wldVC -user $vcUser -pass $vcPass -service 'vsphere-ui' -nolog if ($status -eq "STARTED") { - $service_status += 1 + $serviceStatus += 1 break - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "The services on vCenter Server $wldVC are still starting. Please wait." Start-Sleep -s 60 } @@ -880,9 +845,9 @@ Try { if (([float]$vcfVersion -lt [float]4.5) -and ($wldVC -eq $vcServer.fqdn)) { # Workaround for ESXis that do not communicate their Maintenance status to vCenter Server foreach ($esxiNode in $esxiDetails) { - if ((Get-VMHost -name $esxiNode.fqdn).ConnectionState -eq "Maintenance") { - write-PowerManagementLogMessage -Type INFO -Message "Performing exit maintenance mode on '$($esxiNode.fqdn)' from vCenter Server." - (Get-VMHost -name $esxiNode.fqdn | Get-View).ExitMaintenanceMode_Task(0) | Out-Null + if ((Get-VMHost -Name $esxiNode.fqdn).ConnectionState -eq "Maintenance") { + Write-PowerManagementLogMessage -Type INFO -Message "Performing exit maintenance mode on '$($esxiNode.fqdn)' from vCenter Server." + (Get-VMHost -Name $esxiNode.fqdn | Get-View).ExitMaintenanceMode_Task(0) | Out-Null } } } @@ -895,37 +860,36 @@ Try { } } - if ($service_status -eq $allWldVCs.count) { + if ($serviceStatus -eq $allWldVCs.count) { Write-PowerManagementLogMessage -Type INFO -Message "vCenter Server has been started successfully." if ([float]$vcfVersion -gt [float]4.4) { #Start ESXi hosts here - Write-Host ""; - $WarningString = "" + # TODO - Check if this workaround is needed for VCF 5.1 and newer. + Write-Host "" + $warningString = "" if ($sddcClusterDetails.count -eq 1) { - $WarningString = "==========================================================`n" - $WarningString += "Please start all the ESXi hosts belonging to the cluster '$($cluster.name)' and wait for the host console to come up. Once done, please enter yes`n" - $WarningString += "==========================================================`n" + $warningString = "==========================================================`n" + $warningString += "Please start all the ESXi hosts belonging to the cluster '$($cluster.name)' and wait for the host console to come up. Once done, please enter yes`n" + $warningString += "==========================================================`n" } else { - $WarningString = "==========================================================`n" - $WarningString += "1) Please start all the ESXi hosts belonging to the cluster '$($cluster.name)'`n" - $WarningString += "2) Also, verify that 'Restart cluster' option(Right-click the cluster and navigate to vSAN) is available in vSphere UI for the cluster '$($cluster.name)'.`n" - $WarningString += "3) If it is not available, refer scenario 3 in https://kb.vmware.com/s/article/87350 and perform its workaround as mentioned'`n" - $WarningString += "Once all the above points are taken care, please enter yes`n" - $WarningString += "==========================================================`n" + $warningString = "==========================================================`n" + $warningString += "1) Please start all the ESXi hosts belonging to the cluster '$($cluster.name)'`n" + $warningString += "2) Also, verify that 'Restart cluster' option(Right-click the cluster and navigate to vSAN) is available in vSphere UI for the cluster '$($cluster.name)'.`n" + $warningString += "3) If it is not available, refer scenario 3 in https://kb.vmware.com/s/article/87350 and perform its workaround as mentioned'`n" + $warningString += "Once all the above points are taken care, please enter yes`n" + $warningString += "==========================================================`n" } - $proceed = Read-Host $WarningString + $proceed = Read-Host $warningString if (-Not $proceed) { Write-PowerManagementLogMessage -Type WARNING -Message "None of the options is selected. Default is 'No', hence stopping script execution." Exit - } - else { + } else { if (($proceed -match "no") -or ($proceed -match "yes")) { if ($proceed -match "no") { Write-PowerManagementLogMessage -Type WARNING -Message "Stopping script execution because the input is 'No'." Exit } - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "Pass the right string - either 'Yes' or 'No'." Exit } @@ -933,7 +897,7 @@ Try { $esxiDetails = $esxiWorkloadCluster[$cluster.name] foreach ($esxiNode in $esxiDetails) { - if (!(Test-EndpointConnection -server $esxiNode.fqdn -Port 443)) { + if (!(Test-EndpointConnection -server $esxiNode.fqdn -port 443)) { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot communicate with the host $($esxiNode.fqdn). Check the FQDN or IP address, or the power state of '$($esxiNode.fqdn)'." Exit } @@ -942,12 +906,13 @@ Try { # Check if Lockdown Mode is enabled on ESXi hosts Test-LockdownMode -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name # Start vSAN Cluster wizard + # TODO - Add check if the cluster is vSAN or not. Set-VsanClusterPowerStatus -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -PowerStatus clusterPoweredOn - # Check if host are out of maintainence mode after cluster restart + # Check if host are out of maintenance mode after cluster restart foreach ($esxiNode in $esxiDetails) { - $HostConnectionState = Get-MaintenanceMode -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password - if ($HostConnectionState -eq "Maintenance") { + $hostConnectionState = Get-MaintenanceMode -server $esxiNode.fqdn -user $esxiNode.username -pass $esxiNode.password + if ($hostConnectionState -eq "Maintenance") { Write-PowerManagementLogMessage -Type ERROR -Message "$($esxiNode.fqdn) is still in maintenance mode even after cluster restart. Check the vSphere Client and take the necessary actions." Exit } @@ -955,16 +920,14 @@ Try { } if ((Test-VsanHealth -cluster $cluster.name -server $vcServer.fqdn -user $vcUser -pass $vcPass) -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "Cluster health is good." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "The cluster isn't in a healthy state. Check your environment and run the script again." Exit } # Check the health and sync status of the vSAN cluster if ((Test-VsanObjectResync -cluster $cluster.name -server $vcServer.fqdn -user $vcUser -pass $vcPass) -eq 0) { # Write-PowerManagementLogMessage -Type INFO -Message "vSAN object resynchronization is successful." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "vSAN object resynchronization has failed. Check your environment and run the script again." Exit } @@ -975,21 +938,21 @@ Try { Write-PowerManagementLogMessage -Type ERROR -Message "Could not enable vSphere High Availability for cluster '$cluster'. Exiting!" } } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Some of the vCenter Server instances are not started. Check the vSphere Client for more details and run the script again after all vCenter Server instances are up and running." Exit } } # Workaround for IAM service not starting vCLS VMs - foreach ($cluster in $ClusterDetails) { + # TODO Check if this is still required for VCF 5.1 and newer. This workaround have an issue with Non vSAN Clusters. + foreach ($cluster in $clusterDetails) { # Startup vSphere Cluster Services Virtual Machines in Virtual Infrastructure Workload Domain - Set-Retreatmode -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -mode disable + Set-RetreatMode -server $vcServer.fqdn -user $vcUser -pass $vcPass -cluster $cluster.name -mode disable Write-PowerManagementLogMessage -Type INFO -Message "vCLS retreat mode has been set. vCLS startup will take some time. Please wait! " } $index = 1 - foreach ($cluster in $ClusterDetails) { + foreach ($cluster in $clusterDetails) { # Waiting for vCLS VMs to be started for ($retries*10) seconds $counter = 0 $retries = 30 @@ -1000,8 +963,7 @@ Try { Write-PowerManagementLogMessage -Type INFO -Message "There are $powerOnVMcount vCLS virtual machines running. Sleeping for $sleepTime seconds until the next check..." Start-Sleep -s $sleepTime $counter += 1 - } - else { + } else { Break } } @@ -1018,15 +980,15 @@ Try { foreach ($vm in $clusterVclsVMs) { [Array]$clusterVcfVMs += $vm } - $vcfvms += $vcServer.fqdn.Split(".")[0] + $vcfVMs += $vcServer.fqdn.Split(".")[0] $clusterVcfVMs += $vcServer.fqdn.Split(".")[0] Write-PowerManagementLogMessage -Type INFO -Message "Trying to fetch information about customer virtual machines for the specified vSphere cluster $($cluster.name)..." - $clusterCustomerVMs = $clusterAllVMs | Where-Object { $vcfvms -notcontains $_ } + $clusterCustomerVMs = $clusterAllVMs | Where-Object { $vcfVMs -NotContains $_ } if ($index -eq 1) { # Get fresh token from SDDC manager - $StatusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg - if ($StatusMsg) { Write-PowerManagementLogMessage -Type INFO -Message $StatusMsg } if ($WarnMsg) { Write-PowerManagementLogMessage -Type WARNING -Message $WarnMsg } if ($ErrorMsg) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } + $statusMsg = Request-VCFToken -fqdn $server -username $user -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue -WarningVariable WarnMsg -ErrorVariable ErrorMsg + if ($statusMsg) { Write-PowerManagementLogMessage -Type INFO -Message $statusMsg } if ($warnMsg) { Write-PowerManagementLogMessage -Type WARNING -Message $warnMsg } if ($ErrorMsg) { Write-PowerManagementLogMessage -Type ERROR -Message $ErrorMsg } # Get NSX-T Details once VC is started ## Gather NSX Manager Cluster Details @@ -1036,8 +998,7 @@ Try { while ($counter -ne $retries) { Try { $nsxtCluster = Get-VCFNsxtCluster -id $workloadDomain.nsxtCluster.id -ErrorAction SilentlyContinue -InformationAction Ignore - } - Catch { + } Catch { Write-PowerManagementLogMessage -Type INFO -Message "SDDC Manager is still retrieving NSX-T Data Center information. Sleeping for $sleepTime seconds until the next check..." Start-Sleep -s $sleepTime $counter += 1 @@ -1054,28 +1015,28 @@ Try { Write-PowerManagementLogMessage -Type ERROR -Message "SDDC Manager did not manage to retrieve NSX-T Data Center information. Please check the LCM log file for errors. Stopping the script execution!" Exit } - $nsxtMgrfqdn = $nsxtCluster.vipFqdn + $nsxtManagerFQDN = $nsxtCluster.vipFqdn - $nsxMgrVIP | Add-Member -Force -Type NoteProperty -Name adminUser -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtMgrfqdn -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).username - $nsxMgrVIP | Add-Member -Force -Type NoteProperty -Name adminPassword -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtMgrfqdn -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).password - $nsxtNodesfqdn = $nsxtCluster.nodes.fqdn + $nsxtManagerVIP | Add-Member -Force -Type NoteProperty -Name adminUser -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtManagerFQDN -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).username + $nsxtManagerVIP | Add-Member -Force -Type NoteProperty -Name adminPassword -Value (Get-VCFCredential | Where-Object ({ $_.resource.resourceName -eq $nsxtManagerFQDN -and $_.resource.domainName -eq $sddcDomain -and $_.credentialType -eq "API" })).password + $nsxtNodesFQDN = $nsxtCluster.nodes.fqdn $nsxtNodes = @() - foreach ($node in $nsxtNodesfqdn) { + foreach ($node in $nsxtNodesFQDN) { [Array]$nsxtNodes += $node.Split(".")[0] - [Array]$vcfvms += $node.Split(".")[0] + [Array]$vcfVMs += $node.Split(".")[0] [Array]$clusterVcfVMs += $node.Split(".")[0] } - $NsxtStarted = 0 + $nsxtStarted = 0 foreach ($node in $nsxtNodes) { Write-PowerManagementLogMessage -Type INFO -Message "Checking if $node is already started." - $NsxtStarted += (Get-VMsWithPowerStatus -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -powerstate "poweredon" -pattern $node -silence).count + $nsxtStarted += (Get-VMsWithPowerStatus -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -powerstate "poweredon" -pattern $node -silence).count } - if (-not ($NsxtStarted -eq $nsxtNodes.count)) { + if (-not ($nsxtStarted -eq $nsxtNodes.count)) { # Startup the NSX Manager Nodes for Virtual Infrastructure Workload Domain - Start-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtvcUser -pass $mgmtvcPass -nodes $nsxtNodes -timeout 600 - if (!(Wait-ForStableNsxtClusterStatus -server $nsxtMgrfqdn -user $nsxMgrVIP.adminUser -pass $nsxMgrVIP.adminPassword)) { + Start-CloudComponent -server $mgmtVcServer.fqdn -user $mgmtVcUser -pass $mgmtVcPass -nodes $nsxtNodes -timeout 600 + if (!(Wait-ForStableNsxtClusterStatus -server $nsxtManagerFQDN -user $nsxtManagerVIP.adminUser -pass $nsxtManagerVIP.adminPassword)) { Write-PowerManagementLogMessage -Type ERROR -Message "The NSX Manager cluster is not in 'STABLE' state. Exiting!" Exit } @@ -1085,36 +1046,34 @@ Try { } # Gather NSX Edge Node Details and do the startup - $nxtClusterEdgeNodes = @() + $nsxtClusterEdgeNodes = @() Try { - [Array]$nsxtEdgeNodes = (Get-EdgeNodeFromNSXManager -server $nsxtMgrfqdn -user $nsxMgrVIP.adminUser -pass $nsxMgrVIP.adminPassword -VCfqdn $vcServer.fqdn) + [Array]$nsxtEdgeNodes = (Get-EdgeNodeFromNSXManager -server $nsxtManagerFQDN -user $nsxtManagerVIP.adminUser -pass $nsxtManagerVIP.adminPassword -VCfqdn $vcServer.fqdn) foreach ($node in $nsxtEdgeNodes) { foreach ($element in $clusterAllVMs) { - if( $element -like $node) { - $nxtClusterEdgeNodes += $node + if ( $element -like $node) { + $nsxtClusterEdgeNodes += $node [Array]$clusterVcfVMs += $node break } } - [Array]$vcfvms += $node + [Array]$vcfVMs += $node } - } - catch { + } Catch { Write-PowerManagementLogMessage -Type WARNING -Message "Cannot fetch information about NSX Edge nodes." } - if ($nxtClusterEdgeNodes.count -ne 0) { - Start-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $nxtClusterEdgeNodes -timeout 600 - } - else { + if ($nsxtClusterEdgeNodes.count -ne 0) { + Start-CloudComponent -server $vcServer.fqdn -user $vcUser -pass $vcPass -nodes $nsxtClusterEdgeNodes -timeout 600 + } else { Write-PowerManagementLogMessage -Type WARNING -Message "No NSX Edge nodes found. Skipping edge nodes startup for vSAN cluster '$($cluster.name)'!" } # End of startup - $vcfvms_string = "" - $vcfvms_string = ($clusterVcfVMs | select -Unique) -join "; " + $vcfVMs_string = "" + $vcfVMs_string = ($clusterVcfVMs | Select-Object -Unique) -join "; " Write-PowerManagementLogMessage -Type INFO -Message "##################################################################################" - Write-PowerManagementLogMessage -Type INFO -Message "The following components have been started: $vcfvms_string , " + Write-PowerManagementLogMessage -Type INFO -Message "The following components have been started: $vcfVMs_string ." if ([float]$vcfVersion -lt [float]4.5) { Write-PowerManagementLogMessage -Type INFO -Message "vSphere High Availability has been enabled by the script. Disable it per your environment's design." } @@ -1122,10 +1081,10 @@ Try { Write-PowerManagementLogMessage -Type INFO -Message "Use the following command to automatically start VMs" Write-PowerManagementLogMessage -Type INFO -Message "Start-CloudComponent -server $($vcServer.fqdn) -user $vcUser -pass $vcPass -nodes -timeout 600" if ([float]$vcfVersion -lt [float]4.5) { - Write-PowerManagementLogMessage -Type INFO -Message "If you have enabled SSH for the ESXi hosts through SDDC manager, disable it at this point." + Write-PowerManagementLogMessage -Type WARNING -Message "If you have enabled SSH for the ESXi hosts through SDDC manager, disable it at this point." } if ([float]$vcfVersion -gt [float]4.4) { - Write-PowerManagementLogMessage -Type INFO -Message "If you have disabled lockdown mode for the ESXi hosts in workload cluster, you can enable it at this point." + Write-PowerManagementLogMessage -Type WARNING -Message "If you have disabled lockdown mode for the ESXi hosts in workload cluster, you can enable it at this point." } Write-PowerManagementLogMessage -Type INFO -Message "##################################################################################" Write-PowerManagementLogMessage -Type INFO -Message "End of startup sequence for the cluster '$($cluster.name)'!" @@ -1133,7 +1092,6 @@ Try { $index += 1 } } -} -Catch { +} Catch { Debug-CatchWriterForPowerManagement -object $_ } diff --git a/VMware.CloudFoundation.PowerManagement.psd1 b/VMware.CloudFoundation.PowerManagement.psd1 index bad9240..6377444 100644 --- a/VMware.CloudFoundation.PowerManagement.psd1 +++ b/VMware.CloudFoundation.PowerManagement.psd1 @@ -52,15 +52,19 @@ # Modules that must be imported into the global environment prior to importing this module RequiredModules = @( @{ - ModuleName = 'Posh-SSH'; + ModuleName = 'VMware.PowerCLI' + ModuleVersion = '12.5.0' + } + @{ + ModuleName = 'Posh-SSH' ModuleVersion = '3.0.8' } @{ - ModuleName = 'PowerVCF'; + ModuleName = 'PowerVCF' ModuleVersion = '2.4.0' } @{ - ModuleName = 'PowerValidatedSolutions'; + ModuleName = 'PowerValidatedSolutions' ModuleVersion = '2.8.0' } ) @@ -84,13 +88,13 @@ FunctionsToExport = '*' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. - CmdletsToExport = '*' + CmdletsToExport = '*' # Variables to export from this module VariablesToExport = '*' # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. - AliasesToExport = @() + AliasesToExport = @() # DSC resources to export from this module # DscResourcesToExport = @() @@ -102,21 +106,21 @@ # FileList = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. - PrivateData = @{ + PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. - Tags = @('VMware', 'CloudFoundation', 'VMwareCloudFoundation') + Tags = @('VMware', 'CloudFoundation', 'VMwareCloudFoundation') # A URL to the license for this module. - LicenseUri = 'https://github.com/vmware/powershell-module-for-vmware-cloud-foundation-power-management/blob/main/LICENSE' + LicenseUri = 'https://github.com/vmware/powershell-module-for-vmware-cloud-foundation-power-management/blob/main/LICENSE' # A URL to the main website for this project. - ProjectUri = 'https://vmware.github.io/powershell-module-for-vmware-cloud-foundation-power-management/' + ProjectUri = 'https://vmware.github.io/powershell-module-for-vmware-cloud-foundation-power-management/' # A URL to an icon representing this module. - IconUri = 'https://raw.githubusercontent.com/vmware/powershell-module-for-vmware-cloud-foundation-power-management/main/.github/icon-85px.svg' + IconUri = 'https://raw.githubusercontent.com/vmware/powershell-module-for-vmware-cloud-foundation-power-management/main/.github/icon-85px.svg' # ReleaseNotes of this module ReleaseNotes = 'https://vmware.github.io/powershell-module-for-vmware-cloud-foundation-power-management/release-notes/' @@ -140,4 +144,4 @@ # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' - } +} diff --git a/VMware.CloudFoundation.PowerManagement.psm1 b/VMware.CloudFoundation.PowerManagement.psm1 index d48fa2c..8feebd4 100644 --- a/VMware.CloudFoundation.PowerManagement.psm1 +++ b/VMware.CloudFoundation.PowerManagement.psm1 @@ -20,7 +20,7 @@ if ($PSEdition -eq 'Core') { if ($PSEdition -eq 'Desktop') { # Enable communication with self signed certs when using Windows Powershell - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 if (-not ([System.Management.Automation.PSTypeName]'TrustAllCertificatePolicy').Type) { Add-Type @" @@ -84,7 +84,7 @@ Function Stop-CloudComponent { The password to authenticate to vCenter Server. .PARAMETER timeout - The timeout in seconds to wait for the cloud component to reach the desired connection state. + The timeout in seconds to wait for the cloud component to reach the desired connection state. .PARAMETER noWait To shudown the cloud component and not wait for desired connection state change. @@ -114,7 +114,7 @@ Function Stop-CloudComponent { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -133,8 +133,7 @@ Function Stop-CloudComponent { Write-PowerManagementLogMessage -Type INFO -Message "Attempting to shut down node '$node'..." if ($PsBoundParameters.ContainsKey("noWait")) { Stop-VM -Server $server -VM $node -Confirm:$false -ErrorAction SilentlyContinue | Out-Null - } - else { + } else { Stop-VMGuest -Server $server -VM $node -Confirm:$false -ErrorAction SilentlyContinue | Out-Null Write-PowerManagementLogMessage -Type INFO -Message "Waiting for node '$node' to shut down..." $sleepTime = 5 @@ -145,13 +144,11 @@ Function Stop-CloudComponent { } if ($count -gt $timeout) { Write-PowerManagementLogMessage -Type ERROR -Message "Node '$node' did not shut down within the expected timeout $timeout value." - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Node '$node' has shut down successfully." } } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Unable to find node '$node' in the inventory of server '$server'." } } @@ -161,15 +158,14 @@ Function Stop-CloudComponent { if ($PSCmdlet.ParameterSetName -eq "Pattern") { Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server' and attempting to shut down nodes with pattern '$pattern'..." if ($pattern) { - $patternNodes = Get-VM -Server $server | Where-Object Name -match $pattern | Select-Object Name, PowerState, VMHost | Where-Object VMHost -match $server - } - else { + $patternNodes = Get-VM -Server $server | Where-Object Name -Match $pattern | Select-Object Name, PowerState, VMHost | Where-Object VMHost -Match $server + } else { $patternNodes = @() } if ($patternNodes.Name.Count -ne 0) { foreach ($node in $patternNodes) { $count = 0 - $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -match $server + $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -Match $server if ($vm_obj.State -eq 'NotRunning') { Write-PowerManagementLogMessage -Type INFO -Message "Node '$($node.name)' is already powered off." Continue @@ -177,43 +173,36 @@ Function Stop-CloudComponent { Write-PowerManagementLogMessage -Type INFO -Message "Attempting to shut down node '$($node.name)'..." if ($PsBoundParameters.ContainsKey("noWait")) { Stop-VM -Server $server -VM $node.Name -Confirm:$false | Out-Null - } - else { - Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -match $server | Stop-VMGuest -Confirm:$false | Out-Null - $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -match $server + } else { + Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -Match $server | Stop-VMGuest -Confirm:$false | Out-Null + $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -Match $server $sleepTime = 1 While (($vm_obj.State -ne 'NotRunning') -and ($count -le $timeout)) { Start-Sleep -s $sleepTime $count = $count + $sleepTime - $vm_obj = Get-VMGuest -VM $node.Name | Where-Object VmUid -match $server + $vm_obj = Get-VMGuest -VM $node.Name | Where-Object VmUid -Match $server } if ($count -gt $timeout) { Write-PowerManagementLogMessage -Type ERROR -Message "Node '$($node.name)' did not shut down within the expected timeout $timeout value." - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Node '$($node.name)' has shut down successfully." } } } - } - elseif ($pattern) { + } elseif ($pattern) { Write-PowerManagementLogMessage -Type WARNING -Message "No nodes match pattern '$pattern' on host '$server'." } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Stop-CloudComponent cmdlet." } } @@ -245,7 +234,7 @@ Function Start-CloudComponent { The password to authenticate to vCenter Server. .PARAMETER timeout - The timeout in seconds to wait for the cloud component to reach the desired connection state. + The timeout in seconds to wait for the cloud component to reach the desired connection state. .PARAMETER nodes The FQDNs of the list of cloud components to startup. @@ -271,7 +260,7 @@ Function Start-CloudComponent { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -300,12 +289,10 @@ Function Start-CloudComponent { if ($count -gt $timeout) { Write-PowerManagementLogMessage -Type ERROR -Message "Node '$node' did not start up within the expected timeout $timeout value." Break - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Node '$node' has started successfully." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot find '$node' in the inventory of host '$server'." } } @@ -315,15 +302,14 @@ Function Start-CloudComponent { if ($PSCmdlet.ParameterSetName -eq "Pattern") { Write-PowerManagementLogMessage -Type INFO -Message "Connected to host '$server' and attempting to start up nodes with pattern '$pattern'..." if ($pattern) { - $patternNodes = Get-VM -Server $server | Where-Object Name -match $pattern | Select-Object Name, PowerState, VMHost | Where-Object VMHost -match $server - } - else { + $patternNodes = Get-VM -Server $server | Where-Object Name -Match $pattern | Select-Object Name, PowerState, VMHost | Where-Object VMHost -Match $server + } else { $patternNodes = @() } if ($patternNodes.Name.Count -ne 0) { foreach ($node in $patternNodes) { $count = 0 - $vm_obj = Get-VMGuest -server $server -VM $node.Name | Where-Object VmUid -match $server + $vm_obj = Get-VMGuest -server $server -VM $node.Name | Where-Object VmUid -Match $server if ($vm_obj.State -eq 'Running') { Write-PowerManagementLogMessage -Type INFO -Message "Node '$($node.name)' is already powered on." Continue @@ -331,39 +317,33 @@ Function Start-CloudComponent { Start-VM -VM $node.Name | Out-Null $sleepTime = 1 - $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -match $server + $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -Match $server Write-PowerManagementLogMessage -Type INFO -Message "Attempting to start up node '$($node.name)'..." While (($vm_obj.State -ne 'Running') -AND ($count -le $timeout)) { Start-Sleep -s $sleepTime $count = $count + $sleepTime - $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -match $server + $vm_obj = Get-VMGuest -Server $server -VM $node.Name | Where-Object VmUid -Match $server } if ($count -gt $timeout) { Write-PowerManagementLogMessage -Type ERROR -Message "Node '$($node.name)' did not start up within the expected timeout $timeout value." - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Node '$($node.name)' has started successfully." } } - } - elseif ($pattern) { + } elseif ($pattern) { Write-PowerManagementLogMessage -Type WARNING -Message "No nodes match pattern '$pattern' on host '$server'." } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to host '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Start-CloudComponent cmdlet." } } @@ -384,7 +364,7 @@ Function Set-MaintenanceMode { .EXAMPLE Set-MaintenanceMode -server sfo01-w01-esx01.sfo.rainpole.io -user root -pass VMw@re1! -state DISABLE This example takes an ESXi host out of maintenance mode. - + .PARAMETER server The FQDN of the ESXi host. @@ -413,7 +393,7 @@ Function Set-MaintenanceMode { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -421,58 +401,48 @@ Function Set-MaintenanceMode { $hostStatus = (Get-VMHost -Server $server) if ($state -eq "ENABLE") { if ($hostStatus.ConnectionState -eq "Connected") { - Write-PowerManagementLogMessage -type INFO -Message "Attempting to enter maintenance mode for '$server'..." - Get-View -Server $server -ViewType HostSystem -Filter @{"Name" = $server } | Where-Object { !$_.Runtime.InMaintenanceMode } | ForEach-Object { $_.EnterMaintenanceMode(0, $false, (new-object VMware.Vim.HostMaintenanceSpec -Property @{vsanMode = (new-object VMware.Vim.VsanHostDecommissionMode -Property @{objectAction = [VMware.Vim.VsanHostDecommissionModeObjectAction]::NoAction }) })) } | Out-Null + Write-PowerManagementLogMessage -Type INFO -Message "Attempting to enter maintenance mode for '$server'..." + Get-View -Server $server -ViewType HostSystem -Filter @{"Name" = $server } | Where-Object { !$_.Runtime.InMaintenanceMode } | ForEach-Object { $_.EnterMaintenanceMode(0, $false, (New-Object VMware.Vim.HostMaintenanceSpec -Property @{vsanMode = (New-Object VMware.Vim.VsanHostDecommissionMode -Property @{objectAction = [VMware.Vim.VsanHostDecommissionModeObjectAction]::NoAction }) })) } | Out-Null $hostStatus = (Get-VMHost -Server $server) if ($hostStatus.ConnectionState -eq "Maintenance") { Write-PowerManagementLogMessage -Type INFO -Message "Host '$server' has entered maintenance mode successfully." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Host '$server' did not enter maintenance mode. Check your environment and try again." } - } - elseif ($hostStatus.ConnectionState -eq "Maintenance") { + } elseif ($hostStatus.ConnectionState -eq "Maintenance") { Write-PowerManagementLogMessage -Type INFO -Message "Host '$server' has already entered maintenance mode." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Host '$server' is not currently connected." } } elseif ($state -eq "DISABLE") { if ($hostStatus.ConnectionState -eq "Maintenance") { - Write-PowerManagementLogMessage -type INFO -Message "Attempting to exit maintenance mode for '$server'..." + Write-PowerManagementLogMessage -Type INFO -Message "Attempting to exit maintenance mode for '$server'..." $task = Set-VMHost -VMHost $server -State "Connected" -RunAsync -WarningAction SilentlyContinue -ErrorAction SilentlyContinue - Wait-Task $task | out-null + Wait-Task $task | Out-Null $hostStatus = (Get-VMHost -Server $server) if ($hostStatus.ConnectionState -eq "Connected") { Write-PowerManagementLogMessage -Type INFO -Message "Host '$server' has exited maintenance mode successfully." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "The host '$server' did not exit maintenance mode. Check your environment and try again." } - } - elseif ($hostStatus.ConnectionState -eq "Connected") { + } elseif ($hostStatus.ConnectionState -eq "Connected") { Write-PowerManagementLogMessage -Type INFO -Message "Host '$server' has already exited maintenance mode" - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Host '$server' is not currently connected." } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Set-MaintenanceMode cmdlet." } } @@ -514,27 +484,23 @@ Function Get-MaintenanceMode { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { - Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server' and attempting to $state maintenance mode..." $hostStatus = (Get-VMHost -Server $server) - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server'. The connection status is '$($hostStatus.ConnectionState)'." + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null return $hostStatus.ConnectionState - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-MaintenanceMode cmdlet." } } @@ -551,7 +517,7 @@ Function Set-DrsAutomationLevel { .EXAMPLE Set-DrsAutomationLevel -server sfo-m01-vc01.sfo.rainpole.io -user administrator@vsphere.local -Pass VMw@re1! -cluster sfo-m01-cl01 -level PartiallyAutomated Thi examples sets the DRS Automation level for the sfo-m01-cl01 cluster to Partially Automated - + .PARAMETER server The FQDN of the vCenter Server. @@ -585,7 +551,7 @@ Function Set-DrsAutomationLevel { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -593,34 +559,27 @@ Function Set-DrsAutomationLevel { if ($drsStatus) { if ($drsStatus.DrsAutomationLevel -eq $level) { Write-PowerManagementLogMessage -Type INFO -Message "The vSphere DRS automation level for cluster '$cluster' is already '$level'." - } - else { + } else { $drsStatus = Set-Cluster -Cluster $cluster -DrsAutomationLevel $level -Confirm:$false if ($drsStatus.DrsAutomationLevel -eq $level) { Write-PowerManagementLogMessage -Type INFO -Message "The vSphere DRS automation level for cluster '$cluster' has been set to '$level' successfully." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Failed to set the vSphere DRS automation level for cluster '$cluster' to '$level'." } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cluster '$cluster' not found on host '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Set-DrsAutomationLevel cmdlet." } } @@ -652,7 +611,7 @@ Function Set-VsanClusterPowerStatus { .PARAMETER clustername The name of the vSAN cluster on which the power settings are to be applied. - + .PARAMETER mgmt The switch used to ignore power settings if management domain information is passed. @@ -678,7 +637,7 @@ Function Set-VsanClusterPowerStatus { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -701,18 +660,17 @@ Function Set-VsanClusterPowerStatus { $counter = 0 $sleepTime = 10 # in seconds if (-not $mgmt) { - do - { + do { $task = Get-Task -Id $powerActionTask if (-Not ($task.State -eq "Error")) { Write-PowerManagementLogMessage -Type INFO -Message "$PowerStatus task is $($task.PercentComplete)% completed." } Start-Sleep -s $sleepTime $counter += $sleepTime - } while($task.State -eq "Running" -and ($counter -lt 1800)) + } while ($task.State -eq "Running" -and ($counter -lt 1800)) - if ($task.State -eq "Error"){ - if ($task.ExtensionData.Info.Error.Fault.FaultMessage -like "VMware.Vim.LocalizableMessage") { + if ($task.State -eq "Error") { + if ($task.ExtensionData.Info.Error.Fault.FaultMessage -like "VMware.Vim.LocalizableMessage") { Write-PowerManagementLogMessage -Type ERROR -Message "'$($PowerStatus)' task exited with a localized error message. Go to the vSphere Client for details and to take the necessary actions." } else { Write-PowerManagementLogMessage -Type WARN -Message "'$($PowerStatus)' task exited with the Message:$($task.ExtensionData.Info.Error.Fault.FaultMessage) and Error: $($task.ExtensionData.Info.Error)." @@ -720,27 +678,23 @@ Function Set-VsanClusterPowerStatus { } } - if ($task.State -eq "Success"){ + if ($task.State -eq "Success") { Write-PowerManagementLogMessage -Type INFO -Message "$PowerStatus task is completed successfully." } else { Write-PowerManagementLogMessage -Type ERROR -Message "$PowerStatus task is blocked in $($task.State) state." } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Set-VsanClusterPowerStatus cmdlet." } } @@ -756,7 +710,7 @@ Function Invoke-VxrailClusterShutdown { .EXAMPLE Invoke-VxrailClusterShutdown -server sfo-w01-vxrm.sfo.rainpole.io -user administrator@vsphere.local -pass VMw@re1! - This example powers off a VxRail cluster cluster which is managed by the VxRail Manager sfo-w01-vxrm.sfo.rainpole.io controls. + This example powers off a VxRail cluster cluster which is managed by the VxRail Manager sfo-w01-vxrm.sfo.rainpole.io controls. #> @@ -765,7 +719,7 @@ Function Invoke-VxrailClusterShutdown { [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$user, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$pass ) - + Try { Write-PowerManagementLogMessage -Type INFO -Message "Starting the call to the Invoke-VxrailClusterShutdown cmdlet." @@ -773,36 +727,37 @@ Function Invoke-VxrailClusterShutdown { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } # Prepare VxRail rest API headers and payload - $payloadTest = @{ dryrun = 'true'} | ConvertTo-Json - $payloadRun = @{ dryrun = 'false'} | ConvertTo-Json + $payloadTest = @{ dryrun = 'true' } | ConvertTo-Json + $payloadRun = @{ dryrun = 'false' } | ConvertTo-Json $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user, $pass))) # Create Basic Authentication Encoded Credentials $headers = @{"Content-Type" = "application/json" } $headers.Add("Authorization", "Basic $base64AuthInfo") - $uri = "https://$server/rest/vxm/v1/cluster/shutdown" + $uri = "https://$server/rest/vxm/v1/cluster/shutdown" Write-PowerManagementLogMessage -Type INFO -Message "Starting VxRail cluster shutdown dry run." - $respond = Invoke-WebRequest -Method POST -Uri $uri -Headers $headers -Body $payloadTest -UseBasicParsing -SkipCertificateCheck - if($respond.StatusCode -eq "202" -or $respond.StatusCode -eq "200") { - $requestID = $respond.content | ConvertFrom-JSON + $respond = Invoke-WebRequest -Method POST -Uri $uri -Headers $headers -Body $payloadTest -UseBasicParsing -SkipCertificateCheck + if ($respond.StatusCode -eq "202" -or $respond.StatusCode -eq "200") { + $requestID = $respond.content | ConvertFrom-Json Write-PowerManagementLogMessage -Type INFO -Message "VxRail cluster shutdown request accepted(ID:$($requestID.request_id))" $uri2 = "https://$server/rest/vxm/v1/requests/$($requestID.request_id)" $loopCounter = 0 - while ($loopCounter -lt 13){ + $loopCounterLimit = 13 + while ($loopCounter -lt $loopCounterLimit) { $respond2 = Invoke-WebRequest -Method GET -Uri $uri2 -Headers $headers -UseBasicParsing -SkipCertificateCheck if ($respond2.StatusCode -eq "202" -or $respond2.StatusCode -eq "200") { - $checkProgress = $respond2.content | ConvertFrom-JSON - if($checkProgress.state -Match "COMPLETED" -or $checkProgress.state -Match "FAILED" ) { + $checkProgress = $respond2.content | ConvertFrom-Json + if ($checkProgress.state -Match "COMPLETED" -or $checkProgress.state -Match "FAILED" ) { break } } Start-Sleep -s 10 $loopCounter += 1 } - + if ($checkProgress.extension.passed -match "true") { Write-PowerManagementLogMessage -Type INFO -Message "VxRail cluster shutdown dry run: SUCCEEDED." Write-PowerManagementLogMessage -Type INFO -Message "Starting VxRail cluster shutdown." @@ -814,23 +769,20 @@ Function Invoke-VxrailClusterShutdown { Write-PowerManagementLogMessage -Type ERROR -Message "VxRail cluster shutdown: FAILED" } } else { - $errorMsg = "" - $checkProgress = $respond2.content | ConvertFrom-JSON + $errorMsg = "" + $checkProgress = $respond2.content | ConvertFrom-Json $parsingError = $checkProgress.extension.status - foreach($errorElement in $parsingError) - { - if ($errorElement.checkResult -match "FAILED") - { + foreach ($errorElement in $parsingError) { + if ($errorElement.checkResult -match "FAILED") { $errorMsg = $errorMsg + "Label: $($errorElement.label),($($errorElement.checkResult)) `nMessage: $($errorElement.message)`n" } } - Write-PowerManagementLogMessage -Type ERROR -Message "VxRail cluster shutdown dry run: FAILED `n $errorMsg" + Write-PowerManagementLogMessage -Type ERROR -Message "VxRail cluster shutdown dry run: FAILED `n $errorMsg" } } else { Write-PowerManagementLogMessage -Type ERROR -Message "VxRail cluster shutdown: FAILED" } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } } Catch { @@ -882,7 +834,7 @@ Function Get-poweronVMsOnRemoteDS { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -910,19 +862,15 @@ Function Get-poweronVMsOnRemoteDS { } } return $PoweredOnVMs - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-poweronVMsOnRemoteDS cmdlet." } } @@ -969,14 +917,14 @@ Function Test-LockdownMode { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { $hostsInCluster = @() - $hostsInCluster = Get-Cluster -Name $cluster | Get-VMHost - $hostsWithLockdown = "" - if ($hostsInCluster.count -ne 0) { + $hostsInCluster = Get-Cluster -Name $cluster | Get-VMHost + $hostsWithLockdown = "" + if ($hostsInCluster.count -ne 0) { foreach ($esxiHost in $hostsInCluster) { Write-PowerManagementLogMessage -Type INFO -Message "Checking lockdown mode for $esxiHost ...." $lockdownStatus = (Get-VMHost -Name $esxiHost).ExtensionData.Config.LockdownMode @@ -998,25 +946,21 @@ Function Test-LockdownMode { } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cluster $cluster is not present on server $server. Check the input to the cmdlet." } - if ([string]::IsNullOrEmpty($hostsWithLockdown)) { + if ([string]::IsNullOrEmpty($hostsWithLockdown)) { Write-PowerManagementLogMessage -Type INFO -Message "Cluster $cluster does not have ESXi hosts in lockdown mode." - } else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "The following ESXi hosts are in lockdown mode: $hostsWithLockdown. Disable lockdown mode to continue." Write-PowerManagementLogMessage -Type ERROR -Message "Some hosts are in lockdown mode. Disable lockdown mode to continue." - } - } - else { + } + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Test-LockdownMode cmdlet." } } @@ -1066,43 +1010,37 @@ Function Get-VMRunningStatus { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { Write-PowerManagementLogMessage -Type INFO -Message "Connected to host '$server' and checking if nodes named '$pattern' are in the '$($status.ToUpper())' state..." - $nodes = Get-VM | Where-Object Name -match $pattern | Select-Object Name, PowerState, VMHost + $nodes = Get-VM | Where-Object Name -Match $pattern | Select-Object Name, PowerState, VMHost if ($nodes.Name.Count -eq 0) { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot find nodes matching pattern '$pattern' in the inventory of host '$server'." - } - else { + } else { foreach ($node in $nodes) { - $vm_obj = Get-VMGuest -server $server -VM $node.Name -ErrorAction SilentlyContinue | Where-Object VmUid -match $server + $vm_obj = Get-VMGuest -server $server -VM $node.Name -ErrorAction SilentlyContinue | Where-Object VmUid -Match $server if ($vm_obj.State -eq $status) { Write-PowerManagementLogMessage -Type INFO -Message "Node $($node.Name) is in '$($status.ToUpper()) state.'" return $true - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Node $($node.Name) is not in '$($status.ToUpper()) state'." return $false } } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-VMRunningStatus cmdlet." } } @@ -1151,34 +1089,28 @@ Function Invoke-EsxCommand { $password = ConvertTo-SecureString $pass -AsPlainText -Force $Cred = New-Object System.Management.Automation.PSCredential ($user, $password) Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." - $session = New-SSHSession -ComputerName $server -Credential $Cred -Force -WarningAction SilentlyContinue + $session = New-SSHSession -ComputerName $server -Credential $Cred -Force -WarningAction SilentlyContinue if ($session) { Write-PowerManagementLogMessage -Type INFO -Message "Attempting to run command '$cmd' on server '$server'..." $commandOutput = Invoke-SSHCommand -Index $session.SessionId -Command $cmd -Timeout 900 if ($expected ) { if (($commandOutput.Output -match $expected)) { Write-PowerManagementLogMessage -Type INFO -Message "Command '$cmd' completed with expected output on server '$server'." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Failure. The `"$($expected)`" is not present in `"$($commandOutput.Output)`" output" } - } - elseif ($commandOutput.exitStatus -eq 0) { + } elseif ($commandOutput.exitStatus -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "Success. The command completed successfully." - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Failure. The command could not be run." } Remove-SSHSession -Index $session.SessionId | Out-Null - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Invoke-EsxCommand cmdlet." } } @@ -1195,7 +1127,7 @@ Function Get-SSHEnabledStatus { .EXAMPLE Get-SSHEnabledStatus -server sfo01-w01-esx01.sfo.rainpole.io -user root -pass VMw@re1! In the above example, it tries to ssh to ESXi host and if success, returns true. - + .PARAMETER server The FQDN of the ESXi host. @@ -1221,24 +1153,21 @@ Function Get-SSHEnabledStatus { $checkServer = (Test-EndpointConnection -server $server -Port 443) if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Attempting to open an SSH connection to server '$server'..." - $session = New-SSHSession -ComputerName $server -Credential $Cred -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue + $session = New-SSHSession -ComputerName $server -Credential $Cred -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue if ($session) { Write-PowerManagementLogMessage -Type INFO -Message "SSH is enabled on '$server'." Remove-SSHSession -Index $session.SessionId | Out-Null return $True - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "SSH is not enabled '$server'." return $False } } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot communicate with server '$server'. Check the power state of the server." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-SSHEnabledStatus cmdlet" } } @@ -1255,7 +1184,7 @@ Function Test-VsanHealth { .EXAMPLE Test-VsanHealth -cluster sfo-m01-cl01 -server sfo-m01-vc01 -user administrator@vsphere.local -pass VMw@re1! This example connects to a vCenter Server and checks the state of the vSAN cluster health. - + .PARAMETER server The FQDN of the vCenter Server. @@ -1284,7 +1213,7 @@ Function Test-VsanHealth { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -1299,8 +1228,7 @@ Function Test-VsanHealth { $flag = 1 Break } - } - Catch { + } Catch { Write-PowerManagementLogMessage -Type INFO -Message "The vSAN health service is yet to come up, please wait ..." Start-Sleep -s 60 $count += 1 @@ -1309,8 +1237,7 @@ Function Test-VsanHealth { if (-Not $flag) { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot run the Test-VsanHealth cmdlet because the vSAN health service is not running." - } - else { + } else { Start-Sleep -s 60 $vchs = Get-VSANView -Server $server -Id "VsanVcClusterHealthSystem-vsan-cluster-health-system" $cluster_view = (Get-Cluster -Name $cluster).ExtensionData.MoRef @@ -1337,26 +1264,21 @@ Function Test-VsanHealth { if ($health_status -eq 'GREEN' -and $results.OverallHealth -ne 'red') { Write-PowerManagementLogMessage -Type INFO -Message "The vSAN health status for $cluster is good." return 0 - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "The vSAN health status for $cluster is bad." return 1 } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Test-VsanHealth cmdlet." } } @@ -1402,7 +1324,7 @@ Function Test-VsanObjectResync { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -1412,25 +1334,20 @@ Function Test-VsanObjectResync { if ($no_resyncing_objects.count -eq 0) { Write-PowerManagementLogMessage -Type INFO -Message "No resynchronizing objects." return 0 - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Resynchronizing objects in progress..." return 1 } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Test-VsanObjectResync cmdlet." } } @@ -1457,7 +1374,7 @@ Function Get-VMsWithPowerStatus { Get-VMsWithPowerStatus -server sfo-m01-vc01.sfo.rainpole.io -user administrator@vsphere.local -pass VMw@re1! -powerstate "poweredon" -pattern "vcls" -silence This example connects to a vCenter Server instance and returns the list of powered-on vCLS virtual machines without log messages in the output. - + .PARAMETER server The FQDN of the vCenter Server. @@ -1484,7 +1401,7 @@ Function Get-VMsWithPowerStatus { [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$server, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String]$user, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String]$pass, - [Parameter (Mandatory = $true)] [ValidateSet("poweredon","poweredoff")] [String]$powerstate, + [Parameter (Mandatory = $true)] [ValidateSet("poweredon", "poweredoff")] [String]$powerstate, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [String]$pattern = $null , [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [Switch]$exactMatch, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [Switch]$silence @@ -1494,50 +1411,43 @@ Function Get-VMsWithPowerStatus { Try { - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "Starting the call to the Get-VMsWithPowerStatus cmdlet."} + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Starting the call to the Get-VMsWithPowerStatus cmdlet." } $checkServer = (Test-EndpointConnection -server $server -Port 443) if ($checkServer) { - if(-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..."} + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." } if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { - if(-not $silence) {Write-PowerManagementLogMessage -type INFO -Message "Connected to server '$server' and attempting to get the list of virtual machines..."} - if ($pattern) { - if ($PSBoundParameters.ContainsKey('exactMatch') ) { - $no_of_vms = get-vm -Server $server | Where-Object Name -EQ $pattern | Where-Object PowerState -eq $powerstate - } - else { - $no_of_vms = get-vm -Server $server | Where-Object Name -match $pattern | Where-Object PowerState -eq $powerstate - } - } - else { - $no_of_vms = get-vm -Server $server | Where-Object PowerState -eq $powerstate - } - if ($no_of_vms.count -eq 0) { - if(-not $silence) {Write-PowerManagementLogMessage -type INFO -Message "No virtual machines in the $powerstate state."} - } - else { - $no_of_vms_string = $no_of_vms -join "," - if(-not $silence) {Write-PowerManagementLogMessage -type INFO -Message "The virtual machines in the $powerstate state are: $no_of_vms_string"} + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server' and attempting to get the list of virtual machines..." } + if ($pattern) { + if ($PSBoundParameters.ContainsKey('exactMatch') ) { + $no_of_vms = get-vm -Server $server | Where-Object Name -EQ $pattern | Where-Object PowerState -EQ $powerstate + } else { + $no_of_vms = get-vm -Server $server | Where-Object Name -Match $pattern | Where-Object PowerState -EQ $powerstate } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - Return $no_of_vms - } - else { + } else { + $no_of_vms = get-vm -Server $server | Where-Object PowerState -EQ $powerstate + } + if ($no_of_vms.count -eq 0) { + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "No virtual machines in the $powerstate state." } + } else { + $no_of_vms_string = $no_of_vms -join "," + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "The virtual machines in the $powerstate state are: $no_of_vms_string" } + } + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Return $no_of_vms + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-VMsWithPowerStatus cmdlet."} + } Finally { + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-VMsWithPowerStatus cmdlet." } } } Export-ModuleMember -Function Get-VMsWithPowerStatus @@ -1593,7 +1503,7 @@ Function Get-VamiServiceStatus { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." } if ($DefaultCisServers) { - Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } $retries = 20 $flag = 0 @@ -1613,23 +1523,16 @@ Function Get-VamiServiceStatus { $vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service' $serviceStatus = $vMonAPI.Get($service, 0) return $serviceStatus.state + } else { + Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - else { - Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." - } - } - else { - Write-PowerManagementLogMessage -Type ERROR -Message "Testing the connection to server '$server' has failed. Check your details and try again." + } else { + Write-PowerManagementLogMessage -Type ERROR -Message "Testing the connection to server '$server' has failed. Check your details and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { - if (-Not $nolog) { - # Write-PowerManagementLogMessage -Type INFO -Message "Disconnecting from host '$server'..." - } - Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } Finally { + Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null if (-Not $nolog) { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-VAMIServiceStatus cmdlet." } @@ -1660,7 +1563,7 @@ Function Set-VamiServiceStatus { .PARAMETER pass The password to authenticate to vCenter Server. - + .PARAMETER state The state of the servcie. The values can be one amongst ("start", "stop", "restart"). @@ -1694,7 +1597,7 @@ Function Set-VamiServiceStatus { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." } if ($DefaultCisServers) { - Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } $retries = 20 $flag = 0 @@ -1715,7 +1618,7 @@ Function Set-VamiServiceStatus { if ($state -eq "start") { $vMonAPI.Start($service) $serviceStatus = $vMonAPI.Get($service, 0) - if($serviceStatus.state -eq "STARTED") { + if ($serviceStatus.state -eq "STARTED") { if (-Not $nolog) { Write-PowerManagementLogMessage -Type INFO -Message "Service '$service' is successfully started." } @@ -1725,7 +1628,7 @@ Function Set-VamiServiceStatus { } elseif ($state -eq "stop") { $vMonAPI.Stop($service) $serviceStatus = $vMonAPI.Get($service, 0) - if($serviceStatus.state -eq "STOPPED") { + if ($serviceStatus.state -eq "STOPPED") { if (-Not $nolog) { Write-PowerManagementLogMessage -Type INFO -Message "Service '$service' is successfully stopped." } @@ -1735,7 +1638,7 @@ Function Set-VamiServiceStatus { } else { $vMonAPI.ReStart($service) $serviceStatus = $vMonAPI.Get($service, 0) - if($serviceStatus.state -eq "STARTED") { + if ($serviceStatus.state -eq "STARTED") { if (-Not $nolog) { Write-PowerManagementLogMessage -Type INFO -Message "Service '$service' is successfully restarted." } @@ -1743,23 +1646,16 @@ Function Set-VamiServiceStatus { Write-PowerManagementLogMessage -Type ERROR -Message "Could not restart service '$service'." } } + } else { + Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - else { - Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." - } - } - else { - Write-PowerManagementLogMessage -Type ERROR -Message "Testing the connection to server '$server' has failed. Check your details and try again." + } else { + Write-PowerManagementLogMessage -Type ERROR -Message "Testing the connection to server '$server' has failed. Check your details and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { - if (-Not $nolog) { - # Write-PowerManagementLogMessage -Type INFO -Message "Disconnecting from host '$server'..." - } - Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } Finally { + Disconnect-CisServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null if (-Not $nolog) { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Set-VamiServiceStatus cmdlet." } @@ -1781,7 +1677,7 @@ Function Set-VsphereHA { Set-VsphereHA -server $server -user $user -pass $pass -cluster $cluster -disable This example sets vSphere High Availability to disabled/stopped - + .PARAMETER server The FQDN of the vCenter Server. @@ -1790,7 +1686,7 @@ Function Set-VsphereHA { .PARAMETER pass The password to authenticate to vCenter Server. - + .PARAMETER cluster The name of the cluster. @@ -1817,7 +1713,7 @@ Function Set-VsphereHA { if ($(Test-EndpointConnection -server $server -Port 443)) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -1828,10 +1724,9 @@ Function Set-VsphereHA { $Retries = 60 if ($enableHA) { if ($(get-cluster -Name $cluster).HAEnabled) { - Write-PowerManagementLogMessage -type INFO -Message "vSphere High Availability is already enabled on the vSAN cluster. " + Write-PowerManagementLogMessage -Type INFO -Message "vSphere High Availability is already enabled on the vSAN cluster. " return $true - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Enabling vSphere High Availability for cluster '$cluster'..." Set-Cluster -Server $server -Cluster $cluster -HAEnabled:$true -Confirm:$false | Out-Null While (-not $completed) { @@ -1848,14 +1743,12 @@ Function Set-VsphereHA { Write-PowerManagementLogMessage -Type INFO -Message "vSphere High Availability configuration changes are not applied. Sleeping for $SecondsDelay seconds..." Start-Sleep -s $SecondsDelay continue - } - else { + } else { $completed = $true if ($(get-cluster -Name $cluster).HAEnabled) { Write-PowerManagementLogMessage -Type INFO -Message "vSphere High Availability for cluster '$cluster' changed to 'Enabled'." return $true - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "Failed to set vSphere High Availability for cluster '$cluster' to 'Enabled'." return $false } @@ -1865,10 +1758,9 @@ Function Set-VsphereHA { } if ($disableHA) { if (!$(get-cluster -Name $cluster).HAEnabled) { - Write-PowerManagementLogMessage -type INFO -Message "vSphere High Availability is already disabled on the vSAN cluster. " + Write-PowerManagementLogMessage -Type INFO -Message "vSphere High Availability is already disabled on the vSAN cluster. " return $true - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Disabling vSphere High Availability for cluster '$cluster'." Set-Cluster -Server $server -Cluster $cluster -HAEnabled:$false -Confirm:$false | Out-Null While (-not $completed) { @@ -1885,14 +1777,12 @@ Function Set-VsphereHA { Write-PowerManagementLogMessage -Type INFO -Message "vSphere High Availability configuration changes are not applied. Sleeping for $SecondsDelay seconds..." Start-Sleep -s $SecondsDelay continue - } - else { + } else { $completed = $true if (!$(get-cluster -Name $cluster).HAEnabled) { Write-PowerManagementLogMessage -Type INFO -Message "Disabled vSphere High Availability for cluster '$cluster'." return $true - } - else { + } else { Write-PowerManagementLogMessage -Type WARNING -Message "Failed to disable vSphere High Availability for cluster '$cluster'." return $false } @@ -1900,19 +1790,15 @@ Function Set-VsphereHA { } } } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Set-VsphereHA cmdlet." } @@ -1939,7 +1825,7 @@ Function Get-DrsAutomationLevel { .PARAMETER pass The password to authenticate to vCenter Server. - + .PARAMETER cluster The name of the cluster. #> @@ -1959,7 +1845,7 @@ Function Get-DrsAutomationLevel { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { @@ -1967,26 +1853,21 @@ Function Get-DrsAutomationLevel { $ClusterData = Get-Cluster -Name $cluster if ($ClusterData.DrsEnabled) { $clsdrsvalue = $ClusterData.DrsAutomationLevel - Write-PowerManagementLogMessage -type INFO -Message "The cluster DRS value: $clsdrsvalue." - } - else { - Write-PowerManagementLogMessage -type INFO -Message "vSphere DRS is not enabled on the cluster $cluster." + Write-PowerManagementLogMessage -Type INFO -Message "The cluster DRS value: $clsdrsvalue." + } else { + Write-PowerManagementLogMessage -Type INFO -Message "vSphere DRS is not enabled on the cluster $cluster." } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null return $clsdrsvalue - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-DrsAutomationLevel cmdlet." } @@ -2017,10 +1898,10 @@ Function Set-Retreatmode { .PARAMETER pass The password to authenticate to vCenter Server. - + .PARAMETER cluster The name of the cluster. - + .PARAMETER mode The name of the retreat mode. The value is one amongst ("enable", "disable"). #> @@ -2041,50 +1922,43 @@ Function Set-Retreatmode { if ($checkServer) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server'..." - $cluster_id = Get-Cluster -Name $cluster | select-object -property Id + $cluster_id = Get-Cluster -Name $cluster | Select-Object -Property Id $domain_out = $cluster_id.Id -match 'domain-c.*' $domain_id = $Matches[0] $advanced_setting = "config.vcls.clusters.$domain_id.enabled" - if (Get-AdvancedSetting -Entity $server -Name $advanced_setting) { + if (Get-AdvancedSetting -Entity $server -Name $advanced_setting) { Write-PowerManagementLogMessage -Type INFO -Message "Advanced setting $advanced_setting is present." if ($mode -eq 'enable') { - Get-AdvancedSetting -Entity $server -Name $advanced_setting | Set-AdvancedSetting -Value 'false' -Confirm:$false | out-null + Get-AdvancedSetting -Entity $server -Name $advanced_setting | Set-AdvancedSetting -Value 'false' -Confirm:$false | Out-Null Write-PowerManagementLogMessage -Type INFO -Message "Advanced setting $advanced_setting is set to false." - } - else { - Get-AdvancedSetting -Entity $server -Name $advanced_setting | Set-AdvancedSetting -Value 'true' -Confirm:$false | Out-Null + } else { + Get-AdvancedSetting -Entity $server -Name $advanced_setting | Set-AdvancedSetting -Value 'true' -Confirm:$false | Out-Null Write-PowerManagementLogMessage -Type INFO -Message "Advanced setting $advanced_setting is set to true." } - } - else { + } else { if ($mode -eq 'enable') { - New-AdvancedSetting -Entity $server -Name $advanced_setting -Value 'false' -Confirm:$false | Out-Null + New-AdvancedSetting -Entity $server -Name $advanced_setting -Value 'false' -Confirm:$false | Out-Null Write-PowerManagementLogMessage -Type INFO -Message "Advanced setting $advanced_setting is set to false." - } - else { - New-AdvancedSetting -Entity $server -Name $advanced_setting -Value 'true' -Confirm:$false | Out-Null + } else { + New-AdvancedSetting -Entity $server -Name $advanced_setting -Value 'true' -Confirm:$false | Out-Null Write-PowerManagementLogMessage -Type INFO -Message "Advanced setting $advanced_setting is set to true." } } - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null - } - else { + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Set-Retreatmode cmdlet." } @@ -2114,10 +1988,10 @@ Function Get-VMToClusterMapping { .PARAMETER pass The password to authenticate to vCenter Server. - + .PARAMETER cluster The name of the cluster. - + .PARAMETER folder The name of the folder to search for virtual machines. @@ -2136,49 +2010,45 @@ Function Get-VMToClusterMapping { [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String[]] $cluster, [Parameter (Mandatory = $true)] [ValidateNotNullOrEmpty()] [String] $folder, [Parameter (Mandatory = $false)] [ValidateNotNullOrEmpty()] [Switch] $silence, - [Parameter (Mandatory = $false)] [ValidateSet("poweredon","poweredoff")] [String] $powerstate + [Parameter (Mandatory = $false)] [ValidateSet("poweredon", "poweredoff")] [String] $powerstate ) $pass = Get-Password -User $user -Password $pass Try { - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "Starting the call to the Get-VMToClusterMapping cmdlet."} + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Starting the call to the Get-VMToClusterMapping cmdlet." } $checkServer = (Test-EndpointConnection -server $server -Port 443) if ($checkServer) { - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..."} + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Connecting to '$server'..." } if ($DefaultVIServers) { - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null } Connect-VIServer -Server $server -Protocol https -User $user -Password $pass | Out-Null if ($DefaultVIServer.Name -eq $server) { - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server'..."} + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Connected to server '$server'..." } foreach ($clus in $cluster) { if ($powerstate) { - $VMs += get-vm -location $clus | where {(Get-VM -location $folder) -contains $_} | where PowerState -eq $powerstate + $VMs += get-vm -location $clus | Where-Object { (Get-VM -location $folder) -contains $_ } | Where-Object PowerState -EQ $powerstate } else { - $VMs += get-vm -location $clus | where {(Get-VM -location $folder) -contains $_} + $VMs += get-vm -location $clus | Where-Object { (Get-VM -location $folder) -contains $_ } } } $clustersstring = $cluster -join "," - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "The list of VMs on cluster $clustersstring is $VMs"} - Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "The list of VMs on cluster $clustersstring is $VMs" } + Disconnect-VIServer -Server * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null return $VMs - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot connect to server '$server'. Check your environment and try again." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { - if(-not $silence) {Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-VMToClusterMapping cmdlet."} + } Finally { + if (-not $silence) { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-VMToClusterMapping cmdlet." } } } @@ -2238,9 +2108,8 @@ Function Wait-ForStableNsxtClusterStatus { $retryCount++ # Retry connection if NSX Manager is not online Try { - $response = Invoke-RestMethod -Method GET -URI $uri -headers $headers -ContentType application/json -TimeoutSec 60 - } - Catch { + $response = Invoke-RestMethod -Method GET -Uri $uri -Headers $headers -ContentType application/json -TimeoutSec 60 + } Catch { Write-PowerManagementLogMessage -Type INFO -Message "Could not connect to NSX Manager '$server'! Sleeping $($SecondsDelay * $aditionalWaitMultiplier) seconds before next attempt." Start-Sleep -s $($SecondsDelay * $aditionalWaitMultiplier) continue @@ -2252,23 +2121,19 @@ Function Wait-ForStableNsxtClusterStatus { if ($successfulConnections -lt 4) { Write-PowerManagementLogMessage -Type INFO -Message "Sleeping for $($SecondsDelay * $aditionalWaitMultiplier) seconds before next check..." Start-Sleep -s $($SecondsDelay * $aditionalWaitMultiplier) - } - else { + } else { Write-PowerManagementLogMessage -Type INFO -Message "Sleeping for $SecondsDelay seconds until the next check..." Start-Sleep -s $SecondsDelay } - } - else { + } else { $completed = $true Write-PowerManagementLogMessage -Type INFO -Message "The state of the NSX Manager cluster '$server' is 'STABLE'." return $true } } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Wait-ForStableNsxtClusterStatus cmdlet." } } @@ -2343,20 +2208,16 @@ Function Get-EdgeNodeFromNSXManager { } Disconnect-NSXTServer * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null return $edge_nodes_list - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check the console output for more details." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-EdgeNodeFromNSXManager cmdlet." } } @@ -2407,19 +2268,15 @@ Function Get-NSXTComputeManagers { $compute_manager_list = $compute_manager_var.list().results.server Disconnect-NSXTServer * -Force -Confirm:$false -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Out-Null return $compute_manager_list - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check the console output for more details." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again." } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-NSXTComputeManagers cmdlet." } } @@ -2472,28 +2329,22 @@ Function Get-TanzuEnabledClusterStatus { if ($out.count -gt 0) { Write-PowerManagementLogMessage -Type INFO -Message "vSphere with Tanzu is enabled." return $True - } - elseif (([string]$ErrorMsg -match "does not have Workloads enabled") -or ([string]::IsNullOrEmpty($ErrorMsg))) { + } elseif (([string]$ErrorMsg -match "does not have Workloads enabled") -or ([string]::IsNullOrEmpty($ErrorMsg))) { Write-PowerManagementLogMessage -Type INFO -Message "vSphere with Tanzu is not enabled." return $False - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Cannot fetch information related to vSphere with Tanzu. ERROR message from 'get-wmcluster' command: '$ErrorMsg'" } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check the console output for more details." } - } - else { + } else { Write-PowerManagementLogMessage -Type ERROR -Message "Connection to '$server' has failed. Check your environment and try again" } - } - Catch { + } Catch { Debug-CatchWriterForPowerManagement -object $_ - } - Finally { + } Finally { Write-PowerManagementLogMessage -Type INFO -Message "Completed the call to the Get-TanzuEnabledClusterStatus cmdlet." } } @@ -2509,25 +2360,25 @@ Function Write-PowerManagementLogMessage { This cmdlet is used for logging messages on the console. .EXAMPLE - Write-PowerManagementLogMessage -Type ERROR -Message "Error message" - Logs as a error message and uses the assigned color. + Write-PowerManagementLogMessage -Type ERROR -message "Error message" + Logs as a error message and uses the assigned color. - Write-PowerManagementLogMessage -Type WARNING -Message "Warning message" + Write-PowerManagementLogMessage -Type WARNING -message "Warning message" Logs as a warning message and uses the assigned color. - Write-PowerManagementLogMessage -Type INFO -Message "Info message" + Write-PowerManagementLogMessage -Type INFO -message "Info message" Logs as a info message and uses the assigned color. - Write-PowerManagementLogMessage -Type EXCEPTION -Message "Exception message" + Write-PowerManagementLogMessage -Type EXCEPTION -message "Exception message" Logs as an exception message and uses the assigned color. - Write-PowerManagementLogMessage -Type INFO -Message "Exception message" -Colour Cyan + Write-PowerManagementLogMessage -Type INFO -message "Exception message" -colour Cyan Logs as an exception message and uses the the specified color. - + .PARAMETER Message The message to be logged on the console. - .PARAMETER type + .PARAMETER Type The type of the log message. The value can be one amongst ("INFO", "ERROR", "WARNING", "EXCEPTION"). .PARAMETER Colour @@ -2538,46 +2389,45 @@ Function Write-PowerManagementLogMessage { #> Param ( [Parameter (Mandatory = $true)] [AllowEmptyString()] [String]$Message, - [Parameter (Mandatory = $false)] [ValidateSet("INFO", "ERROR", "WARNING", "EXCEPTION")] [String]$type, + [Parameter (Mandatory = $false)] [ValidateSet("INFO", "ERROR", "WARNING", "EXCEPTION")] [String]$Type, [Parameter (Mandatory = $false)] [String]$Colour, - [Parameter (Mandatory = $false)] [String]$Skipnewline - ) + [Parameter (Mandatory = $false)] [String]$SkipnewLine + ) $ErrorActionPreference = 'Stop' - if (!$Colour) { + if (!$colour) { switch ($type) { "INFO" { - $Colour = "Green" + $colour = "Green" } "WARNING" { - $Colour = "Yellow" + $colour = "Yellow" } "ERROR" { - $Colour = "Red" + $colour = "Red" } "EXCEPTION" { - $Colour = "Magenta" + $colour = "Magenta" } default { - $Colour = "White" + $colour = "White" } } } $timeStamp = Get-Date -Format "MM-dd-yyyy_HH:mm:ss" - Write-Host -NoNewline -ForegroundColor White " [$timestamp]" - if ($Skipnewline) { - Write-Host -NoNewline -ForegroundColor $Colour " $type $Message" + Write-Host -NoNewline -ForegroundColor White " [$timeStamp]" + if ($skipNewLine) { + Write-Host -NoNewline -ForegroundColor $colour " $type $message" + } else { + Write-Host -ForegroundColor $colour " $type $message" } - else { - Write-Host -ForegroundColor $Colour " $Type $Message" - } - $logContent = '[' + $timeStamp + '] ' + $Type + ' ' + $Message + $logContent = '[' + $timeStamp + '] ' + $type + ' ' + $message if ($type -match "ERROR") { Write-Error -Message $Message } -} +} Export-ModuleMember -Function Write-PowerManagementLogMessage Function Debug-CatchWriterForPowerManagement { @@ -2588,9 +2438,9 @@ Function Debug-CatchWriterForPowerManagement { $lineNumber = $object.InvocationInfo.ScriptLineNumber $lineText = $object.InvocationInfo.Line.trim() $errorMessage = $object.Exception.Message - Write-PowerManagementLogMessage -message " ERROR at Script Line $lineNumber" -Colour Red - Write-PowerManagementLogMessage -message " Relevant Command: $lineText" -Colour Red - Write-PowerManagementLogMessage -message " ERROR Message: $errorMessage" -Colour Red + Write-PowerManagementLogMessage -Message " ERROR at Script Line $lineNumber" -Colour Red + Write-PowerManagementLogMessage -Message " Relevant Command: $lineText" -Colour Red + Write-PowerManagementLogMessage -Message " ERROR Message: $errorMessage" -Colour Red Write-Error -Message $errorMessage }