Using the CIM Cmdlets in Windows PowerShell to solve a challenge

Introduced in PowerShell 3.0 and further enhanced in PowerShell 4.0, the CIM (Common Information Model) Cmdlets makes it easier to work with WMI (Windows Management Instrumentation). You can find an introduction to the new CIM Cmdlets in this article on the Windows PowerShell Teams blog.

In this article we will look at a usage scenario for the new CIM Cmdlets.

The Challenge

When adding a disk to a Windows Failover Cluster, the clustered disk is added to the cluster as a resource. The resource is automatically named “Cluster Disk N”, where N is the first available number. The challenge we are going to solve is renaming the newly added cluster disk based on the name (File System Label) of the underlying disk volume. This is typically an NTFS volume which is initialized and formatted before the disk is added to the cluster:

image

Using the Failover Cluster Manager in Windows Server we can view the name of the underlying volume:

image

Based on this observation we can manually rename the cluster resource. However, in a large cluster with many disks this task is a good candidate for automation.

Solving the challenge using CIM Cmdlets

By using the Get-ClusterResource cmdlet in the FailoverClusters PowerShell module we can view information about the disk, but there isnt an easy way to view the name of the underlying volume.

Due to that, we can rather leverage the Get-CimInstance cmdlet to list all cluster resources in the MSCluster_Resource class:

image

We use the –Filter parameter to specify that we only want cluster resources of the type “Physical Disk”, if not we would also get cluster resources such as cluster IP addresses, cluster names and so on.

Based on the information available on the object produced by Get-CimInstance, we can see many cluster related properties. However, no information about the underlying volume is available.

There is one cmdlet in the CIMCmdlets module which can get all the associated instances for a particular instance – the Get-CimAssociatedInstance cmdlet. In this scenario, we want to find all related volumes for the cluster disks. We start by finding all related instances:

image

This produced a large list of different kind of objects. We can use Get-Member to view information about the objects, and Select-Object to view the unique object types:

image

Based on the above output, the MSCluster_DiskPartition looks like a good candidate. We can use the –ResultClass parameter of Get-CimAssociatedInstance in order to narrow down the results to the class we want:

image

This is excactly what we want, as we can see the VolumeLabel property on the above output.

Now that we have the information we want – the VolumeLabel property – we need to find a way to rename the cluster resource (“Cluster Disk 1”). We can start by looking for a Rename method on the MSCluster_DiskPartition object. Normally, we would use Get-Member to view the available methods:

image

Since the CIM cmdlets is using the Ws-Man (WS-Management) protocol, the objects we get returned is serialized/deserialized. Thus the objects methods is remove since we arent working with a “live” object. The Get-CimClass cmdlet can be used to get the class schema of a CIM class, which includes the methods.
Instead let`s try the Get-CimClass cmdlet to view the methods available on the mscluster_resource class:

image

As we can see, there is a Rename method which takes one parameter: newName.

In order to invoke the method, we can use the Invoke-CimMethod cmdlet where we specify Rename as the MethodName and provide the value we want to configure as a hash table on the Arguments parameter:

image

We provided the VolumeLabel property returned by the Get-CimAssociatedInstance cmdlet as the value for the newName parameter, effectively solving the challenge.

After invoking the method, we can see the name of the cluster disk is immediately updated in Failover Cluster Manager:

image

When working with multiple cluster disks, we can use a foreach loop in order to invoke the rename method for all disks  if the name of the cluster resource does not match the name of the underlying disk volume:

Resources

Browsing PowerShell Commands using a grid window

Get-CommandGridView is a PowerShell function written by PowerShell MVP Jeffery Hicks, which he blogged about here. I think this is a nice way to explore what is available in PowerShell modules and snapins. The function will show the available cmdlets in the specified module or snapin in a grid window, showing the properties Name,Noun,Verb,CommandType and ModuleName:

image

I think this is a great way to explore new modules/snapins, but I also thought it would be a good idea to leverage the new –PassThru switch on Out-GridView introduced in PowerShell 3.0 to let the user select commands to be sent to Get-Help –ShowWindow to further explore the help for interesting cmdlets/functions. I modified Jeff`s original function to provide this functionality:

Here is an example from running Get-CommandGridView -Module Hyper-V:

image

You can now select one or more cmdlets (using Shift or Ctrl + select) and then hit the OK button to bring up help windows for the selected cmdlets:

image

image

If no module is specified, all cmdlets and functions will be retrieved. That could potentially be thousands of cmdlets/functions, so in order to protect the user from opening to many help windows I added a validation attributte to the MaxHelpWindowCount parameter.

The functionality of the Get-CommandGridView function is similar to the Show Command Add-on introduced in PowerShell ISE 3.0, but I think it is more convenient when exploring new modules.

Here is a screenshot of the Show Command Add-on for those who have not seen it:

image

Converting Hyper-V VHD-files to VHDX using Windows PowerShell

With the introduction of Windows Server 2012 Hyper-V, Microsoft also provided a new format for virtual hard disk files. The previous VHD-format is now updated to a new format called VHDX. Some of the new features of the new format is much larger storage capacity (from a maximum of 2 TB for VHD, to a new maximum of 64 TB for VHDX), as well as data corruption protection during power failures. You can find more information about the new VHDX format on the “Hyper-V Virtual Hard Disk Format Overview” article on Microsoft TechNet, as well as the “VHDX Format Specification v 1.0” document which provides detailed information.

When virtual machines are migrated (imported) to a Windows Server 2012 Hyper-V host, the virtual hard disk files is not automatically converted to the new VHDX format. This is something you must do manually, either by using the “Edit Virtual Hard Disk Wizard” or by using the Convert-VHD cmdlet in the Hyper-V PowerShell module.

As soon as a virtual machine is migrated from an earlier version of Hyper-V to Windows Server 2012 Hyper-V, best practice would be to convert the virtual hard disk files to the new VHDX format.

If you have more than a couple of virtual machines, it would be a good idea to automate the conversion process. You can start to explore the Convert-VHD cmdlet by running Get-Help “Convert-VHD” –ShowWindow:

image

If you do not get a similar result as above, run Update-Help from an elevated PowerShell session and try again.

If you scroll to the bottom you will also find a few examples:

image

Example 1 shows how to convert a single VHD file to a new VHDX file. There are several things to consider before doing this in a production environment:

  • Should you keep the source VHD in case something goes wrong? If no, add the –DeleteSource swich parameter.
  • Should you use Fixed disks or Dynamically expanding disks? There are different recommendations both in the community and in Microsoft. In the Performance Tuning Guidelines for Windows Server 2012 dynamically expanding is recommended, while in this Premier Field Engineering (PFE) blog article Fixed size is recommended. To read more opinions from the community, see this article by Virtual Machine MVP Aidan Finn as well as this article by Virtual Machine MVP Thomas Maurer.
  • The virtual machine must be stop before its virtual hard disk files can be expanded.
  • The old VHD file must be replaced by the new VHDX file in the virtual machine configuration.
  • Enough disk space must be available on the underlying data disk. For example, if the VHD file to be converted is 100 GB, you must have minimum 100 GB free space on the data disk for the destination VHDX file.

I have created a sample PowerShell script below which will convert VHD-files for stopped virtual machines to VHDX. If the virtual hard disk files for the stopped virtual machines is already of type VHDX, the virtual machine will be skipped.

You may want to add additional logging and error handling before using this script in a production environment. I would also encourage to always test the script in a lab environment before using it in production.

You can find the script here on the Microsoft TechNet Script Center.

Automatically update help-files for Windows PowerShell

With the introduction of Windows PowerShell 3.0 the help system was made updateable, which means we no longer have to wait for the next release of PowerShell to retrieve enhancements and bug fixes to the help system.

In an enterprise environment the help system typically needs to be centrally managed. There are several ways to accomplish this, for example we can use the “Set the default source path for Update-Help” Group Policy setting under Computer Configuration->Administrative Templates->Windows Components->Windows PowerShell to specify a default value for the SourcePath parameter:

image

In order to automatically update help files on computers running PowerShell 3.0 we can leverage scheduled tasks and distribute these through Group Policy.

1) On a computer running Windows Server 2012 or Windows 8, create a scheduled task that will periodically run the Save-Help cmdlet to save the files to a central location. This is not mandatory, but typically large environments have computers without internet access, thus it may be appropriate to download the help files to a central file server. In order to retrieve help files for all modules you should also install all management tools from Server Manager on the Windows Server 2012 computer running the scheduled task (using Remote Server Administration Tools if running Windows 8). Note that there is a HelpModules available which removes the requirement to install the management tools made by PowerShell MVP Joel “Jaykul” Bennett. You can read more in his blog post “Get-Help for Modules you don’t have installed”.

Create a new scheduled task which runs with the computer accounts credentials (SYSTEM):

image

Note: Remember to configure the file and NTFS settings for the central file share to allow Domain Computers to read the files.

Next, configure an appropriate time when the scheduled task should run:

image

Configure an action with the Start a program option:

image

Path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Arguments: -Command "& {Update-Help;Save-Help -DestinationPath '\\server\share\PowerShell\Help-files'}"

This will first run Update-Help to retrieve the newest help-files from Microsoft, and Save-Help to save the help-files from the local computer to the central file share.

Note: You could also use PowerShell to create the scheduled task which will run Save-Help, an example can be found in this blog post by Pat Richard.

2) On a Group Policy object which will affect all computers where you want the help files to be deployed, create a new scheduled task using Group Policy Preferences:

image

Create a new scheduled task which runs with the computer accounts credentials (SYSTEM):

image

Next, configure an appropriate time when the scheduled task should run (this should run shortly after the Save-Help scheduled task is run):

image

Configure an action with the Start a program option:

image

Path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Arguments: -Command “& {if (($PSVersionTable.PSVersion).Major -ge 3) {Update-Help -SourcePath ‘\\server\share\PowerShell\Help-files’}}”

You could also use Item-level targeting in order to create the scheduled task only on computers where PowerShell 3.0 is installed (if doing so, the if (($PSVersionTable.PSVersion).Major statement above can be dropped):

image

Here we test if the key named “3” exists under the PowerShell hive in HKLM:

image

Finally the task is created:

image

When future PowerShell versions is released, for example PowerShell 4.0, the Item level targeting must be updated to check for the “4” key in the registry as well. Alternatively an even more clever method to determine that the minimum version of PowerShell is 3.0 may be incorporated (please leave a note in the comments section below if you create one).

Resources

Introducing Windows PowerShell 3.0

Now that Windows 8 and Windows Server 2012 is available, the same is true for Windows PowerShell 3.0 since it is included in the operating system. Windows PowerShell will also be available for down level operating systems (Windows 7, Windows Server 2008 and Windows Server 2008 R2) shortly, as part of the Windows Management Framework (WMF). In addition to PowerShell, new versions of Windows Management Instrumentation (WMI) and Windows Remote Management (WinRM) is included in the WMF.

What is new?

PowerShell 2.0 brought a whole set of new features including background jobs, remoting and the PowerShell ISE. In PowerShell 3.0 there have been made a great number to these features as well as many new ones. I will go through some of the major news:

Workflows – Based on the Windows Workflow Foundation the PowerShell team have brought workflows into PowerShell. A workflow is a sequence of automated steps or so called activities which performs tasks or receives data from managed devices. This makes it possible for IT Professionals to perform automated tasks against a wide variety of devices, for example software installation. A practical example is the installation and configuration of a Windows Server Failover Cluster, where installation and configuration can be orchestrated from a workflow. Among the feature set of a workflow is the ability to suspend and resume execution, no matter if the reason is planned or a temporary network outage. You can see examples and read more about this feature in this article on the PowerShell team blog.

Enhancements to PowerShell Remoting – Robust sessions is a new feature in PowerShell Remoting which makes it possible for a PowerShell Remoting session, a so-called “PSSession”, to survive a temporary network outage. Delegated administration is another new feature in remoting, where a RunAsAccount can be configured on a remoting endpoint. This makes it possible to delegate tasks to for example helpdesk user, without needing to delegate tasks on the backbone application itself.

Simplified syntax – Especially for beginners, the syntax for various parts of PowerShell might be hard to remember and understand. An example of this is the syntax for the –FilterScript parameter of Where-Object and the –Process parameter of Foreach-Object, which both accepts a so-called script block. In version 1.0 and 2.0 of PowerShell we had to use the $_.propertyname syntax inside this scriptblock. For example Get-Service | Where-Object {$_.Status –eq ‘Running’}. In version 3.0, this still works, but there is an alternate more user friendly syntax as well: Get-Service | Where-Object Status –eq ‘Running’. Here we can see that we did not have to use the curly brackets or the $_. syntax. You should note that you have to use the existing syntax if you are doing more than one comparison, however, this makes it much easier for beginners who are likely to do a single comparison in the beginning. Also experienced users will enjoy this feature since it requires less typing.

More user friendly – A lot of enhancements have been made to make PowerShell more user friendly. A common mistake for new users is not loading the required module for the cmdlet they want to run. For example, if you run Get-ADUser without first running Import-Module ActiveDirectory, you would get an error message stating that Get-ADUser is not recognized. In PowerShell 3.0 there is a new feature called module autoloading, which automatically loads the required module for the cmdlet which is being run. Another features in terms of user friendliness is the new cmdlet Show-Command, as well as the Intellisense feature in PowerShell ISE. You can read more about these two features in this and this article on the PowerShell team blog.

Windows PowerShell Web Service – makes it possible to expose a set of PowerShell cmdlets as a Restful Endpoint via OData (Open Data Protocol). This makes it possible to run PowerShell cmdlets from both Windows and non-Windows devices. Note that this feature is more targeted against advanced users and developers.

Windows PowerShell Web Access – If you have used Microsoft Exchange Server`s webmail functionality, OWA, this feature will look familiar. The sign in page for PowerShell Web Access looks very similar to the OWA sign in page. When logged in, you will be presented with a PowerShell session. This makes it easy to use PowerShell both from a web browser on your computer as well as from mobile devices such as an Iphone or Windows Phone. Note that this feature requires Windows Server 2012. You can find instructions on how to configure this feature in this article on Microsoft TechNet.

Updateable help – Until PowerShell 3.0 the help files that is parsed when you are using the Get-Help cmdlet has been a part of the installation. Updating these files have not been possible, since rolling out help files through the channels for updating the operatingsystem (Windows Update, WSUS) could not be justified. Due to this reason, it was not possible for the PowerShell team to correct errors and enhance the help files after the product had shipped. To overcome this limitation, a new feature named updateable help has been added in version 3.0. There is a new cmdlet called Update-Help you can execute in order to update the help files. If you need to download the files in order to bring them over to a computer not connected to the internet you can use the Save-Help cmdlet. You can read more about updateable help in this article by PowerShell MVP Don Jones.

Microsoft Script Explorer – Technically this is not a part of PowerShell 3.0, but rather a standalone download released in the same timeframe as PowerShell 3.0. Using Script Explorer you can search for scripts and other resources on both Microsoft TechNet as well as 3rd party repositories and local UNC-paths, for example a company repository. Script Explorer can either be run as a standalone application or integrated into the PowerShell ISE as an add-on. By integrating it to the ISE you can copy scripts you find directly in to the editor. Script Explorer will also support Windows PowerShell 2.0.

In addition to the above mentioned features, there has been made a great number of bug fixes and enhancements based on feedback from Microsoft Connect.

There have also been added a significant number of cmdlets in Windows 8 and Windows Server 2012 to administer roles, features and the operating system itself. There is about 2 400 cmdlets in Windows Server 2012, the number depends on which roles and features is installed. This is a result of the fact that Windows PowerShell was added to the Common Engineering Criteria at Microsoft in 2009.

You can find links to more new features in PowerShell 3.0 in the Resource section at the bottom of this article.

Downloads

As stated earlier, you already have PowerShell 3.0 if you are running Windows 8 or Windows Server 2012. To install PowerShell 3.0 on down level operating systems you must be running one of the following:

  • Windows 7 Service Pack 1
  • Windows Server 2008 R2 SP1
  • Windows Server 2008 Service Pack 2

Windows Management Framework 3.0: Contains new versions of PowerShell, WMI and WinRM.

Microsoft .NET Framework 4.0: This is a prerequisite for installing Windows Management Framework 3.0 on down level operating systems.

Microsoft Script Explorer will be available for the following operating systems:

  • Windows 7 Service Pack 1
  • Windows 8
  • Windows Server 2008 R2 SP1
  • Windows Server 2008 Service Pack 2
  • Windows Server 2012
  • Windows Vista Service Pack 2

Microsoft Script Explorer Release Candidate: This is the download for the Microsoft Script Explorer Release Candidate. This blogpost will be updated with a link to the RTM-version as soon as this is available.

Microsoft .NET Framework 3.5 Service Pack 1: This is a prerequisite for installing Microsoft Script Explorer. In Windows 7/Windows 8 this feature can be installed as a built-in feature.

Resources

The community around PowerShell is very active and are constantly contributing new resources. Here I have listed some resources which points you to many of these resources, both from Microsoft and the community.

  • Windows PowerShell Survival Guide– A TechNet Wiki article updated by the community. Here you can find links on how to get started with PowerShell as well as a great number of guides, books, blogs, training, videos and other resources.
  • PowerShell V3 Featured Articles– A TechNet Wiki article containing links to articles about new features in PowerShell 3.0.
  • PowerShell V3 Tips and Tricks– A TechNet Wiki article containing lots of examples about new functionality in PowerShell 3.0.
  • Windows PowerShell Support for Windows Server 2012– A Microsoft TechNet article with an overview and links to the Windows PowerShell modules in Windows Server 2012.
  • PowerShell Book Guide – An overview of various PowerShell books targeted at both beginners and more experienced users. There is also a link to a free ebook about PowerShell Remoting.