Sep 022014
 

Quick Report script to find those VMs that span more than one Numa Boundary.
Meaning:  If your ESX host has two – quad core CPUs and your VM is configured for six vCPUs,  then your VMs is spanning two NUMA boundaries.
Also, if your VM is configured with 32GB of memory but you only have 24GB of ram Per CPU Socket, your VM will cross memory NUMA boundaries!

Add-PSSnapin VMware.*
$report=@()

Connect-VIServer myvcenter.pcli.me

$temp = get-view -viewtype virtualmachine -property name,runtime.host,config.hardware
$temphost = get-view -viewtype hostsystem -property name,hardware.cpuinfo,hardware.MemorySize
foreach($a in $temp){
$row = “” | select VMname,VMTotalvCPUs,VMSockets,VMCores,CPUCalcNumaNodes,MemCalcNumaNodes
$row.VMname = $a.name
$row.VMTotalvCPUs = $a.config.hardware.numcpu
$row.VMsockets = ($a.config.hardware.numcpu)/($a.config.hardware.NumCoresPerSocket)
$row.VMcores = $a.config.hardware.NumCoresPerSocket
$t = $temphost | where {$_.moref -eq $a.runtime.host}
$nodesCalc = try{[system.math]::ceiling($a.config.hardware.numcpu /($t.hardware.cpuinfo.numcpucores / $t.hardware.cpuinfo.NumCpuPackages))}catch{}
$row.CpuCalcNumaNodes = if($nodesCalc -gt $t.hardware.cpuinfo.NumCpuPackages){$t.hardware.cpuinfo.NumCpuPackages}else{$nodesCalc}
$nodesCalc = if(((($t.hardware.memorysize)/1048576)/$t.hardware.cpuinfo.NumCpuPackages) -lt ($a.config.hardware.MemoryMB)){$nodescalc + 1}else{$nodescalc}
$row.MemCalcNumaNodes = if($nodesCalc -gt $t.hardware.cpuinfo.NumCpuPackages){$t.hardware.cpuinfo.NumCpuPackages}else{$nodesCalc}
$report += $row
}

### format the below output as needed.  It currently reports any VMs that span across more than one NUMA boundary.
$report | where {($_.CPUCalcNumaNodes -ge 2) -or ($_.MemCalcNumaNodes -ge 2)} | ft

 

 

 

Aug 072014
 

Some Quick One-Liners to help with Day to Day changes.  Copy and Adapt as needed.

Quick Notes***
Ram and HardDisk Capacity numbers are in GB.   The bottom code to increase a VMs existing HardDisk has a WMI call to get the Drive letters (For Windows VMs).  This will help match Hard Disk to Drive letter before you issue the last command to expand it.

####### Edit your VM name here #######
$theVM = get-vm “MySuperCoolVM”

######Increase vCPU#######
$thevm | set-vm -numcpu “3″ -confirm:$false

#######Increase RAM#######
$thevm | set-vm -memoryGB “8″ -confirm:$false

#######Rename to old_X and move to old folder
$thevm | set-vm -name (“old_”+($thevm.name)) -confirm:$false
$thevm | move-vm -destination (get-folder “old”)

#######add new Drive to VM#######
$thevm |new-harddisk -capacityGB “50″

#######increase drive on VM#######
$thevm | get-harddisk | select name,capacityGB,filename

$report = @()
$temp = get-WmiObject win32_logicaldisk -Computername ($thevm.name)
foreach($b in ($temp | where {$_.drivetype -eq “3″})){
$reportrow = “” | select VMname, DriveLetter, VolumeName,CapacityGB, FreespaceGB,percentFree
$reportrow.vmname = $thevm.name
$reportrow.driveletter = $b.DeviceID
$reportrow.VolumeName = $b.VolumeName
$reportrow.capacityGB = “{0:N3}” -f ($b.Size / 1073741824)
$reportrow.freespaceGB = “{0:N3}” -f ($b.FreeSpace / 1073741824)
$reportrow.percentfree = [System.Math]::floor(($b.FreeSpace / $b.Size)*100)
$report += $reportrow
}

$report | ft

$thevm | get-harddisk | where {$_.name -eq “Hard disk 3″} | set-harddisk -capacityGB “50″ -confirm:$false

 

Jul 242014
 

#Upgrading a cluster from 5.1 to 5.5 or even updating past the Heart Bleed and need a quick double check that all of the host got the new build?
#I throw this at the entire vcenter but you can narrow it down to per datacenter or cluster if you like…

### Here is the quick (cluster only) code…

$Report = @()
get-cluster myCluster | get-vmhost | %{
$vmhost = Get-View $_.ID
$ReportRow = “” | Select-Object Hostname, build
$ReportRow.Hostname = $vmhost.Name
$ReportRow.Build = $vmhost.summary.config.product.build
$Report += $ReportRow
}
$report | FT

 

### If you want to be more fancy, here is a multi vCenter scan… (check ALL the hosts!)

Add-PSSnapin VMware.VimAutomation.Core

$vcenters = @()
$vcenters += “vcenter1″
$vcenters += “vcenter2″
$vcenters += “vcenter3″

$Report = @()
foreach($vcenter in $vcenters){
Connect-VIServer $vcenter

$clusters = get-cluster
foreach($a in $clusters){
$a | get-vmhost | %{
$vmhost = Get-View $_.ID
$ReportRow = “” | Select-Object vcenter,cluster,Hostname, build
$ReportRow.vcenter = $vcenter
$ReportRow.cluster = $a.name
$ReportRow.Hostname = $vmhost.Name
$ReportRow.Build = $vmhost.summary.config.product.build
$Report += $ReportRow
}
}
Disconnect-viserver -confirm:$False
}
$report | FT

Jul 072014
 

#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              192.168.0.101    False                                                True
#esx06             192.168.0.101    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

Jun 062014
 

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.)
OR
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
}
}
}
$report

Jun 042014
 

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:

#VMGroup
$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
$cluster.ReconfigureComputeResource_Task($spec,$true)
#HostGroup
$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
$cluster.ReconfigureComputeResource_Task($spec,$true)
#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
$cluster.ReconfigureComputeResource_Task($spec,$true)

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.

May 272014
 

#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

####

Feb 282014
 

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

Feb 262014
 

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