Category Archives: PowerCli

PowerCli: Migrating DRS rules to a new vCenter Management server

Image supplied by :
Image by :

Hello world ūüėČ

I haven’t written a blog post in forever, been busy with a big vSphere 6.0 distributed deployment.

Part of the vSphere 6 deployment i had to migrate DRS rules from a windows based vCenter deployment to a VCSA based deployment and copying all your DRS rules across can be a tedious process. I had a plethora of DRS rules to migrate across multiple clusters and was not looking forward to creating all the rules manually. Luckily  Luc Dekens and Matt Boren put together a DRSRule module which made the task easy. More info about the module can be found here.

I have put together a PowerShell script that will migrate all the rules for you.

Note : Updated to Import-Module and not PSSnapin for PowerCli 6.5.x

	 Created on:   	2016/10/21 11:28 AM
	 Created by:   	Xana Cloete
	 Filename:     	vsphere6_DRS_RULES_migration.ps1
	IMPORTANT !! - The script assumes that the source cluster and destination cluster have the same name.
		This script will retrieve all the specified cluster DRS information from the old vCenter management server and copy them to the new destination vCenter management server.
		Tested DRS rule migration from vCenter 5.5 (Windows Deployment) to vCenter 6.0 (Distributed appliance deployment)
	Ensure the powershell module "DRSRule" is installed. Follow DRSRule install guide. Run script from within PowerCLI
DRSRule – a DRS rules and groups module
.EXAMPLE .\vsphere6_upg_drs_rule_migration.ps1 -source-site MY_OLD_VC -cluster CLUSTER_NAME -destination-site MY_NEW_VC #> Param ( [String]$my_old_vc, [string]$the_cluster, [string]$my_new_vc ) if (!$my_old_vc -or (!$the_cluster) -or (!$my_new_vc)) { Throw "You need to supply all parameters." } # Import VIM automation core snapin if not loaded $imported = Get-Module -Name VMware.VimAutomation.Core -ErrorAction 'SilentlyContinue' if (!$imported) { Write-Host -ForegroundColor "yellow" "Importing VMware.VimAutomation.Core..." try { Import-Module VMware.VimAutomation.Core -ErrorAction 'Stop' } catch { Write-Host "Something went wrong. ""VMware.VimAutomation.Core"" snapin not found. Try execute the script from PowerCli" } } # Import DRS Module try { Import-Module DRSRule -ErrorAction 'Stop' } catch { write-host "DRSRule Module not found. Did you install it correctly ?. Check" } cls Write-Host "Welcome to the DRSRule migration tool." Write-Host "You will need to have full administrative access to both vCenter management serevers to proceed." Write-Host Write-Host "=============================================" Write-Host Write-Host "The info you supplied:" write-host Write-Host " Old_VC : $my_old_vc" Write-Host " New_VC : $my_new_vc" Write-Host " Cluster : $the_cluster" write-host Write-Host "=============================================" Read-Host "Hit Enter to continue." cls try { Connect-VIServer $my_old_vc -WarningAction 'SilentlyContinue' -ErrorAction 'Stop' } catch { write-host "Unable to connect to the old vCenter Management Server $my_old_vc" break } write-host "Connected to $my_old_vc." write-host "Collecting DRS Information. Please Wait." $drshostgrps = get-cluster -name $the_cluster| get-DRSVMHostGroup $drsvmgrps = get-cluster -name $the_cluster |Get-DRSVmGroup $drs_vm2hosts = get-cluster -name $the_cluster |Get-DrsVMToVMHostRule $drs_vm2vms = get-cluster -name $the_cluster |Get-DrsVMToVMRule write-host "Done." write-host "Disconnect from $my_old_vc" Disconnect-VIServer $my_old_vc -Confirm:$false try { Connect-VIServer $my_new_vc -WarningAction 'SilentlyContinue' -ErrorAction 'Stop' } catch { write-host "Unable to connect to the new vCenter Management Server $my_new_vc" break } write-host "Connected to $my_new_vc." write-host "Start applying DRS Information. Please Wait." foreach ($drshostgrp in $drshostgrps) { New-DRSVMHostGroup -name:$ -cluster:$drshostgrp.cluster -vmhost:$drshostgrp.vmhost write-host "DRSRule VMHost Groups Created." } foreach ($drsvmgrp in $drsvmgrps) { New-DrsVMGroup -name:$ -cluster:$drsvmgrp.cluster -vm:$drsvmgrp.vm write-host "DRSRule VM Groups created." } foreach ($drs_vm2host in $drs_vm2hosts) { new-DRSVMToVMHostRule -name:$ -cluster:$drs_vm2host.cluster -enabled:$drs_vm2host.enabled -mandatory:$drs_vm2host.mandatory -VMGroupName:$drs_vm2host.vmgroupname -AffineHostGroupName:$drs_vm2host.AffineHostGroupName -AntiAffineHostGroupName:$drs_vm2host.AntiAffineHostGroupName write-host "DRSRule VM to VMHost Rules created" } foreach ($drs_vm2vm in $drs_vm2vms) { New-DrsVMToVMRule -name:$ -cluster:$drs_vm2vm.cluster -enabled:$drs_vm2vm.enabled -KeepTogether:$drs_vm2vm.keeptogether -vm:$drs_vm2vm.vm write-host "DRSRule VM to VM Rules created." } write-host "All done. Please validate all rules manually on the clusters and vcenter management servers." write-host "Disconnecting from the VC's" Disconnect-VIServer * -confirm:$false write-host "Disconnected"


RDM : Perennial reservation

Are you hosting any MSCS workloads on ESXi ?
You probably forgot to set a perennial reservation. ¬†I’ve used RDM’s in small environments and never really noticed any issues with slow ESXi node startups…Until recently.

The infrastructure I currently look after has a 3 node MSQL cluster with more than 25 RDM’s presented to them. A few days ago I had to add ¬†another two ESXi nodes to the cluster and noticed that the nodes took longer than expected to start up. ¬† This issues was related to KB1016106.

Due to the amount of RDM’s presented to the ESXi cluster, I would have to automate the process to perennially reserve the RDM’s across all the nodes.

Step 1

Determine what disks are actually RDM’s and get the naa.ID.

# Import VIM automation core snapin if not loaded
$imported = Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction 'SilentlyContinue'
if (!$imported)
 Write-Host -ForegroundColor "yellow" "Importing VMware.VimAutomation.Core..."
 Add-PSSnapin VMware.VimAutomation.Core -ErrorAction 'Stop'
 Write-Host "Something went wrong. ""VMware.VimAutomation.Core"" snapin not found. Try execute the script from PowerCli"
$vchost = Read-Host "Please enter your VIserver FQDN/IP"

 try {
 Connect-VIServer $vchost -ErrorAction:Stop
 Write-Host -ForegroundColor Green "Connected to VI server"

 } catch {
 Write-Host -ForegroundColor Red "Unable to connect to the VI server"
$vm = Read-Host "Please enter the VM name"
$rdms = get-vm $vm | get-harddisk | Where-Object {$_.DiskType -eq "RawPhysical"}
foreach ($rdm in $rdms){
$observed = New-Object -TypeName PSObject
$observed | Add-Member -MemberType NoteProperty -Name Parent -Value $rdm.Parent
$observed | Add-Member -MemberType NoteProperty -Name Name -Value $
$observed | Add-Member -MemberType NoteProperty -Name ScsiCanonicalName -Value $rdm.ScsiCanonicalName
Write-Output $observed

Disconnect-VIServer $vchost -Confirm:$false

Step 2

Using the output obtained from step 1, execute this script against your individual ESXi nodes. You will need to use the “Scsi_CNAME” to reserve the devices on your ESXI node. ¬†Create a new file containing each naa.ID similar to this :



Now you can start setting the reservation on your ESXi node with this script.

Add-PSSnapin VMware.VimAutomation.Core
 try {
 Get-PSSnapin -Name "VMware.VimAutomation.Core" -ErrorAction:Stop
 Write-Host -ForegroundColor Green "Loaded ""VMware.VimAutomation.Core"" PSSnapin"
 } catch {
 Write-Host -ForegroundColor Red "Unable to load the required PS module ""VMware.VimAutomation.Core"""

$path_to_csv = Read-Host "Your path to the .csv input file"
$vmhost = Read-Host "Please supply your ESXi nodes FQDN"
$esxi_admin = Read-Host "Please specify user with root access"
$esxi_admin_pass = Read-Host "Please specify password"
$naas = Import-Csv $path_to_csv

foreach ($naa in $naas){
Connect-VIServer $VMHost -User $esxi_admin -Password $esxi_admin_pass 

 $myesxcli= get-esxcli $VMHost
 $rdmnaa = $naa.ScsiCanonicalName
 $$false, "$rdmnaa", $true)

Disconnect-VIServer $VMHost -Confirm:$false 

Step 3

Verify that your reservation have been set. Grab one or two random naa.ID’s and check.



Thats it, your done.

ESXi CIM Permissions


Using HP’s IRS (Insight Remote Support) to monitor ¬†your ESXi nodes hardware ?

Setting this up was not as straight forward as you think it should be. Turns out that the permissions required as outlined on VMware’s site here¬†is not enough to get HP’s IRS to work.

Use this script to configure the correct accounts and permissions.

Usage :
.\isr_usr_role.ps1 -filename *.csv
This script must be used to grant HP IRS access to individual ESXi nodes.

File Name : irs_usr_role.ps1
Author : Xana Cloete -
Requires : Powershell v3, Vmware vSphere PowerCli 5.5 or later
Version : 1.0

Param ([string]$filename)

# Global environment variables #
$esxi_user = "root"
$esxi_pass = "yourpass"
$command = ".\Script\ESXi\cmd.txt"
$putty_exe = ".\Script\ESXi\plink.exe"
$esxi_hosts = Import-Csv $filename

foreach ($esxi_host in $esxi_hosts){
try {
Connect-VIServer $ -User $esxi_user -Password $esxi_pass -ErrorAction:Stop
catch {
"Unbale to connect to the ESXi node. Please check node connectivity"
# start the SSH Services
Get-VMHost -Name $ | Get-VMHostService | Where-Object {$_.Key -eq "TSM-SSH"} | Start-VMHostService

#Create the hpris user account on the ESxi node.
New-VMHostAccount -Id $irs_user -Password $irs_pass -GrantShellAccess:$false

#Create a new role with CIM privileges
New-VIRole $vi_role -Privilege "CIM","System Management"

#Assign the hpris user account the role we just created.
Get-VMHost | New-VIPermission -Principal $irs_user -Role $vi_role -Propagate:$true

#SSH to the host and apply some security restrcition to the new user.

$ssh_host = $
echo y | .\plink.exe -ssh root@$ssh_host -P 22 -pw $esxi_pass -m $command

#Stop the SSH services
Get-VMHost -Name $ | Get-VMHostService | Where-Object {$_.Key -eq "TSM-SSH"} | Stop-VMHostService -Confirm:$false

#Disconnect from the ESXi node.
Disconnect-VIServer -Confirm:$false

Before executing the script you will need these files in the root of the script

  • Source input file containing the host DNS or IP info. You can get a sample here (sample)
  • plink.exe is required to execute some commands on the ESXi node. You can get that here.
  • You need a text file that contains all the commands that are executed remotely on the ESXi node. You can get a sample here (cmd.txt)



Set virtual machine IP with PowerCli


Ever wondered how you could configure IP’s on a¬†couple of newly created virtual machines using PowerCli. I created a quick script to configure IP addresses on some RHEL 6 virtual machines.
This script has some specific actions that had to be performed to set the hostname. This was done using “SED”.

You could edit it to do other OS’s as well. Just note that this is not supported on Server 2012. ¬†I’ll create a new post on how to do this for Server 2012.

Here are some prerequisites before you can actually execute this script:

  • VMTools needs to be installed and running.
  • Root/Admin credentails.
  • A .csv file containing the info you would like to inject in to the virtual machines. (name,ip, sub,gw,dns)

Copy  this script below.

#Import a csv containing all the info.
$vms = Import-Csv "c:\Users\User\Documents\Script\cloud_vms.csv"

#Start prcoessing each VM per line item.

foreach ($vm in $vms){

$script_block_eth0 = "sed 's/ONBOOT=no/ONBOOT=yes/' -i /etc/sysconfig/network-scripts/ifcfg-eth0"
Invoke-VMScript -ScriptText $script_block_eth0 -VM $ -GuestUser root -GuestPassword "P@ssw0rd" -ToolsWaitSecs 20
Get-VMGuestNetworkInterface -VM $ -Name "eth0" -GuestUser root -GuestPassword "P@ssw0rd" | Set-VMGuestNetworkInterface -Ip $vm.ip -Netmask $vm.mask -Gateway $vm.gateway -Dns $vm.dns1,$vm.dns2 -GuestUser root -GuestPassword "P@ssw0rd" -ToolsWaitSecs 30 -Confirm:$false

$vmname = $
$script_block_hostname = "sed 's/HOSTNAME=template/HOSTNAME=$vmname/' -i /etc/sysconfig/network"
Invoke-VMScript -ScriptText $script_block_hostname -VM $ -GuestUser root -GuestPassword "P@ssw0rd" -ToolsWaitSecs 20

Invoke-VMScript -ScriptText "service network restart" -VM $ -GuestUser root -GuestPassword "P@ssw0rd" -ToolsWaitSecs 20