System Center Virtual Machine Manager vCheck

System Center Center Virtual Machine Manager (SC VMM) is part of the Microsoft System Center family, used to manage virtual infrastructures. The 2008 R2 version supports managing both Microsoft Hyper-V and VMware (communicating via VMware vCenter), while the 2012 version which was released in April 2012 added support for Citrix XenServer. Among the added benefits of using SC VMM for managing your hypervisor infrastructure is capabilities such as Physical to Virtual (P2V) conversion, creating virtual machines based on templates as well as having a centralized console for management. The 2012 release also added capabilities for managing private cloud infrastructures, where the managed hypervisors will be abstracted under the new Fabric bar:


There are many additional changes in the 2012 release, including the ability to manage services, storage, networking, cluster creation and many more. If you are interested in learning more I would recommend you to watch the TechNet Edge video Virtual Machine Manager 2012: Technical Overview as well as dig into the product documentation (link in the Resource section below).

Most, if not all, Hyper-V production environments I have worked with use SC VMM for management. One thing that many administrators may miss however, is a quick glance at the status of the environment. You do of course see the status of the hosts and virtual machines by opening the console, but other things such as old checkpoints and the use of dynamic virtual hard disks instead of Fixed size virtual hard disks is not easily discoverable. Since SC VMM is based on Windows PowerShell (for example, you get a “View Script” button showing the complete PowerShell code when creating a new virtual machine), gathering this information and presenting it in a report is not so difficult. Let me introduce the SC VMM vCheck:


SC VMM vCheck

If you work with both PowerShell and VMware, there is a good chance you have seen and used Alan Renoufs very useful vCheck script:

vCheck is a vCenter checking script, the script is designed to run as a scheduled task before you get into the office to present you with key information via an email directly to your inbox in a nice easily readable format.

For more information and detailed usage guidance, see this article.

Beginning with the 6.0 release of vCheck, Alan added the support for Plugins, making it easier for the community to contribute with their own checks. I had several snippets of PowerShell code for checking various things such as VMs with snapshots, so when I saw the new Plugins capability added to vCheck I thought it would be a good opportunity to provide a SC VMM Plugin. Here is the initial checks in the SC VMM Plugin for vCheck:

  • SC VMM Connection Plugin
  • General Information
  • SC VMM Basic Host Information
  • Hyper-V Cluster Shared Volumes
  • Hyper-V VMs with snapshots
  • SC VMM New VMs
  • SC VMM VM Operating System Statistics
  • Hyper-V VMs with mounted ISO
  • Hyper-V Legacy VM NIC Adapters
  • Hyper-V VMs with static MAC address
  • SC VMM Dynamically Expanding Disks
  • SC VMM Dynamically Expanding Disks Consolidation Forecast
  • Hyper-V Integration Components Version
  • Hyper-V 2008 R2 SP1 Capacity Report

As you can see I have divided the plugins into two categories, one for SC VMM which works across all supported hypervisors, as well as some specific for Hyper-V.

vCheck contains a ps1-file named GlobalSettings.ps1, where you can specify the name of the SC VMM server, e-mail settings (if you want the report e-mailed to you) as well as HTML color codes. Here you can see two examples of the same report using different colors:

image  image

You can download the plugin from this link:

SC VMM vCheck Plugin Download

If you want to add a new Plugin, all you need to do is to create a ps1-file in the Plugins-folder, preferably in a subfolder. Then you add the following 7 variables at the top of the file, and your code at the bottom. The main script will pick up objects from the Plugins, so make sure you output objects with only the desired properties. For example Get-VM | Select-Object name.

We can look at the VM Operating System Statistics as an example:

This is actually a PowerShell “one-liner” turned into a vCheck Plugin. Note that the $VMs variable contains all virtual machines managed by SC VMM and is created in the SC VMM Connectivity Plugin. The settings section is not used by the above plugin, however, this is a section intended for Plugin specific settings such as the threshold for how old snapshots you want to include in the report.

Over time the SC VMM Plugin will hopefully grow by added community contributions. If you want to contribute, or have suggestions for new Plugins, please add them to the SC VMM Plugin sites comment section, as more people will discover them there compared to this article.

If you want to hear more about the SC VMM vCheck I was interviewed to talk about it on the Get-Scripting podcast, you can download the episode from here.



System Center Virtual Machine Manager 2012 on Microsoft TechNet

System Center Virtual Machine Manager 2008 and 2008 R2 on Microsoft TechNet

Automate a task in System Center Virtual Machine Manager 2012 based on the “View Script” button

Working with scheduled tasks from Windows PowerShell

Traditionally Windows administrators is used to work with the Windows Task Scheduler using the command line utilities at.exe and schtasks.exe. Schtasks.exe was introduced as a replacement for at.exe in Windows XP/Windows Server 2003, while at.exe still exists in the latest Windows versions for backwards compatibility.

Both of the utilities works in Windows PowerShell, but they both produce text, not objects. This means we can not use for example the object manipulation cmdlets Where-Object and Select-Object on the output from these utilities. There are some tricks you can use to get the output from external applications in PowerShell into objects. An example on this is the /fo parameter on schtasks.exe, which allow us to specify the format of the output from the command. Since PowerShell has a ConvertFrom-Csv cmdlet, this means we can do this to get all scheduled tasks in object form:

schtasks.exe /query /fo csv | ConvertFrom-Csv

This allows us to use for example the Where-Object cmdlet to filter the output based on the Status-property:


To make this utilities behave more PowerShell friendly we could create custom functions which for example wraps schtasks.exe /create in a New-Task function, but still it would require a lot of work to parse the text output into custom objects.

Task Scheduler 2.0 which was released in Windows Vista and Windows Server 2008 introduced a COM-interface. This makes possible to access the Task Scheduler interface using PowerShell: New-Object -ComObject Schedule.Service

By using this COM-object we can access the Task Scheduler Scripting Objects, which produces objects rather than text. Of course this still requires a bit of work and the need to read quite a bit of documentation in order to make it user friendly for an administrator. Luckily the PowerShell team released a TaskScheduler module which builds on this COM-object as part of the PowerShell Pack, released as part of the Windows 7 Resource Kit.

When you have installed the MSI-file from the PowerShell Pack download page, you can import the TaskScheduler module and have a look at the available functions:


We can for example use the Get-ScheduledTask function to retrieve all scheduled tasks on the local computer:


This is an example of how to schedule a PowerShell script to run every day at 06.00:

# Import the module
Import-Module TaskScheduler

# Create a new task
$task = New-Task
$task.Settings.Hidden = $true

# Add an action and a trigger
Add-TaskAction -Task $task -Path C:Windowssystem32WindowsPowerShellv1.0powershell.exe -Arguments "-File C:MyScript.ps1"
Add-TaskTrigger -Task $task -Daily -At "06:00"

# Register the task
Register-ScheduledTask -Name "PowerShell - MyScript.ps1" -Task $task

When the above example is run we can find the new scheduled task in the Task Scheduler:





Or of course by using the Get-ScheduledTask function:


Instead of configuring a script file (ps1-file) to be the task action, we could have specified a script block to the Add-TaskAction function:

Add-TaskAction -Task $task -Script {“Hello World”}

Then the script block would be passed as an encoded command to powershell.exe:


An advantage of this approach is that we do not need to save our code to disk in advance to configuring it as a scheduled task.

Scheduled jobs in PowerShell 3.0

With the new version of Windows coming out later this year, we will also get a new version of Windows PowerShell. One of the new features in PowerShell 3.0 is a new module called PSScheduledJobs, which allows us to schedule jobs natively from within PowerShell. In addition, the output and results from the job is actually stored so that we can retrieve them after the job is executed, just like we could with background jobs in PowerShell 2.0.

The following information and examples is based on the Windows PowerShell 3.0 version available in the Windows 8 Consumer Preview.

Here we can see the cmdlets available in the PSScheduledJob module:


The following example is using the PSScheduledJob module to do the same as the previous example which used the TaskScheduler module from the PowerShell Pack:

# Import the module (not necessary due to the new module autoloading in PowerShell 3.0)
Import-Module PSScheduledJob

# Add a job option
$joboption = New-ScheduledJobOption -HideInTaskScheduler

# Add a trigger
$trigger = New-JobTrigger -Daily -At "06:00"

# Register the job
Register-ScheduledJob -Name "PowerShell - MyScript.ps1" -Trigger $trigger -FilePath C:MyScript.ps1 -ScheduledJobOption $joboption

If we want to specify a script block instead of a script file, we can use the ScriptBlock parameter instead of the FilePath parameter of Register-ScheduledJob:

Register-ScheduledJob -Name “PowerShell – MyScript.ps1″ -Trigger $trigger -ScriptBlock {“Hello World”}

If we look at the new task that is created from the example above we can see the following:


The arguments passed to powershell.exe:

-NoLogo -NonInteractive -WindowStyle Hidden -Command “Import-Module PSScheduledJob; $jobDef = [Microsoft.PowerShell.ScheduledJob.ScheduledJobDefinition]::LoadFromStore(‘PowerShell – MyScript.ps1′, ‘C:Users<username>AppDataLocalWindowsPowerShellScheduledJobs’); $jobDef.Run()”

We can see that the job is stored in a separate folder in the current user`s AppData-folder:


The job is defined in the ScheduledJobDefinition XML-file, and there is an empty sub-folder named Output. If I manually start the job, we can see that the following is added to the Output folder:


Next I want to retrieve the results of the job, not by looking in the XML-files, but by using the Get-Job cmdlet. There is a gotcha to be aware of regarding this. If you open a new PowerShell session and run Get-Job, the scheduled jobs created using the PSScheduledJob cmdlets will not be available. You have to first import the PSScheduledJob module and then run Get-Job. By using Receive-Job we can get the results from our job:


To read about the reason for this in addition to more details about the new module you can read the “Scheduling Background Jobs in Windows PowerShell 3.0” article on the Windows PowerShell Team Blog.


How to Schedule a PowerShell Script

Sending Automated emails with Send-MailMessage, ConvertTo-HTML, and the PowerShellPack’s TaskScheduler module

Windows PowerShell Scheduled Job Module

How to Configure Clustered Tasks with Windows Server 2012


Download TechNet Edge videos using Windows PowerShell

I recently got a question on Twitter if I could create a PowerShell script to download files from TechNet Edge. I thought this would be useful for many other people as well, so I have spent some time this weekend working on this script. I wanted to make the script as generic and re-usable as possible, so even though I started hardcoding it for downloading files from a given RSS-feed from TechNet Edge, I later on generalized it to make it easy to re-use on other websites  as well. The script is called Get-WebVideoFile.ps1, and is available on both PoshCode and the Microsoft TechNet Script Center.

How to use the script

1) The script requires PowerShell 2.0 and you must have configured your PowerShell execution policy in order to run the script. Run $host.version from PowerShell to see what version you are running. If you need help configuring the execution policy or running the script, see “Running Windows PowerShell Scripts” on Microsoft TechNet.

2) Download the script from here (PoshCode) or here (Microsoft TechNet Script Center).

3) Find the RSS URL for the category you want to download files from. On TechNet Edge you can find an overview of all categories (called tags) on this link.


In this example I have chosen the Microsoft Virtual Academy tag:


You can then find the RSS URL by clicking on the RSS icon to the right of the title on the top of the page.

4) Specify the URL on the RssUrl parameter when running the Get-WebVideoFile script:


You will get a progress bar which shows the progress for the current file:


Remember that you can also use Windows PowerShell ISE (or any 3rd party host) instead of the PowerShell console host:


More information about the script

Comment based help

At the top of the script you can see that I have added comment based help. This means you can use Get-Help to show information and example usage of the script:



You can read more about comment based help in this TechNet Magazine Article by Don Jones, as well as in the help topic about_Comment_Based_Help.


RssUrl – This is the only mandatory parameter, which provides the script the RSS feed to go through. The script download the HTML code from each RSS entrys link, and look for a URL that matches the regular expression.

Destination – The folder the files will be downloaded to. If not specified the files will be downloaded to the current users Video-folder (for example C:UsersUsernameVideos).

UseOriginalFileName – This is a switch parameter to specify that you want to use the original file names for the downloaded files. On TechNet Edge most video files got a non-descriptive name, for example e1ef34ca-cdef-463d-9c3f-94aa606bc6ab.wmv. Because of this I set the default behavior of the script to use the RSS item title as the file name.

UrlRegex – This is the regular expression that will be used to search for the video URL from the HTML code from each RSS item link. You can re-use the default regex and replace “wmv” with for example “mp4” if you want to download the MP4-versions of the videos. If you are interested in learning about Regular Expressions, I can recommend the book “Master Regular Expressions” by Jeffrey E.F. Friedl. If you want a tool to help you build the regular expression I can recommend RegexBuddy.

Verbose – This is not a parameter I have added, it is one of the common parameters in PowerShell which I want to highlight since I have added some verbose information. For example if the regular expression does not match, you can see it in the verbose output. This is a switch parameter, so you can add “-Verbose” to the script parameters to use it. You can also read more about the Verbose parameter in the about_CommonParameters help topic.

The download process

Initially when creating the script I started using the DownloadFile method of the Net.WebClient class in .NET. This worked fine, but did not provide any progress status during download. This makes it hard for the user of the script to know how long the download will take, and if anything is happening at all. I then turned to Background Intelligent Transfer Service (BITS), and the Start-BitsTransfer cmdlet which provides progress status as well as other features. For some reason the BITS jobs failed with the error message “HTTP status 404: The requested URL does not exist on the server.”. I am not sure why, but this may be because the server-side on TechNet Edge downloads does not support the necessary HTTP Requirements.

I then got a tip from Joel Bennett about his Get-WebFile function available on PoshCode. This function met my requirements, and is included at the top of the script.

The script will check the destination folder to see if the file is already downloaded, which means you can run the script several times without downloading files you already have. This is also useful when running the script as a scheduled task, which may be of interest if you want to automatically download new videos in a specific category.

Update 17.06.2012: To download videos from TechEd North America 2012 the URL regex needs to be updated. Here is an example for downloading from the WMV RSS-feed: .\Get-WebVideoFile.ps1 -UrlRegex “(?<url><file>[^>]*?wmv))” -RssUrl “”

Related resources

MMS 2012 Download Sessions – Offline Viewing (PowerShell script to download sessions from MMS 2012)