#this code will scan all hosts in your vcenter and check for duplicate IPs. You can narrow the scan by placing a get-cluster or get-datacenter object when loading the “$thedata” var.

$thedata = get-vmhost | Get-VMHostNetwork | Select Hostname, VMkernelGateway -ExpandProperty VirtualNic
$report = @()
$temp = $thedata | %{$_.ip}
$h = @{}
$temp | foreach {$h[“$_”] += 1}
$dups = $h.keys | where {$h[“$_”] -gt 1}
foreach($a in $dups){
$report += $thedata | where {$_.ip -eq $a} | select hostname,ip,ManagementTrafficEnabled,VMotionEnabled
$report | ft

#sample output :
#HostName     IP                        ManagementTrafficEnabled       VMotionEnabled
#———-         ———-             ———                                             —————-
#esx01        False                                                True
#esx06       False                                                 True

#if you want the report to include more information you can edit the “report +=” line and add extra fields  (to the select area).
#example : You can add the Devicename and PortGroupName if you need help finding the exact vmk with the dup IP.
$report += $thedata | where {$_.ip -eq $a} | select hostname,ip,devicename,portgroupname,ManagementTrafficEnabled,VMotionEnable

This code will pull the list of vlans on your vDS trunk, pull the vlans of each port group on the vDS, then compare the two to find any misconfigurations.
This can help identify if any vDS Trunk is missing vlans (for vDS healthcheck to work right.)
Help find vDS objects that have a vlan configured on the trunk but no port group to use it.
— Ultimately.. this is a Health Check for the vDS Health Check.

$report = @()
$vds = get-vdswitch

foreach($a in $vds){
$pgs = $a | get-vdportgroup
$uplinkvlans = @()
$uplinkvlantypecheck = $pgs| ?{$_.name -like “*Uplinks*”} | %{$_.VlanConfiguration.vlantype}
if($uplinkvlantypecheck -eq “Trunk”){
$uplinkvlanrange = $pgs| ?{$_.name -like “*Uplinks*”} | %{$_.VlanConfiguration.ranges}
foreach($b in $uplinkvlanrange){
if($b.StartVlanId -eq “0” -and $b.EndVlanId -eq “4094”){$report += $a.name + ” Trunk is configured with ALL VLANs — 0-4094″ }else{
$start = $b.StartVlanId
$end = $b.EndVlanId
$uplinkvlans += $start..$end
} #end Else
} #end foreach vlan on trunk
} #end if trunk
else{$uplinkvlans = $pgs| ?{$_.name -like “*Uplinks*”} | %{$_.VlanConfiguration.vlanid}
} #end else

#end uplink vlan collection

$vmPGs = $pgs | ?{$_.name -notlike “*Uplinks*”}
$pgvlans = @()
foreach($apg in $vmPGs){
if(($apg.VlanConfiguration.vlantype) -eq “Trunk”){
$pgvlanrange = $apg | %{$_.VlanConfiguration.ranges}
foreach($b in $pgvlanrange){
$start = $b.StartVlanId
$end = $b.EndVlanId
$pgvlans += $start..$end
} #end foreach vlan in PG
} #end if trunk
else{$pgvlans += $apg| %{$_.VlanConfiguration.vlanid}
} #end else
} #end port group vlan collection

$pgvlans = $pgvlans | select -unique
$checkit = Compare-Object $uplinkvlans $pgvlans
if($checkit.inputobject.count -gt 0){
foreach($aa in $checkit){
if($aa.sideindicator -eq “<="){$texta = "PortGroup"} if($aa.sideindicator -eq "=>“){$texta = “Trunk”}
$report += $a.name + ” ” +$texta+” is missing vlan “+ $aa.inputobject

So you want to Pin a VM to a host huh?
Maybe for some network mirror or span port entertainment?

Here is how you do it pcli style:

#set your vars:

$thecluster = “pcli-cluster1”
$thevmhost = “esx1.pcli.me”
$thevm = “vm1”
$VMGroupName = “MyVMGroupName”
$HostGroupName = “MyHostGroupName”
$rulename = “MyAffinityRuleName”

#paste the code:

$cluster = Get-Cluster $thecluster | Get-View
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$group = New-Object VMware.Vim.ClusterGroupSpec
$group.operation = “add”
$group.Info = New-Object VMware.Vim.ClusterVmGroup
$group.Info.Name = $VMGroupName
Get-VM -Name $theVM | %{$group.Info.VM += $_.Extensiondata.MoRef}
$spec.GroupSpec += $group
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$group = New-Object VMware.Vim.ClusterGroupSpec
$group.operation = “add”
$group.Info = New-Object VMware.Vim.ClusterHostGroup
$group.Info.Name = $HostGroupName
Get-VMHost -Name $TheVMHost | %{$group.Info.Host += $_.Extensiondata.MoRef}
$spec.GroupSpec += $group
#Make the Rule
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$rule = New-Object VMware.Vim.ClusterRuleSpec
$rule.operation = “add”
$rule.info = New-Object VMware.Vim.ClusterVmHostRuleInfo
$rule.info.enabled = $true
$rule.info.name = $RuleName
$rule.info.mandatory = $true
$rule.info.vmGroupName = $VMGroupName
$rule.info.affineHostGroupName = $HostGroupName
$spec.RulesSpec += $rule

I’m sure someone can reduce the code but I left it broken out here to provide the section view.
IE : If you only want to create a Host group, take the middle part of the script.

#Looks like playing with vFlash can cause some vCenter Webclient issues….
#KB = http://kb.vmware.com/kb/2072392

#If you want to “remove” all vflash from your hosts so you can get things working again, you can use PowerCLI.
#1 – Download the “Extensions” for vflash (and vsan) here
– – https://labs.vmware.com/flings/powercli-extensions
#2 – Place that folder into your powershell > Modules directory.
– – The most common places is : C:\Windows\System32\WindowsPowerShell\v1.0\Modules
#3 – Import the Extensions : Import-Module VMware.VimAutomation.Extensions
#4 – Verify that the Extensions loaded : get-command -Module VMware.VimAutomation.Extensions
– – Output should show ten new command-lets
#5 – Review your current vFlash config :
– – $hosts = get-cluster pcli.me | Get-VMHost
– – Get-VMHostVFlashConfiguration -VMHost $hosts
– – Output will look close to this:
– – – Name CapacityGB SwapCacheReservationGB Extents
– – – esx1.pcli.me 731 0 {eui.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:P1}
– – – esx2.pcli.me 731 0 {eui.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:P1}

#6 – Remove the config with this command (you can make it smaller but this command worked best for me)
– – get-vmhost esx1.pcli.me| get-VMHostVFlashConfiguration | Set-VMHostVFlashConfiguration -RemoveVFlashResource
– – get-vmhost esx2.pcli.me| get-VMHostVFlashConfiguration | Set-VMHostVFlashConfiguration -RemoveVFlashResource

#7 – Then to verify that things are removed, throw another Get-VMHostVFlashConfiguration -VMHost $hosts


This One Line of code will list the count of VMs on each datastore in the Datastore Cluster
Just edit the datastore cluster name below:

foreach($a in (get-datastorecluster MyDataStoreCluster | get-datastore)){write-host $a ($a | get-vm).count}

List will look like this:

Datastore-1 12
Datastore-2 10
Datastore-3 9
Datastore-4 1
Datastore-5 42

This will check your ESXi host and tell you which LUNs support VAAI primitives.

$hostname = “myhost.pcli.me”

$report2 = @()
$Datastorelist = get-vmhost $hostname | Get-Datastore
foreach ($ds in $datastorelist) {
$reportrow = “” | Select DatastoreName,CName
$reportrow.DatastoreName = $ds.Name
$reportrow.CName = $ds.extensiondata.info.vmfs.extent | %{$_.diskname}
$report2 += $reportrow
$temp = get-esxcli -vmhost $hostname | %{$_.storage.core.device.vaai.status.get()}
$report = @()
foreach($a in $temp){
$ReportRow = “” | Select-Object Hostname,LunName,Device,ATSStatus,CloneStatus,DeleteStatus,VAAIPluginName,ZeroStatus
$ReportRow.hostname = $hostname
$ReportRow.LunName = $report2 | where {$_.cname -eq $a.Device} | %{$_.datastorename}
$ReportRow.Device = $a.Device
$ReportRow.ATSStatus = $a.ATSStatus
$ReportRow.CloneStatus = $a.CloneStatus
$ReportRow.DeleteStatus = $a.DeleteStatus
$ReportRow.VAAIPluginName = $a.VAAIPluginName
$ReportRow.ZeroStatus = $a.ZeroStatus
$report += $reportrow
$report | Ft -a

This code will fully migrate a powered on VM to another cluster (On the same vcenter)
This will migrate the VMs storage and the memory state with one command.

### Set your vars
$vmname = “MyVM”
$going2Host = “MyHost.pcli.me”
$datastorename = “Datastore-1”

Get-VM $vmname | Move-VM -Destination $going2Host -Datastore (get-datastore “$datastorename”) -confirm:$false -RunAsync:$true


####### ####### ####### ####### ####### ####### #######
You can use this code if you want to select the datastore cluster instead of a single LUN.
This may error out if you have SDRS enabled on the VM.
Check this code to disable it before running the migration line below or just disable it via the GUI : http://www.pcli.me/?p=159

$vmname = “MyVM”
$going2Host = “MyHost.pcli.me”
$datastoreclustername = “MyDataStoreCluster”

Get-VM $vmname | Move-VM -Destination $going2Host -Datastore (get-datastorecluster “$datastoreclustername”) -confirm:$false -RunAsync:$true

VMware Links:

This code will reconfigure your Storage DRS Cluster Settings for a single VM.

### Set your vars ###
$theVM = “MyVM”
$theDatastoreCluster = “MyStorageCluster”

$SRMan = Get-View StorageResourceManager
$DSCluster = Get-DatastoreCluster -Name $theDatastoreCluster
$spec = New-Object VMware.Vim.StorageDrsConfigSpec
$DSCluster.ExtensionData.PodStorageDrsEntry.StorageDrsConfig.VmConfig |
where {(Get-View $_.VM | Select -ExpandProperty Name) -like $theVM} | %{
$entry = New-Object VMware.Vim.StorageDrsVmConfigSpec
$entry.Operation = “edit”
$entry.Info = $_
$entry.Info.Enabled = $false
$spec.vmConfigSpec += $entry

This code will aid in the automation of deleting Host Affinity rules via PowerCLI.

Currently the Get-DRSRule and Remove-DRSRule command does not allow the removal of VM-Host Affinity rules.
This code block will get a “VMHost Affinity” rule based on a string filter then delete it along with the VM group + Host group attached to it.
If you don’t want to delete the VM and host group, just remove the sub group specs below.

Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer “MyVcenter.pcli.me” -User “XX” -password “XX”

$Mycluster = get-cluster “MyCluster”
$therules = get-drsrule -cluster $mycluster -type vmhostaffinity | where {$_.name -match “RuleNameHere”}

foreach($rule in $therules){
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.rulesSpec = New-Object VMware.Vim.ClusterRuleSpec[](1)
$spec.rulesSpec[0] = New-Object VMware.Vim.ClusterRuleSpec
$spec.rulesSpec[0].operation = “remove”
$spec.rulesSpec[0].removeKey = $rule.key
$spec.rulesSpec[0].info = New-Object VMware.Vim.ClusterVmHostRuleInfo
$spec.rulesSpec[0].info.name = $rule.name
$spec.rulesSpec[0].info.vmGroupName = $rule.extensiondata.vmgroupname
$spec.rulesSpec[0].info.affineHostGroupName = $rule.extensiondata.AffineHostgroupname
$spec.groupSpec = New-Object VMware.Vim.ClusterGroupSpec[](2)
$spec.groupSpec[0] = New-Object VMware.Vim.ClusterGroupSpec
$spec.groupSpec[0].operation = “remove”
$spec.groupSpec[0].removeKey = $rule.extensiondata.vmgroupname
$spec.groupSpec[0].info = New-Object VMware.Vim.ClusterVmGroup
$spec.groupSpec[0].info.name = $rule.extensiondata.vmgroupname
$spec.groupSpec[1] = New-Object VMware.Vim.ClusterGroupSpec
$spec.groupSpec[1].operation = “remove”
$spec.groupSpec[1].removeKey = $rule.extensiondata.AffineHostgroupname
$spec.groupSpec[1].info = New-Object VMware.Vim.ClusterHostGroup
$spec.groupSpec[1].info.name = $rule.extensiondata.AffineHostgroupname
$_this = Get-View (get-cluster $Mycluster)
$_this.ReconfigureComputeResource_Task($spec, $true)

Here are some extra vars if you want to make a report from each rule”
#The name of the Rule

#name of the VM group and host group assigned to the Rule
$vmgroupname = $rule.extensiondata.vmgroupname
$hostgroupname = $rule.extensiondata.AffineHostgroupname

#list of VMs by name in the VM Group
$vmlist = get-vm -id $rule.vmids | %{$_.name}

#list of hosts by name in the Host group
$hostlist = get-vmhost -id $rule.AffineHostIds | %{$_.name}

VMware Links:

This code will grab the vmotion count that you see on the summary page of your cluster object. This counter is total vmotions to include system and manual migrations. If you want the manual ones you will need to parse out your vievents.

Get-Cluster | Select Name,@{N=”vMotion”;E={$_.ExtensionData.Summary.NumVmotions}}