VMware PowerShell – Useful HealthCheck Remediation Scripts
VMware PowerShell – Useful HealthCheck Remediation Scripts
I get to conduct and review the recommendations and findings from a VMware HealthCheck and Best Practice Reviews. Recently I conducted one and to help with remediation I pulled together some simple PowerShell Scripts to remove the manual effort.
Disconnect all Connected CDs from VMs
A very common finding is connected CDs preventing DRS and VMotion operations from occurring. This script solves that by disconnecting them all;
#add your cluster name to the $Cluster variable to target a cluster $Cluster = "Cluster_Name" $VMs = Get-Cluster -Name $Cluster | Get-VM #Comment out the lines above and uncomment the below variable to target all VMs connected to VC #VMs = Get-VM $CDConnected = @(Get-CDDrive $VMs | where { ($_.ConnectionState.Connected -eq "true") }) Foreach ($CD in $CDConnected) { Write-Host "Removing CD-ROM of:" $CD.Parent If ($CD -ne $null) { Set-CDDrive -connected 0 -StartConnected 0 $CD -Confirm:$false > $null } } Write-Host "Completed!"
This script has options for targeting a Cluster or if you comment out different lines, you can target every VM in an VC.
DCUI and ESXi Shell inactive Interactive timeouts
Another very common finding is that there is no timeout configured for inactive interactive sessions. The script below again can work on either a cluster or everything connected to VC basis and sets the advanced settings that control these. The values for each of these fields is configured in seconds, in the example below I’ve set this to ‘300’ which equates to 5 minutes.
#add your cluster name to the $Cluster variable to target a cluster $Cluster = "Cluster_Name" $VMHost = Get-Cluster -Name $Cluster | Get-VMHost #Comment out the lines above and uncomment the below variable to target all hosts connected to VC #$VMhost = Get-VMhost Get-VMHost $VMHost | Get-AdvancedSetting -Name 'UserVars.ESXiShellInteractiveTimeOut' | Set-AdvancedSetting -Value "300" -Confirm:$false Get-VMHost $VMHost | Get-AdvancedSetting -Name 'UserVars.DCUITimeOut' | Set-AdvancedSetting -Value "300" -Confirm:$false
Isolation.Tools.X.Disable
Almost common is that the security isolation settings for virtual machines are not configured. In the example below I’m working with the Isolation.Tools.Copy.Disable and Isolation.Tools.Paste.Disable settings.
$desired = @( @{ Name = 'isolation.tools.copy.disable' Value = $true }, @{ Name = 'isolation.tools.paste.disable' Value = $true } ) $Cluster = Get-Cluster 'Cluster_Name' $VMs = $Cluster | Get-VM ForEach($VM in $VMs) { $desired | %{ $setting = Get-AdvancedSetting -Entity $vm -Name $_.Name if($setting){ if($setting.Value -eq $_.Value){ Write-Output "Setting $($_.Name) Compliant!" } else{ Write-Output "Setting $($_.Name) Setting Non-Compliant!" Set-AdvancedSetting -AdvancedSetting $setting -Value $_.Value -Confirm:$true } } else{ Write-Output "Setting $($_.Name) Non-Compliant! Setting Must Be Created!" New-AdvancedSetting -Name $_.Name -Value $_.Value -Entity $vm -Confirm:$true } } }
This script is a little more complicated that those above.
It first creates a desired state variable for the isolation.tools.copy.disable and paste.disable settings. As these settings may or may not have been created in VMs it then discovers the state and applies the appropriate action. If the setting exists and it is desired it outputs ‘Compliant!’. If the setting exists and is not desired it outputs ‘ Setting Non-Compliant!’ and sets it back to the desired state. If the setting doesn’t exist the script outputs ‘Setting Must Be Created!’ and creates it with the desired state settings. In the example I’ve set a confirmation request for each change for the moment – when comfortable simply change ‘-Confirm:$true’ to ‘-Confirm:$false’.
Hopefully this is helpful to someone
Thanks
Simon