Friday, July 19, 2013

Changing ESXi IP address and default route via command line

esxcfg-vmknic "Management Network" -i [newip] -n [newsubnetmask]
esxcfg-route -d default 0.0.0.0 [olddefaultgw]
esxcfg-route -a default 0.0.0.0 [newdefaultgw]
/sbin/services.sh restart

Friday, March 29, 2013

PowerCLI - Removing inaccessible VM's from inventory

In my lab I often destroy and re-create Nutanix clusters which sometimes leaves stale, inaccessible datastores as well as a bunch of inaccessible VM's. The following script will remove all these inaccessible VM's from inventory (Thanks to my colleague Steven for this one):
Get-Cluster -Name $clustername | Get-VM | Get-View | Where {-not $_.Config.Template} | Where{$_.Runtime.ConnectionState -eq “invalid” -or $_.Runtime.ConnectionState -eq “inaccessible”} | %{Remove-VM -VM $_.Name}

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