Last week I was adding new datastores to a cluster for a provider whose best practices recommended a Round Robin multipath policy, changing paths with every iop. There is a VMware knowledge base article on how to do this - https://kb.vmware.com/s/article/2069356 - which details the CLI commands that need to be run on every host in the cluster for every datastore that needs to be configured. Attached to the KB article is a list of the PowerCLI commands that will also implement the same configuration.
When pressed for a choice, either - enabling SSH on each host, logging in, running the commands, logging out, disabling SSH - or - running PowerCLI commands remotely against the vCenter Server - the easiest option seems obvious.
So, I’ve written a script that will do this for multiple datastores against all hosts in a cluster. The latest version is available at https://github.com/nelons/psscripts/blob/master/vsphere/Set-ESXRoundRobinForDatastore.ps1, or the version at the time of writing this article is displayed below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# Configuration variables.
# The FQDN (or IP) of your vCenter Server.
$vCenterServer = "vcenter.dnsname";
$ClusterName = "cluster";
# An array of datastore names that you want to convert.
$datastores = @("Datastore Name");
# When should the path be switched ?
$iops_switch = 1;
Connect-VIServer $vCenterServer | out-null;
$hosts = Get-VMHost -Location $ClusterName | Where-object {($_.ConnectionState -like "Connected")} | Sort-Object Name
# This will get the datastores from the array at the top of the file.
$ds_id = $datastores | ForEach-Object { Get-Datastore -Name $_ } | ForEach-Object { return $_.ExtensionData.Info.Vmfs.Extent.DiskName; }
# Uncomment this line if you want to ignore the datastore name array
# and instead filter on the start of the datastore name.
# Remember to update the part of the line that starts with "start of datastore name" !
# Remember to comment out the datastore array line above !
#$ds_id = $datastores | ForEach-Object { Get-Datastore | { $_.Name.StartsWith("Start of datastore name"); } } | ForEach-Object { return $_.ExtensionData.Info.Vmfs.Extent.DiskName; }
$hosts | ForEach-Object {
$esx = $_;
Write-Output "$($esx.Name): Checking LUNs.";
$ds_id | ForEach-Object {
$lun = $esx | Get-SCSILun -LunType Disk -CanonicalName $_;
if ($null -ne $lun) {
# Make sure it is RoundRobin
if ($($lun.MultipathPolicy) -notlike “RoundRobinâ€) {
Write-Output "$($esx.Name), $($_): Setting multipath policy to RoundRobin.";
$lun | Set-ScsiLun -MultipathPolicy RoundRobin | out-null;
}
if ($($lun.CommandsToSwitchPath) -ne $iops_switch) {
# Set the IOPS switch.
Write-Output "$($esx.Name), $($_): Settings commands to switch path parameter to 1.";
$lun | Set-ScsiLun -CommandsToSwitchPath $iops_switch | out-null;
}
}
}
}
Disconnect-VIServer -Force -Confirm:$False;
|