Thanks for the heads up on the API documentation. I'll save that for future reference.
I just completed the script and after using measure-command to check some execution times, it turns out that it wasn't the esxcli commands that were causing the excessive run times. By converting everything else over to get-view commands, the script is now very quick to execute.
I'll post the script here in case anyone can see any easy ways to improve it. I definitely cobbled it together pulling ideas from a few sources. Most notably it was adapted from this script by Arnim van Lieshout: Match VM and Windows harddisks using PowerShell | Arnim van Lieshout
PS this is my first time posting code, is there no way to do syntax highlighting for PowerShell??
#Load PowerCLI modues if ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) { . “C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1"} #Prompt for vCenter Server if no connection exists if(!$global:DefaultVIServers){$vCenterServer = Read-Host -Prompt "Enter the vCenter server you would like to connect to" Connect-VIServer $vCenterServer} else{Write-Host "You are connected to $Global:DefaultVIServers, continuing with connected server"} #Prompt for datacenter $Datacenter = Read-Host -Prompt "Enter the datacenter you would like to check for perennial reservations" #Get VMs from the specified datacenter that have a SCSI adapter set in physical sharing mode $DatacenterFilter = Get-View -ViewType Datacenter -Property Name -Filter @{"Name"="^$Datacenter$"} | select -ExpandProperty MoRef $MSCSVMsView = Get-View -ViewType VirtualMachine -SearchRoot $DatacenterFilter | Where-Object {$_.Config.Hardware.Device.SharedBus -eq "physicalSharing" -and $_.Config.Hardware.Device.DeviceInfo.Label -match "SCSI Controller"} #Get LUN ID of each RDM attached to the physically shared SCSI adapter on each VM foreach($MSCSVMView in $MSCSVMsView){ $VirtualSCSIControllers = $MSCSVMView.Config.Hardware.Device | Where-Object{$_.SharedBus -eq "physicalSharing" -and $_.DeviceInfo.Label -match "SCSI Controller"} foreach($VirtualSCSIController in $VirtualSCSIControllers){ $MSCSVirtualDiskDevices = $MSCSVMView.Config.Hardware.Device | Where-Object {$_.ControllerKey -eq $VirtualSCSIController.Key} $MSCSLUNIds += $MSCSVirtualDiskDevices.Backing.LunUuid}} #Filter for duplicate LUN IDs (due to multiple VMs in a cluster having the same LUNs presented) $MSCSLunIds = $MSCSLunIds | Sort -Unique #Check each host for the LUN. If the LUN exists, check for perennial reservation. If no reservation exists, set reservation. Foreach($VMHost in ($VMHosts = Get-View -ViewType HostSystem -SearchRoot $DatacenterFilter)){ $myesxcli = Get-EsxCli -VMhost $VMHost.Name Foreach($MSCSLUNId in $MSCSLUNIds){ if(!($MSCSCanonicalName = $VMHost.Config.StorageDevice.ScsiLun | Where-Object{$_.Uuid -eq $MSCSLUNId} | Select -ExpandProperty CanonicalName)){ Write-Host $MSCSLUNId "does not exist on " $VMHost.Name ". Skipping"} else{ if($myesxcli.storage.core.device.list($MSCSCanonicalName).IsPerenniallyReserved -eq "true"){ Write-Host "$MSCSCanonicalName is already perennially reserved on" $VMHost.Name ". Skipping"} else{ $myesxcli.storage.core.device.setconfig($false, $MSCSCanonicalName, $true) Write-Host "Added perennial reservation for $MSCSCanonicalName on " $VMHost.Name} }}}