A. Mikkelsen

VMware ESX scripts, commands, tools and other nice to know things that will make your virtualization days easier!!!!

Browsing Posts in ESXi

If you ever need to clear the list of ignored SSL certificates (hosts or vCenters) that you use from the VIclient.

  1. Open the “Registry Editor”
  2. Locate the key named “HKEY_CURRENT_USER\Software\VMware\Virtual Infrastructure Client\Preferences\UI\SSLIgnore”
  3. Delete all certificates needed.


When connecting some storage systems to vSphere, vSphere sometime doesn’t select the most optimal multipathing policy.

I came across the above problem when adding an EMC VPLEX storage system to a  large vSphere 4.1 installation.
vSphere selected the Fixed path multipathing policy. In smaller environments this isn’t normally a problem , but when a Fixed policy is selected in a large environment with multiple datastores. vSphere selects the first path for each datastore, this results in almost all datastores uses the same path. The result is that the path will be overloaded.

EMC’s best practices for EMC VMAX/VPLEX is to use Fixed policy with static load balancing or to use EMC PowerPath.
In our environment Fixed or PowerPath wasn’t an option as we have multiple hosts and datastores, so in close communication with EMC we chose to change the multipathing policy to Round Robin..
EMC has once now informed us that RR is only an option (not the best) if PowerPath or Fixed is not an option.

Changing the policy for a few LUN’s won’t take long, if you only have a few hosts and a few datastores, but if you have multiple hosts with multiple datastores, the task is massive.

Using Powershell and EsxCli the task is very easy and extremely fast.
Thanks to Arnim van Lieshout (http://www.van-lieshout.com/2011/01/esxcli-powercli/) for the basic script.

The below script illustrates how to set RoundRobin and not Fixed, this will be updated ASAP.
Until then take a look at this post from LucD http://communities.vmware.com/message/1774139 

<pre>function FuncMail {
 param($To, $From, $Subject, $Body, $smtpServer)
 $msg = new-object Net.Mail.MailMessage
 $smtp = new-object Net.Mail.SmtpClient($smtpServer)
 $msg.From = $From
 $msg.Subject = $Subject
 $msg.IsBodyHtml = 1
 $msg.Body = $Body

#load Vmware Module
if ((Get-PSSnapin | Where-Object { $_.Name -eq "VMware.VimAutomation.Core" }) -eq $null) { Add-PSSnapin VMware.VimAutomation.Core }

# ----------- Variables ---------------
$vcServer = "vcenterserver"
$vCenterUser = "vcenterusername"
$vCenterPWD = "vcenterpassword"
$DC = "*" # Use * for all DC else replace * with datacenter name
$cluster = "*" # Use * for all Clusters in DC else replace * with cluster name

# LUN settings
$LUNType = "EMC Fibre Channel Disk*"
$psp = "VMW_PSP_RR"
$satp = "VMW_SATP_INV"
$iops = 10

$esxUser = "esxuser-root"
$esxPWD = "esxuserpassword"

# Email
$strEmailTo = "to@mail.com"
$strEmailFrom = "from@mail.com"
$strEmailSubject = "PSP info '$vcServer' "
$strEmailSMTP = "smtpserver.com"

$strHeadHTML = "<STYLE TYPE='text/css'>"
$strHeadHTML += "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$strHeadHTML += "TH{border-width: 1px;padding: 10px;border-style: solid;border-color: black; background-color:thistle}"
$strHeadHTML += "TD{border-width: 0px;padding: 0px;padding-right: 5px;padding-left: 5px;border-style: solid;border-color: black}"
$strHeadHTML += "</STYLE>"

$strBodyHTMLStart = "<H3> Setting PSP multipath & IOPS : "
$strBodyHTMLStart += Get-Date -Format g
$strBodyHTMLStart += "</H3>"
$strBodyHTMLStart += "<TABLE><TR> <TH>vCenter</TH> <TH>Datacenter</TH> <TH>Cluster</TH> <TH>Host</TH> <TH>Device</TH> <TH>SATP</TH> <TH>Old PSP</TH> <TH>New PSP</TH> <TH>IOPS</TH> <TH>Old Paths</TH> <TH>New Paths</TH></TR>"

$strBodyHTMLinfoStart = "<H3> PSP multipath & IOPS not set : "
$strBodyHTMLinfoStart += Get-Date -Format g
$strBodyHTMLinfoStart += "</H3>"
$strBodyHTMLinfoStart += "<TABLE><TR> <TH>vCenter</TH> <TH>Datacenter</TH> <TH>Cluster</TH> <TH>Host</TH> <TH>Device</TH> <TH>SATP</TH> <TH>PSP</TH> <TH>Paths</TH></TR>"

# ---------- Logic (Don't Change) --------------------

$strBODYHTML = ""
$strBodyExcludeHTML = ""

#Connect to vCenter
Connect-VIServer $vcServer -User $vCenterUser -Password $vCenterPWD| Out-Null

#Get Datacenter Clusters
$arrDC = Get-Datacenter -Name $DC | Sort Name
 foreach($objDC in $arrDC){

 #Get Cluster list
 $arrCluster = Get-Cluster -Location $objDC -Name $cluster | Sort name
 foreach($objCluster in $arrCluster){

 #Connect to ESX hosts in cluster
 foreach ($esx in Get-VMHost -Location $objCluster | Sort Name) {

 Connect-VIServer $esx -User $esxUser -Password $esxPWD | Out-Null

#Retrieve the esxcli instances and loop through them
 foreach($esxcli in Get-EsxCli -Server $esx.name) {

 #Write-Host $esx.Name -BackgroundColor Red

 # Change PSP for EMC VPLEX/VMAX devices
 $arrDevice = $esxCli.nmp.device.list() | where {$_.PathSelectionPolicy -ne $psp -and $_.DeviceDisplayName -like $LUNType}
 foreach($myDevice in $arrDevice){
 #Write-Host "Updating $($myDevice.Device)" -ForegroundColor green
 $esxCli.nmp.device.setpolicy($null, $myDevice.Device, $psp)

 $newPSP = $esxCli.nmp.device.list($myDevice.device)
 $newIOPS = $esxcli.nmp.roundrobin.getconfig($myDevice.device)
 $strBODYHTML += "<TR> <TD>$($vcServer)</TD> <TD>$($objDC.Name)</TD> <TD>$($objCluster.Name)</TD> <TD>$($esx.Name)</TD> <TD>$($myDevice.Device)</TD> <TD>$($myDevice.StorageArrayType)</TD> <TD>$($myDevice.PathSelectionPolicy)</TD> <TD>$($($newPSP[0]).PathSelectionPolicy)</TD> <TD>$($newIOPS.IOOperationLimit)</TD> <TD>$($myDevice.WorkingPaths)</TD> <TD>$($($newPSP[0]).WorkingPaths)</TD></TR>"

 # Changes not set on
 $arrInfoDevice = $esxCli.nmp.device.list() | where {$_.PathSelectionPolicy -ne $psp -and $_.DeviceDisplayName -like $LUNType}
 foreach($myInfoDevice in $arrInfoDevice){
 $strBODYHTMLinfo += "<TR> <TD>$($vcServer)</TD> <TD>$($objDC.Name)</TD> <TD>$($objCluster.Name)</TD> <TD>$($esx.Name)</TD> <TD>$($myInfoDevice.Device)</TD> <TD>$($myInfoDevice.StorageArrayType)</TD> <TD>$($myInfoDevice.PathSelectionPolicy)</TD> <TD>$($myInfoDevice.WorkingPaths)</TD></TR>"

 #Change the default PSP for my SATP
 $esxcli.nmp.satp.setdefaultpsp($psp,$satp) | Out-Null
 Disconnect-VIServer $esx.name -Confirm:$false
#Disconnect from vCenter
Disconnect-VIServer $vcServer -Confirm:$false | Out-Null

$strBodyHTMLEnd = "</TABLE>"
$strBodyHTMLinfoEnd = "</TABLE>"

# Collect the HTML
$strHTML = "<HTML><HEAD>"
$strHTML += $strHeadHTML
$strHTML += "</HEAD><BODY>"
$strHTML += $strBodyHTMLStart
$strHTML += $strBODYHTML
$strHTML += $strBodyHTMLEnd
$strHTML += $strBodyHTMLinfoStart
$strHTML += $strBODYHTMLinfo
$strHTML += $strBodyHTMLinfoEnd
$strHTML += "</BODY></HTML>"

# Email the collected data
FuncMail -To $strEmailTo -From $strEmailFrom -Subject $strEmailSubject -Body $strHTML -smtpServer $strEmailSMTP

Script explained

Line 20-24:
Add you vCenter server name and the logon credentionls.

Line 27-30:
LUNTYPE, is the storage type you want to change PSP and SATP for (you can set this to *, if you want you set the PSP and SATP for all datastores.
PSP, is the multipathing policy you want to change to.
SATP, is the storage array type you want to change the default to.
IOPS, is the number of IO’s to be send, before switching to the next path. vSphere default is 1000, EMC recommends 1, but I found 10 to work for me.
Stephen Foskett has explained what is PSP and SATP in plain English  http://blog.fosketts.net/2011/06/06/vmware-esx-vsphere-satp-psp-support-matrix/.

Line 33-34:
Change the user to a user with root privileges.
Change the password to correspond with the user.

Line 37-40:
Change the info to receive an report of what has been changed.

Line 92-93:
Sets the PSP and IOPS for each datastore.

Line 95-96:
Retrieves the new settings (for verification) for  each datastore.

Line 101-107:
Generates a list of datastores, where the PSP setting wasn’t able to be set.
Run the script again to set them.

Line 111:
Sets the hosts default datastore PSP and SATP.
If your hosts connect to multiple different storage systems, I wouldn’t recommend setting this, but it’s to you.

If you want to see an output on the screen of the progress of the script, uncomment the lines 85, 91

Download the full RoundRobin script here.

An exampel of what a report can look like:

Post is updated after input from Josh Coen, www.valcolabs.com.

Friday I was at a customer to upgrade their ESXi 4.0 (free) to version 4.1.
This should have been an easy task, download CD, burn it and install.

This wasn’t the case, the new ESXi 4.1 wouldn’t install, it kept freezing during the extract of the cim.vgz file.
The problem occurred on both the Dell custom of ESXi 4.0 U1 and the standard ESXi 4.1.
We googled and googled but didn’t find a solution – in the end we blamed the error on the old bios version 1.1.4.

To my luck the customer still had the CD we installed the server with 9 months ago – ESXi 4.0.

We installed ESXi using the old CD and then everything was working – but we still needed to upgrade to ESXi 4.1.

So now what to do …….

Normally you use the hostupdate utility or the Remote CLI but the hostupdate utility is not included in the free version of ESXi and the we didn’t want to install the Remote CLI on the computer.
To my luck I had the hostupdate utility installed but i kept getting this error when trying to upgrade the ESXi host.

“Failed to read the upgrade package metadata.xml”

The solution to our problem was:

  1. Since it was a ESXi free with out support, we decided to use the “ESXi command line interface”, witch is unsupported.
    Follow this guide to enable it (http://www.bauer-power.net/2010/04/vmware-esxi-hack-to-allow-ssh.html).
  2. Download and extract the upgrade ZIP file from VMware.
  3. From the VIclient, upload the extracted files to the host datastore, using the “datastore browser”
    – I uploaded the files to a folder named “upgrade”
  4. Put the ESXi host in “Maintance Mode”
    – Since it is a ESXi, this can only be done when all VM’s are powered off.
  5. Connect the the ESXi console using ex. Putty.exe.
  6. Navigate to the upgrade directory.
    cd /vmfs/volumes/local-datastore/upgrade
  7. Begin the upgrade process
    esxupdate update -m metadata.zip
  8. When the upgrade is finished, reboot the host.
  9. To verify the new build number:
    – Connect to the host using the VIclient
    – Select the host
    – Choose the “Summery” tab
    – Verify that the ESXi version number and build has been updated

Time keeping in a virtual environment can be a challenge to setup.

To help you, VMware has maintained a KB on the subject.

The KB presents best practices for achieving accurate timekeeping in Windows Guest operating systems. These recommendations include a suggested configuration for timesynchronization in the guest and on the host.

A more specific guide also exists for Windows and Linux servers:
For Windows read:
For Linux read:

It’s great reading, but very nerdy 🙂

If you are looking for a easy and simple guide for setting up iSCSI on vSphere (ESX 4.x) you might want to take a look at this guide from www.techhead.co.uk

Yesterday I by mistake extended a disk on a VM that had snapshots.
Using vmkfstools.
Kind of like this thread (http://communities.vmware.com/thread/238035).

This resulted in the following PowerOn error:

Failed to power on Servername on Host in Cluster:

Cannot open the disk ‘/vmfs/volumes/LUN/Folder/VM.vmdk’
Reason: The parent virtual machine disk has been modified since the child was created

The server was a database server so I had no choice than to fix it.

I tried the following with no luck:

  • Reverting to snapshot didn’t help – (Don’t try this if you don’t have a good backup)
  • Shrinking the vmdk again using vmkfstools – (This has not been possible since ESX 3.0)

Then I tried to use VMware Converter to do a V2V and in the first try (all defaults) that didn’t help the VM started with a BSOD.I tried again using the Converter but this time I changed one default parameter.In the “View/Edit Options” tap, remove the check mark in “Reconfigure destination virtual machine” and click YES to the warning.Removing the reconfigure option saved my day.
The VM started and I was able to restore the latest files from backup.

VMware have released a demo on YouTube that shows a “must have” for PowerShell users who automate and manage vSphere and vCenter through PowerShell.

The project is named “Onyx” and works like a middelware between the vCenter Client and the vCenter Server.
Onyx is unfortunately still in a private beta and therefore not acceble to the Public…….. 🙁

Read more on rtfm-ed.co.uk.

Or read more on the “get-scripting podcast” blog

Have you ever needed to verify the security or hardened state of you ESX hosts?

If yes, then these tools from ConfigureSoft.com or TripWire.com will help you make the process easier.
If no, take a look at the tools anyway – it’s always nice to know if your “babies” are safe ;-).

Compliance Checker for VMware ESX, checks the compliance of VMware ESX hosts against VMware hardening guidelines and Center for Internet Security (CIS) benchmarks.

Compliance Checker for PCI DSS, checks the compliance of servers and desktops against PCI DSS v1.2 requirements as specified by PCI Security Standards Council.

TripWire ConfigCheck

Read a great how to.

2 years ago a VMUG user in Denmark created a Ubuntu VM that could graficily could show the develeoment of the amount of VM’s in a Cluster.

Unfurtionally someone stole my labtop and the VM :-).

So I had to create a new. And of cause it’s based on PowerShell ;-).

The webpages shows the following information

  • Amount of VM’s in each Cluster
  • Amount of Hosts in each Cluster
  • The size of each Datastore and the amount of free disk space

Get the source code in the Download section under Vi Toolkit for Windows

Today I had to upgrade all our Jumphost VM’s from 256MB to 512MB of memory (more than 200 VM’s).
There are two ways accomplice this.

1. Do it manually (Very time consuming)

2. Script it with PowerShell

As the lazy person I am I decided that scripting was the way forward.
The script I came up with is as follows:

Connect-VIServer "vi_servername" -User "vi_username" -Password password"

# Select all VM's that have less than 512MB and change the Memory to 512MB
foreach ($vm in Get-VM | Select Name,MemoryMB | Where-Object{$_.MemoryMB -lt "512"}){
Set-VM $vm.Name -MemoryMB "512" -Confirm:$FALSE

To suppress the script to prompt for acceptance each time I added the following option

The script easily be changed to add or update other VM hardware settings.
– Number of CPU’s (Set-VM <vm-name> -NumCpu 2)

– Rename VM (Set-VM <vm-name> -Name “NewName”)

Find more options and ideas in the “Automating VMware with PowerShell – Hands-On Lab” from VMworls 2008.

Just remember if a VM is running you have to poweroff or shutdown the VM before the changes will take effect.
This is because a restart or reset does’t reload the vmx file.


The script is now updates so it also implements the following settings

  • Sets Memory Reservation to half of the amount of ram.
  • Sets Memory Limit to “Unlimited”
  • Sets the VM to check for new VMware Tools on PowerOn.
  • Sets the VM to sync time from host.

Take a look at the scripts here.

Powered by WordPress Web Design by SRS Solutions © 2018 A. Mikkelsen Design by SRS Solutions