Sunday, September 13, 2015

Quick ping of VM guests

Quick ping of VM guests


get-vm | sort name | Foreach {Write-Output "Guest $($_.name) up: $(Test-Connection $_ -count 1 -quiet)"}


Guest vmtest01 up: True
Guest vmtest02 up: True
Guest vmtest03 up: True
Guest vmtest04 up: True
Guest vmtest05 up: True
Guest vmtest06 up: True
Guest vmtest07 up: True
Guest vmtest08 up: True
Guest vmtest09 up: True
Guest vmtest10 up: False
Guest vmtest11 up: True
Guest vmtest12 up: True
Guest vmtest13 up: True
Guest vmtest14 up: True
Guest vmtest15 up: True




You may want to use -count 2 if your network has a tendency to drop the first ping.

Friday, September 4, 2015

Restarting all VMs in one line (AKA, why vCenter admins shouldn't leave their workstations unlocked)

We live in an interesting IT world.  A former employer once took away my second AD 'admin' account because I wasn't a Windows admin and the auditors insisted that the only people who should have separate admin accounts were Windows admins.  How backwards is that?  After they took away my separate account, I had only one AD account with all my permissions, which included highly privileged access in vCenter.  That's right - I had one account to login with, and that account had the ability to reboot, shut down, or delete every VM in the company with one line of code.  (Ok, 2 lines of code if I wasn't already connected to the vCenter servers.)  And yes, I did express my concern to management, who agreed that this change actually decreased security.  However, since the change was something that was brought up by auditors and the appearance of security is often more important than actual security, nothing was ever done to separate my privileges on the virtual side.





Get-VM | Restart-VMGuest -confirm:$false
Get-VM | Stop-VM -confirm:$false
Get-VM | Remove-VM -DeletePermanently -runasync -confirm:$false




In the first command, Restart-VMGuest requires a supported version of vmtools to be installed and running in the VM.  It will use vmtools to use the guest operating system's graceful shutdown routine.  Use Restart-VM if you want to just pull the rug out under the OS more like a hardware power cycle.




In the second command, there is no graceful shutdown and no requirement for vmtools.  It's like holding in the power button and crashing down the VM hard.  Use Stop-VMGuest if you want to try a graceful shutdown using vmtools instead.




In the last command, the -DeletePermanently flag removes the VM files from the storage instead of just removing the VM from vCenter inventory.  -RunAsync lets it run much more quickly, as it will start the delete process and move to the next delete, instead of waiting for the current delete to finish before starting the next one.



Sunday, May 31, 2015

CIMC Storage log filled with Unexpected sense errors

We have many standalone Cisco UCS C240 M3S hosts, and on all of them the CIMC storage log is being filled with 'Unexpected sense' errors every 5 minutes.

According to the release notes (http://www.cisco.com/c/en/us/td/docs/unified_computing/ucs/release/notes/OL-32046-01.html), this is due to VMware treating all storage devices the same way, regardless of whether they are SAS disks or just enclosures.  They list a manual workaround that will stop these messages from being logged in the vmkernel.log and in the CIMC storage log that involves ssh'ing into the host and running an esxcli command.

Of course, I don't want to turn on ssh and remote to the host to run the commands one host at a time - PowerCLI to the rescue!

These steps will  "disconnect" the enclosure from the viewpoint of ESXi.  The parameter set is correct for ESXi 5.5. You may need to adjust the parameters for different ESXi versions.

connect-viserver myhost.mylab.com
$esxcli = get-esxcli -vmhost myhost.mylab.com
$device = ($esxcli.storage.core.device.list() | where-object {$_.DeviceType -match "enclosure"}).device
$esxcli.storage.core.device.set($null,$device,$false,$null,$false,$null,$null,$null,"off")

As always, watch the line breaks when you copy/paste. From here, it should be easy to script an automated solution for an entire environment. Note that if you have lockdown mode enabled there may be other steps required to allow you to connect via get-esxcli.

Saturday, May 30, 2015

Get boot time of ESXi host in local time with PowerCLI

A co-worker came to me yesterday with a request for something that seemed quite easy but came with an unexpected twist.  He needed to get the boot time for a group of ESXi hosts.  Finding the code for this wasn't hard with a quick google search.

For a single host:
PowerCLI C:\script> (get-vmhost esxhost01.example.local).extensiondata.runtime.boottime

Tuesday, March 31, 2015 1:13:07 AM

Using select makes it easier to report on a group of hosts:

PowerCLI C:\script> get-vmhost | select name,@{Name="BootTime";Expression={$_.extensiondata.runtime.boottime}}

Name                                          BootTime              
----                                          --------          
esxhost01.example.local                       5/1/2015 2:57:32 PM 
esxhost02.example.local                       5/29/2015 1:54:30 PM


Piece of cake!  Except this was UTC time, and it makes more sense for us to report our boot time in local time.  Here's the thing - a [datetime] object in Powershell has a method toUniversalTime() but there is no reverse method to convert UTC to local time.

What's the answer? Use New-Timespan to determine your offset from UTC time and the addhours() method of the [datetime] object.  Your offset from UTC can be calculated as:

$offset = (new-timespan -start (get-date).touniversaltime() -end (get-date)).hours

For one host:
(get-vmhost esxhost01.example.local).extensiondata.runtime.boottime.addhours((new-timespan -start (get-date).touniversaltime() -end (get-date)).hours)

For a group of hosts:
get-vmhost | select name,@{Name="BootTime";Expression={$_.extensiondata.runtime.boottime.addhours((new-timespan -start (get-date).touniversaltime() -end (get-date)).hours)}}

Sorry for the line breaks :)

Tuesday, May 12, 2015

One-Liner to get the VMs restarted by HA after an ESXi host PSOD

PSODs suck.  We know that.  We've been getting the occasional PSOD after going to 5.5 U2, and when a prod host crashes the first thing everyone wants to know is: Which VMs were affected?

I put together a one-liner to get this information based on the event that is recorded on the VM when HA restarts it on another host.

get-vmhost ProdHost01.example.local | get-cluster | get-vm | Get-VIEvent -Start (Get-Date).AddHours(-24) -types warning | where-object {$_.fullformattedmessage -match "restarted"} | select objectname,createdtime,fullformattedmessage

Breakdown:
get-vmhost : get the vm host object of the host that went down with a PSOD
get-cluster : gets the cluster that host was in
get-vm : gets all the VMs in that cluster
Get-VIEvent -Start (Get-Date).AddHours(-24) -types warning : gets all the events of type 'warning' within the past 24 hours (adjust the # according to how long ago the PSOD was.
where-object {$_.fullformattedmessage -match "restarted"}: filters the events for those that match 'restarted'.

I'm working on turning this into an actual function that would save some typing.

Sunday, June 22, 2014

One-liner to list names, NAA ids of the boot luns in a cluster

One-liner to list hosts, datastore names, and NAAs of the boot luns in a cluster.
get-cluster "cluster01" | get-vmhost | sort-object name | get-datastore | where-object {$_.CapacityGB -lt 100} | select @{n="host";e={($_ | get-vmhost | select name).name}}, name, @{n="NAA";e={($_ | get-scsilun | select canonicalname).canonicalname}}


Broken down:
  1. Get-cluster "cluster01" - start by getting the cluster
  2. get-vmhost - get all the ESXi hosts in the cluster
  3. sort-object name - optional to sort the hosts by name
  4. get-datastore - get the datastores attached to the hosts
  5. where-object {$_.CapacityGB -lt 10} - filters only the small datastores*.
  6. Select-object - pick the properties to display
  7. @{n="host";e={($_ | get-vmhost | select name).name}} - shows the name of the vmhost
  8. name - shows the name of the datastore object
  9. @{n="NAA";e={($_ | get-scsilun | select canonicalname).canonicalname}} - shows the naa of the datastore
*Adjust this where clause depending on how you can identify the boot luns in your environment. For example, if you name all your boot luns with 'boot' in them, you could use where-object {$_.name -like "*boot*"}. I pick all the small datastores because if the datastore is less than 10GB in our environment, it's always a boot lun.

Not all the fields may display completely on your screen. You can always pipe to out-file to dump the info to a text file or pipe to format-list

Sample output:
host     Name          NAA
----     ----          ---
hostab01 hostab01-boot naa.6005076801818...
hostab02 hostab02-boot naa.6005076801818...
hostab03 hostab03-boot naa.6005076801808...
hostab04 hostab04-boot naa.6005076801808...
hostab05 hostab05-boot naa.6005076801808...

Sunday, June 8, 2014

Storage vMotion just one hard disk using PowerCLI

I was looking for a quick way to storage vMotion some of a VMs hard disks but not all of them. I found a pretty quick one-liner at ict-freak.nl
Get-HardDisk -vm | Where {$_.Name -eq "Hard disk <#>"} | `
% {Set-HardDisk -HardDisk $_ -Datastore "" -Confirm:$false}
However, I found that Set-HardDisk is deprecated. Move-HardDisk is the preferred method. The help file for Move-Hard disk had some simple examples.
$vm = get-vm "MyVM"
$mydisk = $vm | get-harddisk -name "Hard Disk 3"
$mydatastore = get-datastore -name "SAN2"
move-harddisk -harddisk $mydisk -datastore $mydatastore


These can be combined into a one-liner like so:
Move-HardDisk -harddisk (get-vm "MyVM" | get-harddisk -name "Hard Disk 3") `
-datastore (get-datastore -name "SAN2") -confirm:$false -runasync

Worked perfectly for me.