Sunday, December 2, 2012

PowerCLI - Deploying VM from template with customization spec

Reproducing an issue recently required me to deploy 20 VM's across 4 hosts that each had 5 datastores (4 VM's on each datastore, one from each host). The datastores were named nfs-[1-5]. Once I had the template VM created with the tools I needed and the customization spec, I was able to deploy the VM's across the hosts/datastores with the following PowerCLI code:
1..5 | Foreach { New-VM -vmhost 192.168.10.244 -Name Win2k8-1-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
1..5 | Foreach { New-VM -vmhost 192.168.10.245 -Name Win2k8-2-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
1..5 | Foreach { New-VM -vmhost 192.168.10.246 -Name Win2k8-3-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
1..5 | Foreach { New-VM -vmhost 192.168.10.247 -Name Win2k8-4-$_ -Template Win2k8Template -Datastore nfs-$_ -OSCustomizationSpec TM-WIN2k8 }
Each VM was using ~20GB, and the whole deployment took approximately an hour. I found a variation of the above on another blog (http://virtuallymikebrown.com/2012/02/17/deploy-a-vm-from-template-with-powercli/) where he was able to pipe the New-VM command to Start-VM but for whatever reason this didn't work for me, I was getting the error: "New-VM : 12/2/2012 5:06:34 PM New-VM Operation is not valid due to the current state of the object." I didn't look into this too much and instead just ran the following loop after the above was done:
$VMs = Get-VM -Name "Win2k8-*"
foreach ($vm in $VMs)  {
  Write-Host "Starting " -NoNewLine
  Write-Host $vm.Name 
  Start-VM $vm.Name
}
The final outcome in vCenter looked like:

Monday, July 9, 2012

PowerCLI snippets

Some PowerCLI snippets that I've used. Use with caution on a production system.
# Connect to multiple vCenters
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false

# Add snap-in if required
if ( (Get-PSSnapin -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) -eq $null ) {
    add-pssnapin VMware.VimAutomation.Core
}
else {
    Write-Host "Snap in already added."
}

Set-PowerCLIConfiguration -InvalidCertificateAction "Ignore" -Confirm:$false

# Connect to vCenter
Connect-VIServer 192.168.10.31 -User laura -Password xxxxxx

Get-VM | Get-View

# Get VM
$vmname="GoldenClient"
$vm = Get-VM $vmname | Get-View

# Get the guest IP address for one or more virtual machines
$vms = Get-VM -Name "vm-*"
foreach ($vm in $vms) {
  $name = $vm.Name
  $ip = $vm.Guest.IPAddress
  echo "Name: $name"
  echo "IP: $ip" 
}

# Get VM alarm state
foreach($state in $vm.DeclaredAlarmState){
    $alarm = Get-View $state.Alarm
    #Write-Host "name:"
    #Write-Host $alarm.info.name
    #Write-Host "overall status:"
    Write-Host $state.OverallStatus
}

# Get all VM's powered on named lnkc* (lnkc-1, lnkc-2, etc)
Get-VM -Name lnkc* | Where-Object{$_.PowerState -eq "PoweredOn"}

# Get count of all powered on VM's
$vms = Get-VM | Where-Object {$_.PowerState -eq "PoweredOn"}
$vms.count

# Get count of all VM's
$vms = Get-VM
$vms.count

# Get all hosts
Get-Host 

# Remove from inventory and delete from disk
remove-vm -DeleteFromDisk:$true -RunAsync:$true -vm $vmName

# Shut down all powered on VM's gracefully
$clustername="rdc"
Get-Cluster -Name $clustername  | Get-VM | Where-Object{$_.PowerState -eq "PoweredOn"} | Shutdown-VMGuest -Confirm:$false

# Put all hosts in the cluster into maintenace mode
Get-Cluster -Name $clustername | Get-VMHost | Set-VMHost -State "Maintenance"

# Reboot all hosts
Get-Cluster -Name $clustername | Get-VMHost | Restart-VMHost -Confirm:$false

# Exit maintenance mode
Get-Cluster -Name $clustername | Get-VMHost | Set-VMHost -State "Connected"

# Power on a set of virtual machines
Get-Cluster -Name $clustername  | Get-VM -Name colo* | Start-VM

# Create port group on a specific VLAN
Get-Cluster -Name $clustername | Get-VMHost | Get-VirtualSwitch | New-VirtualPortGroup -name 'my-vlan' -VLanID 12

# Disconnect from vCenter
Disconnect-VIServer -Confirm:$false

Thursday, March 15, 2012

PowerCLI - Connecting to multiple vCenters

By default the connection mode of PowerCLI is set to "Single" which means if you connect to multiple vCenter or server instances, only the last established one is used.

To run a command such as "Get-VM" against all connections, set the connection mode to multiple with the following command:

Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false
Output:
Proxy Policy    Default Server  Invalid Certificate 
Mode            Action              
------------    --------------- --------------------
UseSystemProxy  Multiple        Unset
To get the current config use Get-PowerCLIConfiguration:
Get-PowerCLIConfiguration
Output:
Proxy Policy    Default Server  Invalid Certificate 
Mode            Action              
------------    --------------- --------------------
UseSystemProxy  Multiple        Unset

Reference: http://www.vmware.com/support/developer/PowerCLI/PowerCLI50/html/Set-PowerCLIConfiguration.html

Wednesday, March 14, 2012

PowerCLI - Formatted table of VM's and their corresponding hosts

Connect-VIServer 192.168.10.196 -User administrator -Password XXXXXX

"{0,-30}           {1,-20}" -f "VM","Host"
"{0,-30}           {1,-20}" -f "--","----"
Get-VM | %{
    $vmHost = $_.VMHost
    foreach($hst in $vmHost) {
         "{0,-30}           {1,-20}" -f "$_","$hst"
    }
}

Output:
VM                                       Host                
--                                       ----                
w2k8_vcenter_1                           192.168.10.1         
NTNX-Ctrl-VM-1-perses                    192.168.10.1         
NTNX_vMA                                 192.168.10.1         
laura-ubuntu                             192.168.10.1         
NTNX-Ctrl-VM-2-perses                    192.168.10.2         
NTNX-Ctrl-VM-3-perses                    192.168.10.3 

Tuesday, March 13, 2012

PowerCLI - Get-Member - Get all properties of an object

Get-VM | Get-Member -MemberType property | Format-Table -Property Name

Name
----
CDDrives
CustomFields
DatastoreIdList
Description
DrsAutomationLevel
ExtensionData
FloppyDrives
Folder
FolderId
Guest
HAIsolationResponse
HardDisks
HARestartPriority
Host
HostId
Id
MemoryMB
Name
NetworkAdapters
Notes
NumCpu
PersistentId
PowerState
ProvisionedSpaceGB
ResourcePool
ResourcePoolId
Uid
UsbDevices
UsedSpaceGB
VApp
Version
VMHost
VMHostId
VMResourceConfiguration
VMSwapfilePolicy

In this example, we can enhance the Get-VM output to show just the properties we are interested in:

Get-VM | Format-List -Property Name,Version


Name    : w2k8_vcenter_1
Version : v7

Name    : NTNX-Ctrl-VM-1-perses
Version : v7

Name    : NTNX_vMA
Version : v4

Name    : laura-ubuntu
Version : v8

Name    : NTNX-Ctrl-VM-2-perses
Version : v7

Name    : NTNX-Ctrl-VM-3-perses
Version : v7

Friday, March 9, 2012

PowerCLI - Get-DatastoreMountInfo (advanced function) and other commands

How to list datastore mounts, unregister VM's, unmount datastores, disable HA/DRS from a cluster (warning: disabling DRS deletes any resource pools from the cluster), and edit firewall rules.

Requirements for datastore functions: PowerCLI 5.0.1, Powershell v2 and the advanced function from:
http://blogs.vmware.com/vsphere/2012/01/automating-datastore-storage-device-detachment-in-vsphere-5.html
http://communities.vmware.com/docs/DOC-18008

Get-PowerCLIVersion

PowerCLI Version
----------------
   VMware vSphere PowerCLI 5.0.1 build 581491
---------------
Snapin Versions
---------------
   VMware AutoDeploy PowerCLI Component 5.0 build 544967
   VMware ImageBuilder PowerCLI Component 5.0 build 544967
   VMware License PowerCLI Component 5.0 build 544881
   VMware vSphere PowerCLI Component 5.0 build 581435

Get-Datastore | Get-DatastoreMountInfo | Sort Datastore, VMHost | FT -AutoSize

Datastore              VMHost      Lun                                                                        Mounted State   
---------              ------      ---                                                                        ------- -----   
NTNX_datastore_1       192.168.10.1 t10.NUTANIX_shared_data1_1e9999cf2847e0cd727c3014df963e57e975bac8             True Attached
NTNX_datastore_1       192.168.10.2 t10.NUTANIX_shared_data1_1e9999cf2847e0cd727c3014df963e57e975bac8             True Attached
NTNX_datastore_1       192.168.10.3 t10.NUTANIX_shared_data1_1e9999cf2847e0cd727c3014df963e57e975bac8             True Attached
NTNX_datastore_2       192.168.10.1 t10.NUTANIX_shared_data2_6b7ca057ea23a4875fecec0f051eba0c16711f10             True Attached
NTNX_datastore_2       192.168.10.2 t10.NUTANIX_shared_data2_6b7ca057ea23a4875fecec0f051eba0c16711f10             True Attached
NTNX_datastore_2       192.168.10.3 t10.NUTANIX_shared_data2_6b7ca057ea23a4875fecec0f051eba0c16711f10             True Attached
NTNX_datastore_3       192.168.10.1 t10.NUTANIX_shared_data3_e9588e3a87e617fd79ab107b736b54cbd3d55e8e             True Attached
NTNX_datastore_3       192.168.10.2 t10.NUTANIX_shared_data3_e9588e3a87e617fd79ab107b736b54cbd3d55e8e             True Attached
NTNX_datastore_3       192.168.10.3 t10.NUTANIX_shared_data3_e9588e3a87e617fd79ab107b736b54cbd3d55e8e             True Attached
NTNX-1-local-ds-perses 192.168.10.1 t10.ATA_____WDC_WD10EARS2D22Y5B1__________________________WD2DWCAV5M430844    True Attached
NTNX-2-local-ds-perses 192.168.10.2 t10.ATA_____WDC_WD10EARS2D22Y5B1__________________________WD2DWCAV5H180730    True Attached
NTNX-3-local-ds-perses 192.168.10.3 t10.ATA_____WDC_WD10EARS2D22Y5B1__________________________WD2DWCAV5M001915    True Attached

Get-Datastore NTNX_datastore_* | Unmount-Datastore
Unmounting VMFS Datastore NTNX_datastore_1 from host 192.168.10.1...
Exception calling "UnmountVmfsVolume" with "1" argument(s): "The resource 'NTNX_datastore_1' is in use."
At line:101 char:35
+                     $StorageSys.UnmountVmfsVolume <<<< ($DS.ExtensionData.Info.vmfs.uuid);
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
 
Unmounting VMFS Datastore NTNX_datastore_1 from host 192.168.10.2...
Unmounting VMFS Datastore NTNX_datastore_1 from host 192.168.10.3...
Unmounting VMFS Datastore NTNX_datastore_2 from host 192.168.10.1...
Unmounting VMFS Datastore NTNX_datastore_2 from host 192.168.10.2...
Unmounting VMFS Datastore NTNX_datastore_2 from host 192.168.10.3...
Unmounting VMFS Datastore NTNX_datastore_3 from host 192.168.10.1...
Unmounting VMFS Datastore NTNX_datastore_3 from host 192.168.10.2...
Unmounting VMFS Datastore NTNX_datastore_3 from host 192.168.10.3...

The above failed because VM's existed on NTNX_datastore_1 on host 192.168.10.1. To resolve, unregister the VM's with the Remove-VM cmdlet (the -DeletePermanently flag would have deleted from disk):

Get-VM ubuntu-vmfs-0 | Remove-VM -Confirm:$false
Get-VM ubuntu-vmfs-1 | Remove-VM -Confirm:$false

Detach the datastore:

Get-Datastore NTNX_datastore_* | Detach-Datastore

Detaching LUN t10.NUTANIX_shared_data1_1e9999cf2847e0cd727c3014df963e57e975bac8 from host 192.168.10.1...
Detaching LUN t10.NUTANIX_shared_data1_1e9999cf2847e0cd727c3014df963e57e975bac8 from host 192.168.10.2...
Detaching LUN t10.NUTANIX_shared_data1_1e9999cf2847e0cd727c3014df963e57e975bac8 from host 192.168.10.3...
Detaching LUN t10.NUTANIX_shared_data2_6b7ca057ea23a4875fecec0f051eba0c16711f10 from host 192.168.10.1...
Detaching LUN t10.NUTANIX_shared_data2_6b7ca057ea23a4875fecec0f051eba0c16711f10 from host 192.168.10.2...
Detaching LUN t10.NUTANIX_shared_data2_6b7ca057ea23a4875fecec0f051eba0c16711f10 from host 192.168.10.3...
Detaching LUN t10.NUTANIX_shared_data3_e9588e3a87e617fd79ab107b736b54cbd3d55e8e from host 192.168.10.1...
Detaching LUN t10.NUTANIX_shared_data3_e9588e3a87e617fd79ab107b736b54cbd3d55e8e from host 192.168.10.2...
Detaching LUN t10.NUTANIX_shared_data3_e9588e3a87e617fd79ab107b736b54cbd3d55e8e from host 192.168.10.3...
Disabling HA/DRS (warning - all Resource Pools will be removed):

Get-Cluster Perses-Cluster | Set-Cluster -HAEnabled:$false -DrsEnabled:$false -Confirm:$false

Name                           HAEnabled  HAFailover DrsEnabled DrsAutomationLevel  
                                          Level                                     
----                           ---------  ---------- ---------- ------------------  
Perses-Cluster                 False      1          False      Manual              
Checking Firewall Rules for "NFS Client" entry on each host:

Get-VMHost | Get-VMHostFirewallException -Name 'NFS Client'


Name                 Enabled IncomingPorts  OutgoingPorts  Protocols  ServiceRunning 
----                 ------- -------------  -------------  ---------  -------------- 
NFS Client           False                  0-65535        TCP                       
NFS Client           False                  0-65535        TCP                       
NFS Client           True                   0-65535        TCP   
Enabling "NFS Client" entry on the firewall each host:

Get-VMHost | Get-VMHostFirewallException -Name 'NFS Client' | Set-VMHostFirewallException -Enabled:$true

Name                 Enabled IncomingPorts  OutgoingPorts  Protocols  ServiceRunning 
----                 ------- -------------  -------------  ---------  -------------- 
NFS Client           True                   0-65535        TCP                       
NFS Client           True                   0-65535        TCP                       
NFS Client           True                   0-65535        TCP

PowerCLI - Get-VM and Stop-VM

$vCenter = "192.168.10.196"
$vcAcct = "administrator"
$vcPass = "xxxxx"

Connect-VIServer $vCenter -User $vcAcct -Password $vcPass

Get-VM 

Name                 PowerState Num CPUs Memory (MB)
----                 ---------- -------- -----------
w2k8_vcenter_1       PoweredOn  1        4096       
NTNX-Ctrl-VM-1-pe... PoweredOn  1        3072       
ubuntu-vmfs-0        PoweredOn  1        1024       
NTNX_vMA             PoweredOn  1        600        
ubuntu-vmfs-1        PoweredOff 1        1024       
NTNX-Ctrl-VM-2-pe... PoweredOn  1        3072       
NTNX-Ctrl-VM-3-pe... PoweredOn  1        3072   

Get-VM | Format-List -Property Name,PowerState

Name       : w2k8_vcenter_1
PowerState : PoweredOn

Name       : NTNX-Ctrl-VM-1-perses
PowerState : PoweredOn

Name       : ubuntu-vmfs-0
PowerState : PoweredOn

Name       : NTNX_vMA
PowerState : PoweredOn

Name       : ubuntu-vmfs-1
PowerState : PoweredOff

Name       : NTNX-Ctrl-VM-2-perses
PowerState : PoweredOn

Name       : NTNX-Ctrl-VM-3-perses
PowerState : PoweredOn

Also:

Get-VM | Format-Table -Property Name,PowerState,NumCpu,MemoryMB
To power off VM:

Get-VM ubuntu-vmfs-0 | Stop-VM -Confirm:$false

Name                 PowerState Num CPUs Memory (MB)
----                 ---------- -------- -----------
ubuntu-vmfs-0        PoweredOff 1        1024       

http://www.vmware.com/support/developer/PowerCLI/PowerCLI501/doc/vsph_powercli_usg501.pdf