PowerCLI List all VMDK disks and what datastore they are on

Once an a while I need to list all my vmdk’s and what datastore they are on… So I created this script with output to CSV:

$outputFile = "D:\tmp\output.csv" 

$VMsAdv = Get-VM | Sort-Object Name | % { Get-View $_.ID } 
$myCol = @() 
ForEach ($VMAdv in $VMsAdv) 
{ 
    ForEach ($Disk in $VMAdv.Layout.Disk) 
    { 
        $myObj = "" | Select-Object Name, Disk 
        $myObj.Name = $VMAdv.Name 
        $myObj.Disk = $Disk.DiskFile[0] 
        $myCol += $myObj 
    } 
} 
$myCol | Export-Csv $outputFile -NoTypeInformation

 

Powercli – How to get Vmware tools version

Classic problem keeping vmware tools up to date.   Here is a set of power shell scripts to help you figure out what machines have old tools and need updates.  I run a version of this script as an email sent to me once a week.

Q: How do I get a list of the Vmware tools on each virtual machine?

get-vm | % { get-view $_.id } | select Name, @{ Name="ToolsVersion"; Expression={$_.config.tools.toolsVersion}},@{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}}

Q: How do I get a list of the Vmware tools on each powered on virtual machine?

get-vm | where {$_.powerstate -ne "PoweredOff" } | % { get-view $_.id } | select Name, @{ Name="ToolsVersion"; Expression={$_.config.tools.toolsVersion}},@{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}}

Q: How do I get a list of the Vmware tools that are not up to date on each powered on virtual machine?

get-vm | where {$_.powerstate -ne "PoweredOff" } | where {$_.Guest.ToolsVersionStatus -ne "guestToolsCurrent"} | % { get-view $_.id } | select Name, @{ Name="ToolsVersion"; Expression={$_.config.tools.toolsVersion}}, @{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}}

Q: How do I get a list of the Vmware tools that are not up to date on each powered on virtual machine and output it to csv?

get-vm | where {$_.powerstate -ne "PoweredOff" } | where {$_.Guest.ToolsVersionStatus -ne "guestToolsCurrent"} | % { get-view $_.id } | select Name, @{ Name="ToolsVersion"; Expression={$_.config.tools.toolsVersion}}, @{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}} | Export-Csv -NoTypeInformation -UseCulture -Path C:\Temp\VMHWandToolsInfo.csv

Powercli Basics Part 1

We all have to start somewhere so what better place than the basics. I kept jumping into complex scripts without working out the basics. For years I have written scripts in shell or perl but I have never spent much time in PowerShell. This is a few basic items to get your started with PowerCLI for Vmware.

What can you do with PowerCLI?

Just about anything you can do in the command line and a lot more. It allows full access to Vmware in every respect. It can be used to automate tasks, produce reports or resolve problems.

Why do we want to automate tasks and produce reports we can do that manually?

This has been suggested more than once. If you have to do it more than once it should be automated why? It reduces to human error risk factor and produces repeatable results everytime. It also helps you think about the process before you do it reducing missed steps. Automation is the key to more time as an administrator and less problems.

First thing first:
Your first step into the world of PowerCLI is installing it. You can download it from vmware’s site for free and you should update it everytime a new version of ESX comes out. Each updated version gets more and more functionality and commands. Make sure you run the installer as Administrator. The next step is to change the execution policy. Microsoft felt that it was a good idea to have all Powershell code signed off by a third party before allowing it to run. This eliminates the chance that someone’s virus could be run. It also makes it impossible for your to run your code so you need to change it.

Changing execution policy
1. Log into Powershell by right clicking on it and selecting run as Administrator
2. Run the following command:

set-executionpolicy remotesigned

3. Anwer yes to the question

Now you need to connect to your first vmware node with PowerCLI.   Right click on powercli on your desktop and select run as administrator.  Once it loads up you need to connect to either vsphere or an esx host with the following command:

connect-viserver IP_address

It has a series of questions which can be answered on the command line or via the prompt (like your login information) and your connected to your host / vcenter.

You can now issue your first powercli command to locate some information about your host or hosts:

get-vmhost

Great now I know how to pull information about my host but what if I want to see all the information it pulls from my host or from any command.  That can be done with the fl command.  Powershell uses a piping structure that will be familiar to all Linux / Unix shell coders.

get-vmhost | fl

How about displaying only selected fields.  For example lets display the used CPU and used memory on each host:

get-vm | select Name, CpuUsageMhz, MemoryUsageGB

Now we have the state of a beautiful reporting system.  Look for more in the next part.

 

Powercli Basics Part 2

Welcome to part 2 we are going to expand on our last code slice:

get-vm | select Name, CpuUsageMhz, MemoryUsageGB

Which produces a nice list of the CpuUsageMhz and MemoryUsageGB per node.   Now we are going to expand that command to produce a report that displays the percent of Memory used and Cpu used across your whole cluster.   First of all we need variables

Variables

Variables in powershell are very flexable.  They are all defined with a dollar $ sign in front of them.  An variable can be an array via $variable_name[number] or a multidementional  array via $variable_name[number].field_name for example

To create variable that holds the number 5 we do the following

$variable=5

To display we do the following:

$variable

In order to load multiple items into an variable making it an array we just add more elements on the command line separated by a comma

$variable=5,6
$variable

To address individual elements of the array you use [number]

$variable[0]

With Vmware you almost always have multiple fields as show by the following command from part 1.

get-vmhost | fl

So when you put the output from get-vmhost into a variable it creates a multidemential array which can be addressed like this:

$output=get-vmhost
$output

So we can choose a single field via the following pattern $variablename[num].fieldname for example

$output[0].NumCpu

What do we do if we have multiple hosts that we want to query .. lets use a for loop:

[sourcecode language="powershell"]
$hosts=get-vmhost

foreach($vmhost in $hosts){

  $vmhost.Name

  $vmhost.CpuTotalMhz

  $vmhost.CpuUsageMhz

  $vmhost.MemoryTotalGB

  $vmhost.MemoryUsageGB

}

[/sourcecode]

Pretty simple stuff… but we are missing a critical part… I think it would be better to understand the totals from my whole cluster not each individual host.  For that we need some math operators:

= Equals

+= Increases by value and appends variable

-= Decreases by value and appends to variable

*= Multiplies by value and appends to variable

/= Divides by value and appends to variable

%= Divides and assigns the remainder to variable (modulus)

So back to our code… lets assume we want to add up all our used CPU and used Ram and figure out what percentage we are using on our whole cluster:

 

[sourcecode language="powershell"]
$hosts=get-vmhost

foreach($vmhost in $hosts){

  $cputotal+=$vmhost.CpuTotalMhz

  $cpuusage+=$vmhost.CpuUsageMhz

  $memorytotal+=$vmhost.MemoryTotalGB

  $memoryused+=$vmhost.MemoryUsageGB

}

 $percpuused=(($cpuusage / $cputotal) * 100)

 Write-Host "You are currently using $percpuused% of your cpu."

 $permemused=(($memoryused / $memorytotal) * 100)

 Write-Host "You are currently using $permemused% of your memory."
[/sourcecode]

One problem with this output… no one cares how many decimal points of a percent you are using. We need to edit the numbers to drop the decimal points:

[sourcecode language="powershell"]
$hosts=get-vmhost

foreach($vmhost in $hosts){

  $cputotal+=$vmhost.CpuTotalMhz

  $cpuusage+=$vmhost.CpuUsageMhz

  $memorytotal+=$vmhost.MemoryTotalGB

  $memoryused+=$vmhost.MemoryUsageGB

}

 $percpuused="{0:N0}" -f (($cpuusage / $cputotal) * 100)

 Write-Host "You are currently using $percpuused% of your cpu."

 $permemused="{0:N0}" -f (($memoryused / $memorytotal) * 100)

 Write-Host "You are currently using $permemused% of your memory."
[/sourcecode]

The addition of “{0:N0}” -f knocks off the decimal points .. you can also keep to places after the decimal point by this command:
“{0:N2}” -f

That’s it for now. In part three I will show you how to make your report a nice HTML email.

Powercli – Virtual Switches

Q: How do I add a new port group to a virtual switch on each ESX host

A: Using powercli you could run the following:

[sourcecode language="powershell"]
$cluster_name = "Your_Cluster_Name"
$vSwitch = "vSwitch_you_want_to_add_vlan_to"
$PortGroupName = "Name_of_Your_Port_Group"
$PortGroupVLAN = "VLAN_of_Your_Port_Group"

foreach ($esx in get-VMhost -Location $cluster_name | sort Name) { $esx | Get-VirtualSwitch -Name $vSwitch | New-VirtualPortGroup -Name “$PortGroupName″ -VlanId $PortGroupVLAN }

[/sourcecode]

Q: How do I change the number of ports on my vSwitch using PowerCli

A: With the following commands:

[sourcecode language="powershell"]
$vSwitch = "Your_vSwitch_Name"
$NumberPorts = "Number_of_ports"

Get-VMHost | % {Get-VirtualSwitch -VMHost $_ -Name $vSwitch | % { Set-VirtualSwitch -VirtualSwitch $_ -NumPorts "$NumberPorts" }

[/sourcecode]

Q: How do I create a vSwitch from PowerCli
A: With this code:

[sourcecode language="powershell"]
# You can do multiple vmnic's on the command just use a , between
$vmnic = "Name_of_vmnic_you_want_assigned_to_switch"
$vSwitch = "Name_of_new_vSwitch"
$NumPorts = "Number_of_ports"

New-VirtualSwitch -Name $vSwitch -NumPorts $NumPorts -Nic $vmnic

[/sourcecode]

PowerCLI upgrade vmware tools on next reboot

I ran across this command somewhere and it’s really useful for the vCloud hosted environment where your tenants never upgrade their tools.   Of course you have to be allowed upgrade the tools make sure your not breaking your SLA or service contract by doing this.  Here is the command:

Foreach ($v in (get-vm)) {
$vm = $v | Get-View
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.Tools = New-Object VMware.Vim.ToolsConfigInfo
$vmConfigSpec.Tools.ToolsUpgradePolicy = "UpgradeAtPowerCycle"
$vm.ReconfigVM($vmConfigSpec)
}

PowerCLI CDROM’s disconnect and reconnect

In powershell it’s really easy to disconnect and reconnect cdrom drives:

To see all connected drives:

Get-VM | where {($_ | Get-CDDrive).ISOPath -ne $null}  |FT Name, @{Label="ISO file"; Expression = { ($_ | Get-CDDrive).ISOPath }}

To auto disconnect all:

Get-VM | Get-CDDrive | Where {$_.ConnectionState.Connected} | Set-CDDrive -Connected $false -Confirm:$false