Tag Archives: powershell

Quick PowerCLI- Getting VM hardware versions

A quick PowerCLI snippet for examining what VM Hardware versions exist in your virtual environment:

Using the “Group-Object” cmdlet we can run up a quick count of all the VMs on each hardware version

Get-VM | Group-Object Version

Count Name                      Group
----- ----                      -----
42    v13                       {VM1,VM2,VM3...}
257   v8                        {VM4,VM5,VM6...}
70    v11                       {VM7,VM8,VM9...}
2     v4                        {VM10,VM11}
5     v10                       {VM12,VM13,VM14...}
2     v9                        {VM15,VM16}
2     v7                        {VM17,VM18}

This can be refined using “Sort-Object” to put the most common hardware version at the top of the list.

Get-VM  | Group-Object Version | Sort-Object Count -Descending
Count Name                      Group
----- ----                      -----
257   v8                        {VM4,VM5,VM6...}
70    v11                       {VM7,VM8,VM9...}
42    v13                       {VM1,VM2,VM3...}
5     v10                       {VM12,VM13,VM14...}
2     v7                        {VM17,VM18}
2     v9                        {VM15,VM16}
2     v4                        {VM10,VM11}

We may only be concerned with VMs that are Powered On, so “Where-Object” can be used to filter the original list.

Get-VM  | Where-Object {$_.PowerState -eq "PoweredOn"} | Group-Object Version | Sort-Object Count -Descending
Count Name                      Group
----- ----                      -----
66    v8                        {VM4,VM5,VM19...}
51    v11                       {VM7,VM8,VM9...}
33    v13                       {VM1,VM21,VM22...}
5     v10                       {VM12,VM13,VM20...}
2     v9                        {VM15,VM16}
1     v4                        {VM10}

This quick snippet can be useful when establishing the range of hardware versions in an environment, or estimating the amount of work involved in updating VM hardware to a modern standard across an estate.

Get the Windows Install Date of a remote computer with PowerShell

A quick script that came up in response to a situation where I wanted to know the date a workstation on the network was last built without visiting the machine or interrupting the currently logged on user. PowerShell to the rescue!

The WMI property “InstallDate” comes into play here.

(Get-WmiObject Win32_OperatingSystem).InstallDate

Returns a date: “20180717202039.000000+060” for my workstation. The Get-WmiObject cmdlet can again be leveraged to make this into a more usable PowerShell DateTime object:

(Get-WmiObject Win32_OperatingSystem).ConvertToDateTime( (Get-WmiObject Win32_OperatingSystem).InstallDate )

Which returns 17 July 2018 20:20:39.

Get-WmiObject can also be used on a remote computer, this example would return the date that the computer called WS12000 was built.

(Get-WmiObject win32_OperatingSystem –ComputerName “WS12000”).InstallDate

I’ve taken this work and expanded it into a PowerShell function (available on GitHub). This function “Get-BuildDate” takes one or more computer names and returns a table of build dates and, because it’s handy, the number of days that have passed since that date.

Some example usage would be:

Return the installation date of workstation 40200:

Get-BuildDate  -ComputerNames "WS40200"

Computer BuildDate           DaysSinceLastBuild
-------- ---------           ------------------
WS40200  17/07/2018 20:20:39                 55

Return the installation date of workstations WS40200 and WS46000:

Get-BuildDate ("WS40200","WS46000")

or alternatively using pipeline input:

("WS40200","WS46000") | Get-BuildDate

Finally, return a table of the last build dates for the sequentially numbered computers called WS12300, WS12301, WS12302…. right through to WS12399:

$Computers=((12300..12399) | ForEach-Object{ "WS$_"}) | Get-BuildDate

The script (and any future refinements) is available here: https://github.com/isjwuk/powershell-general/blob/master/Get-BuildDate.ps1

Find VMs being replicated to a datastore with Get-VmdkFolders

I’m using vSphere Replication to replicate a number of VMs to a datastore which is being decommissioned. I can’t reconfigure replication by code (I’ve mentioned that there’s no public API or PowerCLI around the vSphere Replication functionality in vSphere 6.5 before- most recently on Twitter)  and I can’t multi-select VMs in the vSphere Web Client and reconfigure en-mass through the GUI.

There’s also no way of telling which VMs are being replicated to this datastore without going into the reconfigure dialogues for each one individually. That’s a lot of clicking before even starting to update the configuration.

I’ve put together a PowerCLI function takes a little of this pain away by establishing which folders on a given datastore contain VMDK files. I’ve already migrated any Virtual Machines off so any remaining VMDKs on the volume should be associated with a replication process. Additionally in this case the default folder name was used when setting up the replication so all the folder names correspond to a VM.

The function is called “Get-VmdkFolders” (as there’s potentially other uses for it) and is available on GitHub here. With this I now have a list of VMs that need manually reconfiguring.

PS C:\> Get-VmdkFolders "MyReplicationDatastore"
MyVM1
MyVM2
MyVM3
MyVM5
MyVM7

 

PowerShell Snippet – Find Windows 2008 VMs before EOL

Support for Windows Server 2008 and 2008 R2 ends in January 2020– just two years from the date of this post. Four years ago I put up a script to find XP and 2003 VMs, and I’ve modified this to search a vSphere environment for powered on VMs running Server 2008 as a Guest OS:

Get-VM |
 Where {$_.PowerState -eq "PoweredOn" -and
 ($_.Guest -like "*Server 2008*")} |
 get-VMGuest |
 select VmName, OSFullName

VmName    OSFullName
------    ----------
MyVM1     Microsoft Windows Server 2008 R2 (64-bit)
MyVM2     Microsoft Windows Server 2008 R2 (64-bit)
MyVM3     Microsoft Windows Server 2008 (64-bit)
MyVM4     Microsoft Windows Server 2008 R2 (64-bit)