TechDays San Francisco

talkbubble-v3I’m very excited to announce that I’ll be presenting at TechDays San Francisco this year. The event runs May 2nd and 3rd. You can find the schedule here. Registration will be forthcoming. Seating will be limited so you won’t want to delay once it opens up.

As you might expect I’ll be talking PowerShell, plus a few other topics I hope you’ll find interesting. Everything is subject to last minute change but here are my current plans.

10 PowerShell Mistakes, Trips and Traps and How to Avoid Them

Windows PowerShell is a language and management technology that many IT professionals, including developers, think they understand. Yet very often they get caught up in pre-conceptions and misinterpretations, usually based on prior experience with scripting or development. This session will explore the 10 most common mistakes and traps that people fall into with PowerShell and how to avoid them.

File and Folder Provisioning with PowerShell and Windows Server 2012

If you manage file servers and aren’t using PowerShell, you are working much too hard. Or if you are using PowerShell v2 you are still working pretty hard. Fortunately PowerShell v3 along with Windows 8 and Windows Server 2012 offer a much better solution. This session will demonstrate how to provision and manage folders, files and file shares using PowerShell from a Windows 8 client. With a little up-front work, you ‘ll be able to create provisioning scripts to deploy a new file share in seconds.

Troubleshooting Active Directory with Windows PowerShell

Active Directory is one of those technologies that when it works, nobody notices. But when it doesn’t work, everyone does. Fortunately, Windows PowerShell and Windows Server 2012 make a terrific troubleshooting tool. In this session we’ll look at some common Active Directory problems, how to diagnose them and in some cases resolve, all with Windows PowerShell.

Building a Windows 8 Hyper-V Lab

We all know the benefits of testing in a non-production environment. But sometimes resources are limited and having a test setup seems like a lot of work. But now that Windows 8 includes Hyper-V, you can setup a lab environment in very little time. This session will guide you through setting up a Hyper-V based test lab and how to get the most out of it using the PowerShell management tools.

As I get more details I’ll share them here, on Twitter and on Google Plus.

Hyper-V ID Hash Table

Microsoft Hyper-VIn Hyper-V, one of the challenges (at least that I’ve run into) has to do with naming. In addition to a name, Hyper-V objects such as virtual machines, are identified with a GUID. Most of the VM-related PowerShell cmdlets will let you specify a virtual machine name. But sometimes you’ll run across the GUID and wonder what is the corresponding virtual machine. Here’s a WMI query using Get-CIMInstance that shows the currently open terminal connections to a few virtual machines.

PS C:\> get-ciminstance -Namespace root\virtualization -class msvm_terminalconnection | Select connectionID,installdate

connectionID installdate
------------ -----------
Microsoft:13876524-BFD8-40A1-95E3-926E37ACFBAB\1 1/3/2013 11:27:50 AM
Microsoft:80E967E6-57F9-4ECF-998A-D07B20B2287F\2 1/3/2013 8:12:56 AM
Microsoft:E1EDE8DA-D632-4F77-81C4-B117FFF1FE15\1 1/3/2013 8:08:35 AM

The GUID in the connection ID corresponds to a virtual machine. Here’s my approach for “translating” the GUID to a name. Every VM has an ID.

PS C:\> (get-vm chi-dc01).id


There is also an VMID property but that is merely an alias to ID. As you can see, the ID is a GUID object so to get just the GUID string takes another step.

PS C:\> (get-vm chi-dc01).id.guid

Now that I know how to capture this information, I can build a “lookup” object using a hash table.

PS C:\> Get-VM | Group-Object -property {$_.ID.GUID} -AsHashTable -AsString

Here’s what I end up with:


Naturally, it makes more sense to save this to a variable.

PS C:\> $vmhash = Get-VM | Group-Object -property {$_.ID.GUID} -AsHashTable -AsString

The VM GUID is the key and the VM object is the value. I can get items a few ways.

PS C:\> $vmhash.'13876524-bfd8-40a1-95e3-926e37acfbab'

Name State CPUUsage(%) MemoryAssigned(M) Uptime Status
---- ----- ----------- ----------------- ------ ------
CHI-FP01 Running 0 761 03:34:51 Operating normally

PS C:\> $vmhash.item('13876524-bfd8-40a1-95e3-926e37acfbab')

Name State CPUUsage(%) MemoryAssigned(M) Uptime Status
---- ----- ----------- ----------------- ------ ------
CHI-FP01 Running 0 761 03:35:11 Operating normally

PS C:\> $vmhash.GetEnumerator() | where {$ -match '13876524-bfd8-40a1-95e3-926e37acfbab'} | se
lect -ExpandProperty Value

Name State CPUUsage(%) MemoryAssigned(M) Uptime Status
---- ----- ----------- ----------------- ------ ------
CHI-FP01 Running 0 761 03:36:29 Operating normally

Now I can add some logic to my Get-CIMInstance command to resolve the GUID to the VM name.

$vmhash = Get-VM | Group-Object -property {$_.ID.GUID} -AsHashTable -AsString

Get-CimInstance -Namespace root\virtualization -class msvm_terminalconnection |
Select @{Name="Started";Expression={$_.installdate}},
#define a GUID regex

$guid = $rx.Match($_.ConnectionID).Value

I also tweaked a few other properties. I extracted the GUID using a regular expression and then found the corresponding entry in the hash table. I could have added a little extra logic to test if the GUID existed as a key but I decided to just plow ahead.


The hash table makes it very easy now to resolve virtual machine GUID’s to a user friendly name.

Importing Hyper-V VM from a PowerShell Backup

My Petri article this week is on importing Hyper-V VMs from a backup. I have many more articles on Hyper-V on Windows 8 on the site as well. You can find all of my recent posts here.

PowerShell Hyper-V Memory Report

Since moving to Windows 8, I’ve continued exploring all the possibilities around Hyper-V on the client, especially using PowerShell. Because I’m trying to run as many virtual machines on my laptop as I can, memory considerations are paramount as I only have 8GB to work with. Actually less since I still have to run Windows 8!

Anyway, I need to be able to see how much memory my virtual machines are using. The Get-VM cmdlet can show me some of the data.

Actually, there are more properties I can get as well.

Those values are in bytes so I would need to reformat them to get them into something more meaningful like bytes. Not especially difficult, but not something I want to have to type all the time. Now, I can also get memory information with Get-VMMemory and this is formatted a little nicer.

What I like about this cmdlet is that it also shows the buffer and priority settings.

In the end, I decided the best course of action was to build my own function that combined information from both cmdlets. The result is a custom object that gives me a good picture of memory configuration and current use. The function, Get-VMMemoryReport, is part of a larger HyperV toolkit module I’m developing but I thought I’d share this with you now.

I wrote the function with the assumption of piping Hyper-V virtual machines to it. Although I can also pipe names to it and the function will then get the virtual machine.

Once the function has the virtual machine object, it also gets data from Get-VMMemory.

Finally, it creates a hash table using the new [ordered] attribute so that the key names will be displayed in the order I enter them. I use this hash table to write a custom object to the pipeline. I could have used the new [pscustomobject] attribute as well, but I felt in a script using New-Object was a bit more meaningful. With this command, I get output like this:

Or I can explore the data in other ways. I can create an HTML report, export to a CSV or take advantage of Out-GridView.

Here’s the report for my currently running virtual machines.

The function defaults to connecting to the localhost, but I am assuming that if you have an Hyper-V server you could use this from any system that has they Hyper-V module also installed. I don’t have a dedicated Hyper-V server to test with so maybe someone will confirm this for me.

In the meantime, download Get-VMMemoryReport and let me know what you think.

Hyper-V VHD Summary

When I made the move to Windows 8, one of my tasks was to migrate my test environment from VirtualBox to Hyper-V. Windows 8 includes a client Hyper-V feature that is easy to use and includes PowerShell support. Plus I needed to expand my Hyper-V skills anyway, especially from the console. After setting up a number of VMs, I realized I needed to get a handle on disks: what files were in use for which VM? The Get-VM cmdlet writes a VirtualMachine object to the pipeline. One of its properties is HardDrives.

The property is actually a nested object.

That tells me where the VHD is, but not about it. For that I can use Get-VHD.

There is some great information here like sizes, type and format. All I need now is a way to combine all of this information so that for every VM I can get a summary of pertinent VHD information. This is a great scenario for using Select-Object and creating a custom property.

In the hash table, the Expression script block is running Get-VHD and returning the Size property. Eventually I want this for all VMs which means I’ll need to expand the HardDrives property.

That is very promising. In fact, let’s cut to the chase.

This function writes a summary object for each VM which means I can further sort, filter or whatever I need to do. Because this can take a bit of time to run, I’ll save the results to a variable.

One unexpected bonus was that it helped me identify a VM with a “bad” VHD reference.

This was a file I had renamed, which “broke” the virtual machine. Or I can see how much space my VHD files are taking.

Or perhaps I need to back them all up.

Awesome. But… function is based on code I developed to run from the command line which works great as a one line command. I’m not likely to have a great number of virtual machines so performance isn’t that big a deal. Plus I could always run it as a job. If I’m going to turn this into a function, perhaps it makes sense to break this up.

If you look at my function, I’m running Get-VHD multiple times for the same file. It probably makes more sense to only get it once. Here’s a revised block of code.

I’ll get the same result, and actually faster. My first version took 7.8 seconds and this takes 2.3 seconds. Because this is a function, I only have to type it once so I can add comments and even a progress message with Write-Host. This isn’t too say I can’t do this all from the console; it is just a bit more tedious.

The purpose of my post is to not only demonstrate some of the Hyper-V cmdlets, but also that what you type at the console doesn’t always make the best PowerShell script. Sometimes you need to re-think things for performance and maintainability.

Download Get-VHDSummary.