Building a PowerShell GUI (Part 6)
If you would like to read the other parts in this article series please go to:
- Building a PowerShell GUI (Part 1)
- Building a PowerShell GUI (Part 2)
- Building a PowerShell GUI (Part 3)
- Building a PowerShell GUI (Part 4)
- Building a PowerShell GUI (Part 5)
- Building a PowerShell GUI (Part 7)
- Building a PowerShell GUI (Part 8)
- Building a PowerShell GUI (Part 9)
- Building a PowerShell GUI (Part 10)
- Building a PowerShell GUI (Part 11)
- Building a PowerShell GUI (Part 12)
- Building a PowerShell GUI (Part 13)
So far in this article series, I have shown you how to create a simple Hello World script that is based around a PowerShell GUI. That particular script creates a nice output, but it doesn’t do anything useful. So with that in mind, I want to shift gears and show you how to build a GUI based PowerShell script that does something useful. In doing so, we will be using the same techniques as before, plus a few new ones.
I have thought long and hard about what type of script I could create. I wanted to do something that would illustrate some of PowerShell’s GUI capabilities, but I didn’t want to create something that is so complicated that the code becomes meaningless to everyone except for PowerShell experts. In the end, I decided to base my code around virtual machines. My plan is to start simple by adapting the Hello World script to display a list of the virtual machines that reside on a Hyper-V host. After that, I will work to further modify the script to use some other visual elements and interact with the Hyper-V host in other ways. By doing so, I can keep things relatively simple at first, but still work toward making the script useful.
Retrieving a List of Virtual Machines
PowerShell makes it really easy to retrieve a list of the virtual machines that reside on a Hyper-V server. Assuming that PowerShell is being run locally on the Hyper-V server, the cmdlet used for retrieving virtual machine data is Get-VM. You can see an example of this in Figure A.
Figure A: The Get-VM cmdlet retrieves a list of the virtual machines that exist on a Hyper-V Server.
You can of course, control the cmdlet’s output or even compile a list of every virtual machine in your entire datacenter. However, I am trying to keep things simple for now, so we will stick to using the Get-VM cmdlet in its most basic form (at least for now).
So let’s talk about the GUI. As you may recall, my Hello World script displayed a simple dialog box containing a button. Clicking on that button caused the dialog box to display the words Hello World, as shown in Figure B.
Figure B: This is the output from my Hello World script.
My goal for this article is to modify the Hello World script to display a list of virtual machines rather than displaying the words Hello World. While this probably doesn’t sound like a big deal, it is an important step. After all, we are going to be replacing static text with text that was generated dynamically.
Let’s start out by taking a look at the function that displays the text. For right now, I am leaving the bulk of the script alone. It is only this one function that I will be modifying. With that said, take a look at the code shown below:
#Define Butten Click Function
$VirtualMachines = Get-VM
Add-Type -AssemblyName System.Windows.Forms
$Label = New-Object System.Windows.Forms.Label
$Label.Text = $VirtualMachines
$Label.AutoSize = $True
$Label.Location = new-object System.Drawing.Size(88,73)
As you can see, I renamed the function to DisplayVMs, just so that the function’s purpose would be more in line with what the function is going to be doing. I have also added a line of code that creates a variable named $VirtualMachines and sets that variable equal to Get-VM. If you look further down in the function, you can see that I have set the label text to $VirtualMachines.
Before I show you what happens when you run this script, I want to show you what would ordinarily happen in the world of text-based PowerShell. If you look at Figure C, you can see that I have entered the following two commands:
$VirtualMachines = Get-VM
As you can see in Figure C, entering the $VirtualMachines command is roughly the same as typing Get-VM. The command outputs a list of my virtual machines.
Figure C: This series of commands causes PowerShell to list my virtual machines.
Now that you have seen what happens in a non-GUI environment, let’s take a look at what happens when I add a GUI interface. Figure D shows the output from my Hello World script when it is retrofit with the script above.
Figure D: This might not have been the expected output.
OK, so what happened? Well, when you assign a cmdlet to a variable and then enter the variable name, you aren’t technically telling PowerShell to show you the output (even though that looks like what is happening), you are actually telling PowerShell to execute the cmdlet that is associated with the variable. This is a very important distinction.
To further clarify things, consider PowerShell’s Write-Host cmdlet. The Write-Host cmdlet is what PowerShell uses to display text on the screen. If the $VirtualMachines variable really contained the virtual machine names, then we should be able to type Write-Host $VirtualMachines and get an output that is identical to what is shown in Figure C. If you look at Figure E however, you can see that the output is more in line with what you see in Figure D.
Figure E: We can produce the same output at the text level.
The key to being able to display dynamically generated text within a GUI is to know how to control text output in text mode. If you can do that, then displaying text in a GUI becomes much less complicated.
As you have probably already figured out, our GUI is using labels in a manner that is very similar to using Write-Host. Therefore, if we can format the text output to be displayed correctly with Write-Host, we should be able to accomplish similar results within the GUI. The trick to making this work is to understand that our variable is actually an array. Therefore, we can output the information that we want simply by specifying the item number and the object attribute that we want to display. Let me show you what I mean.
Suppose for a moment that I want to display the name of the first virtual machine that is listed within the array. The attribute name that I will need to use is Name. Since I want to look at the first virtual machine on the list, I will specify the number 0. The actual command that I will be using looks like this:
If you look back at Figure E, you can see that the first virtual machine on my list was named Anniv. Therefore, when I enter the command shown above, Anniv should be displayed as the output. You can see how this works in Figure F.
Figure F: I was able to output the name of a specific virtual machine using Write-Host.
Now, let’s see if we can do the same thing using our GUI script. This time, I am modifying the $Label.Text line to read:
$Label.Text = $VirtualMachines.Name
You can see the output in Figure G.
Figure G: We were able to display dynamic output in a GUI.
In this article, I showed you how to adapt the GUI to display a virtual machine name. In Part 7, I will continue the discussion by showing you how to better control the text output.