Tag Archives: PowerCLI

Mass update VM description field

I had a need to update description fields in many of my VMs and the vSphere client doesn’t exactly lend itself to being able to accomplish this quickly. I decided to use PowerCLI to dump a CSV of my VM names and description fields. I then updated the CSV and imported the new descriptions back into the VMs

First, to dump a CSV of VMs and descriptions in a particular cluster

Connect-VIServer "myserver.foo.com"
Get-Cluster "mycluster" | Get-VM | Select-object Name, Description | Export-CSV "myvms.csv"

Then, after updating the CSV with new description information, save the descriptions back into the VMs.

Connect-VIServer "myserver.foo.com"
$csv=Import-Csv "myvms.csv"
$csv | % { Set-VM $_.VMName -Description $_.Description -Confirm:$false }

Guest NICs disconnected after upgrade

We are upgrading our infrastructure to ESXi 4.1 and had an unexpected result in Development cluster where multiple VMs were suddenly disconnected after vMotion. It sounded a lot like a problem that I had seen before where a misconfiguration in the number of ports on a vSwitch prevents vMotioned VMs from being able to connect to the switch. If a vSwitch has too few available ports, the VMs that vMotion over are unable to connect to the switch. You generally avoid this with host profiles, but it’s possible a host in the Dev cluster fell out of sync. In any event, the server that was being upgraded this evening had been rebuilt and it wasn’t worth trying to figure out what the configuration might have been. I needed to go through, find all VMs that should have been connected but weren’t, and reconnect them. I decided that I needed:

  • VMs that were currently Powered On – obviously as Powered Off VMs are all disconnected
  • VMs with NICs currently set to “Connect at Power On” so I could avoid connecting something that an admin had intentionally left disconnected
  • VMs with NICs currently not connected

Note that this script will change network settings and REBOOT VMs if you execute it. I was watching the script while it executed, I pinged the guest DNS name first to ensure the IP wasn’t already on the network, then connected the NIC, then pinged again to make sure it was back on the network. I figured I could Control-C to stop if something looked wrong. I rebooted all of the guests to avoid any failed service / failed task problems that might have occurred while the guests were disconnected.

$vms=get-cluster "Development" | get-vm | Where { $_.PowerState -eq "PoweredOn" }| Sort-Object Name
foreach ($vm in $vms)
{
   $nics = $vm | get-networkadapter | Where {$_.ConnectionState.Connected -eq $false -and $_.ConnectionState.StartConnected -eq $true}
   if ($nics -ne $null)
   {
  	 foreach ( $nic in $nics )
  	 {
	     	write-host $vm.Name
	     	write-host $nic
	      	ping $vm.Guest.HostName -n 5
		$nic | Set-NetworkAdapter -Connected $true -confirm:$false
	 }
 
        ping $vm.Guest.HostName -n 5
	$vm | Restart-VMGuest
 
   }

PowerCLI proxy problems

oday, I couldn’t connect to my vCenter server using Connect-VIServer. It failed with “Could not connect using the requested protocol.”

There have been some changes to the corporate proxy servers over the last couple of weeks and it’s causing connection problems

I bypassed the proxy with this:

Set-VIToolkitConfiguration -ProxyPolicy NoProxy -confirm:$false

VMware Automatic HBA rescan

When you add a new datastore, vCenter initiates an automatic rescan on the ESX hosts in the cluster. This can create a so-called “rescan storm” with your hosts pounding away at the SAN. This can cause serious performance problems for the duration of the storm. Even if you don’t have enough hosts in a cluster to see a real problem, it’s pretty inconvenient to have to wait for each rescan when you’re trying to add 10 datastores.

To disable the automatic rescan, open your vSphere client.

1. Administration->vCenter Server
2. Settings->Advanced Settings
3. Look for “config.vpxd.filter.hostRescanFilter. If it’s not there, add it and set to false.

If it’s currently set to true, you have to edit vpxd.cfg and restart the vCenter service.
C:\Documents and Settings\All Users\Application Data\VMware\VMware VirtualCenter\vpxd.cfg, change this key to false and restart the vCenter service.
true

Doing this creates a new problem – you now have to manually force a rescan on every host.

Here is a PowerCLI one-liner to automate this process. It will perform the rescan on each host in the cluster, and only on one host at a time.

get-cluster “Production” | Get-VMHost | %{ Get-VMHostStorage $_ -RescanVMFS }

PowerCLI script to export all Vms

Here is a PowerCLI script I hacked together to list out all of our VMs by cluster.

# List out all VMs by cluster, export to Excel
 
$VMCollection = @()
$ClusterName = ""
 
# Path to save Excel output
$savepath = "D:\My Documents\Scripts\powershell\VMware\VMListByCluster\"
# Enter your vCenter server here
$VIServer = "MYSERVER"
 
function GetVmDetails( $Details, $ClusterName )
{
 
$Details | Add-Member -Name Name -Value $VM.Name -membertype NoteProperty
$Details | Add-Member -Name DNSName -Value $vm.Guest.get_HostName() -membertype NoteProperty
$Details | Add-Member -Name Description -Value $vm.Description -membertype NoteProperty
$Details | Add-Member -Name OperatingSystem -Value $vm.Guest.get_OSFullName() -membertype NoteProperty
$Details | Add-Member -Name Cluster -Value $ClusterName -membertype NoteProperty
 
if ( $Details.DNSName.Length -eq 0 )
{
$Details.DNSName = " "
}
}
 
Write-Host "Connecting to Virtual Center..."
Connect-VIServer $VIServer
$AllClusters = Get-Cluster | Sort-Object "Name"
ForEach( $Cluster in $AllClusters)
{
 
$ClusterName = $Cluster.Name
$AllVMs = get-cluster $ClusterName | Get-VM | Sort-Object Name
ForEach ($VM in $AllVMs )
{
Write-Host $VM.Name
$Details = New-Object PSObject
GetVMDetails $Details $ClusterName
$VMCollection += $Details
}
}
 
#$VMCollection
 
Write-Host "Exporting to Excel..."
$cnt = ($VMCollection | Measure-Object).Count
 
$Excel = New-Object -Com Excel.Application
#$Excel.visible = $True
$Excel = $Excel.Workbooks.Add()
 
$Sheet = $Excel.WorkSheets.Item(1)
 
$Sheet.Cells.Item(1,1) = "VM Name"
$Sheet.Cells.Item(1,1).Font.Bold = $True
$Sheet.Range("A1").ColumnWidth = 24
 
$Sheet.Cells.Item(1,2) = "DNS Name"
$Sheet.Cells.Item(1,2).Font.Bold = $True
$Sheet.Range("B1").ColumnWidth = 35
 
$Sheet.Cells.Item(1,3) = "Description"
$Sheet.Cells.Item(1,3).Font.Bold = $True
$Sheet.Range("C1").ColumnWidth = 47
 
$Sheet.Cells.Item(1,4) = "OS"
$Sheet.Cells.Item(1,4).Font.Bold = $True
$Sheet.Range("D1").ColumnWidth = 54
 
$Sheet.Cells.Item(1,5) = "Cluster"
$Sheet.Cells.Item(1,5).Font.Bold = $True
$Sheet.Range("E1").ColumnWidth = 16
 
#Header Row
$Sheet.Range("A1").RowHeight = 50
 
$intRow = 2
ForEach ($objVM in $VMCollection )
{
$Sheet.Cells.Item($intRow,1) = $objVM.Name
$Sheet.Cells.Item($intRow,2) = $objVM.DNSName
$Sheet.Cells.Item($intRow,3) = $objVM.Description
$Sheet.Cells.Item($intRow,4) = $objVM.OperatingSystem
$Sheet.Cells.Item($intRow,5) = $objVM.Cluster
$rng = "A" + $intRow.ToString()
$Sheet.Range($rng).RowHeight = 110
Write-Host $objVM.Name
$msg = ($intRow -1).ToString() + " of " + $cnt.ToString()
Write-Host $msg
$intRow += 1
 
}
 
$fname = $savepath + "vms.xlsx"
$Excel.Application.DisplayAlerts = $False
$Sheet.SaveAs($fname)
$Excel.Application.DisplayAlerts = $True
$Excel.Close()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Excel)

Quick and dirty PowerCLI script to list out all VM MAC addresses

I needed a quick list of all MAC addresses in our VMWare environment and threw together this PowerCLI script.

$LOG_FILE = "C:\machines.txt"
$VI_SERVER = "your-virtual-center-server-here"
Connect-VIServer $VI_SERVER
get-vm | %{ $_ | select Name | out-file -filepath $LOG_FILE -append; $_ | Get-NetworkAdapter | out-file -filepath $LOG_FILE -append }