Learn about Windows PowerShell
Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell 3.0 to configure Hyper-V Resource Metering on Windows Server 2012.
Microsoft Scripting Guy, Ed Wilson, is here. Well, today is Monday, and the first thing I do on Monday is update the Help on Windows PowerShell 3.0. I use the command that is shown here.
Update-Help -Module * -Force
Note I need to open the Windows PowerShell console with admin rights to update Help.
Once I have updated Help, I am prepared to start the week.
Exam note One of the objectives on the Exam 70-410: Installing and Configuring Windows Server 2012 is configure Resource Metering, and so if you are working on your new MCSE for Server Infrastructure, you will want to know this material. Of course, if you are running or thinking about running Hyper-V on Windows Server 2012, you will want to know this information as well. The Introduction to Resource Metering blog post written by Lalithra Fernando on the Virtualization Blog is an excellent place to start. Lalithra also wrote a blog post called How to Use Resource Metering with PowerShell, which is also a good introduction.
One of the things is a bit confusing about Hyper-V Resource Metering on Windows Server 2012 is that I must enable Resource Metering on the individual virtual machine, but if I want to set the Resource Metering interval, I need to do that on the server that hosts the virtual machines.
Note This is the second article in a series about Hyper-V and Windows PowerShell. It is also the fourth article in a series I have written about the MCSE exam 70-410.
Therefore, to configure the Resource Metering interval, I need to use the Set-VMHost cmdlet. I can do this remotely, if my logged on account has rights to the remote Hyper-V server. This is because the cmdlet has a –computername parameter, but no –credential parameter. Of course, I can wrap the thing by using Windows PowerShell remoting, and run the command on multiple remote Hyper-V servers.
The thing that is really confusing about configuring Resource Metering is that the ResourceMeteringSaveInterval parameter requires a TimeSpan object as the input parameter. Also, the parameter only accepts whole hour values—couple this with an error in the Help example, and it is really a challenge to get this thing to work properly. (Oh, did I say that it will accept lots of things, not generate an error, and not make the change?)
So, the first thing I do is follow the example in the Help, but an error occurs. Here is the command I typed:
Set-VMHost -ResourceMeteringSaveInterval 02: 00:00
Well, maybe I do not need to do all that. Besides, it only accepts values from 1 – 24 hours, in whole numbers, so why should I type all those colons and stuff. So I try the following command:
Set-VMHost -ResourceMeteringSaveInterval 3
Cool, no errors come back. But when I check the VMHost, I see the ResourceMeteringSaveInterval has not changed. These commands are shown here.
16:52 C:\> Set-VMHost -ResourceMeteringSaveInterval 3
16:56 C:\> Get-VMHost | select resource*
So, I try it with a leading zero. Again no error returns, but no change either.
Set-VMHost -ResourceMeteringSaveInterval 03
Well, dude, this is NOT really that hard. Because I KNOW how to create a new TimeSpan, in fact, the cmdlet is New-TimeSpan, as shown here.
17:00 C:\> New-TimeSpan -Hours 3
Days : 0
Hours : 3
Minutes : 0
Seconds : 0
Milliseconds : 0
Ticks : 108000000000
TotalDays : 0.125
TotalHours : 3
TotalMinutes : 180
TotalSeconds : 10800
TotalMilliseconds : 10800000
So, all I have to do is store the TimeSpan in a variable and use that variable to configure the Resource Metering save interval, as shown here.
$rm = New-TimeSpan -Hours 3
Set-VMHost -ResourceMeteringSaveInterval $rm
Get-VMHost | select resource*
The image shown here illustrates using these commands, as well as the output associated with each cmdlet.
Well, so I found out I could actually change the value—that is good news at least. So now, of course, I want to see if I can simplify the process. The first thing I decide to do is to put the New-TimeSpan cmdlet in the ResourceMeteringSaveInterval parameter slot. Once I make the change, I use the up arrow and retrieve the Get-VMHost command where I choose the Resource* property. The output shows that the command was successful.
17:04 C:\> Set-VMHost -ResourceMeteringSaveInterval (New-TimeSpan -Hours 2)
17:09 C:\> Get-VMHost | select resource*
Well, that is cool, what about if I cast it to a TimeSpan object? I love casting stuff in Windows PowerShell. I think it is both elegant and useful. So, I use the [timespan] type accelerator to cast 01 to a TimeSpan object. The results appear here.
17:09 C:\> [timespan]01
Hours : 0
Ticks : 1
TotalDays : 1.15740740740741E-12
TotalHours : 2.77777777777778E-11
TotalMinutes : 1.66666666666667E-09
TotalSeconds : 1E-07
TotalMilliseconds : 0.0001
Well, it worked, but the problem is that I created a TimeSpan that is equal to 1 tick, and not to 1 hour. Bummer. So I add some zeros and look to see what happens. The output appears in the following image.
I now know that I can use [timespan]"01:00:00" and create a legitimate TimeSpan that measures 1 hour. But can I make it any easier? I drop a couple of zeros, and as shown here, it works.
17:14 C:\> [timespan]"01:00"
Hours : 1
Ticks : 36000000000
TotalDays : 0.0416666666666667
TotalHours : 1
TotalMinutes : 60
TotalSeconds : 3600
TotalMilliseconds : 3600000
Groovy, that worked as well. I am confident that it will work for the Set-VMHost cmdlet as well, but the only way to ensure that is to use it directly. So here goes:
Set-VMHost -ResourceMeteringSaveInterval [timespan]"12:00"
Bummer, an error occurs. I modify the command and group the [timespan]”12:00”. The revised command is shown here.
Set-VMHost -ResourceMeteringSaveInterval ([timespan]"12:00")
This time the command does not generate a command, so I use the Get-VMHost cmdlet to see if it worked. As shown in the following image, the command works fine.
Well, I know that Windows PowerShell does automatic type conversion, and I also know from the previous errors that the –ResourceMeteringSaveInterval expects a TimeSpan object. If I can convert 01:00 to a TimeSpan, will the parameter accept it? Let’s see …
17:18 C:\> Set-VMHost -ResourceMeteringSaveInterval 01:00
17:22 C:\> Get-VMHost | select resource*
Yep, it works.
I typed a lot of commands in this article. What worked? Well, storing a TimeSpan object in a variable works, as shown here:
Also, creating the TimeSpan object at the ResourceMeteringSaveInterval also worked, as shown here:
Set-VMHost -ResourceMeteringSaveInterval (New-Timespan -Hours 2)
Because Windows PowerShell does automatic type conversion, I can also supply a value that casts to a TimeSpan object, as shown here.
Set-VMHost -ResourceMeteringSaveInterval 01:00
I can also drop the leading zero if I wish, because the following command also works.
Set-VMHost -ResourceMeteringSaveInterval 5:00
Join me tomorrow when I will talk about more cool Windows PowerShell stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy