Welcome to TechNet Blogs Sign in | Join | Help
Scripting Hyper-V with WMI and PowerShell: Part 1 – Introduction + Querying State

Scripting Hyper-V with WMI and PowerShell

Part 1 – Introduction + Querying State

 

Introduction

When it comes to scripting Hyper-V there are really 2 methods:

1.       Using the virtualization WMI provider that ships with Hyper-V.

2.       Using the cmdlets provided by System Centre Virtual Machine Manager 2008

So which option should you use?  Well if you want an easy life, the answer is absolutely Option 2.  Use SCVMM 2008, and scripting Hyper-V is like a pleasurable dream.  The cmdlets are task orientated, provide a rich set of features and really do work very well.  So why is this a guide to Option 1 – Using the virtualization WMI provider?  Well, sometimes Hyper-V will be used without an accompanying System Centre deployment, and if that’s the case, using WMI is your only scripting option.

I`ll be honest, using the WMI provider to script Hyper-V is unintuitive, complicated and feels quite clunky.  So the question has to be asked “Why is the Hyper-V WMI provider so difficult to use?”  The answer is Industry Standards.  The virtualization WMI provider fully complies with the standards outlined by the Distributed Management Task Force (DMTF).  Whilst standards are great for creating consistency among different vendors, there are often comprises with the simplicity of individual solutions. Contrastingly the SCVMM cmdlets are a bespoke solution designed by Microsoft to be simple, intuitive and powerful, but do not adhere to any industry standards.

So, with the expectation that the Hyper-V WMI journey will be a challenging one, let’s get on with it.

 

WMI Basics

As mentioned we will be using the virtualization WMI provider, and before going any further I would strongly recommend that you spend some time understanding WMI to a reasonable depth.    If you can answer the following questions, you’re probably familiar enough with WMI to get the most out of this tutorial:

1.       What is namespace?

2.       What is a class?

3.       How do you create a WMI Object in PowerShell?

Basic WMI information is out of scope for this tutorial, so if you can’t answer the above questions, before continuing I would suggest the following pre-reading/viewing:

1.       Brief WMI Intro on Technet Edge -  http://edge.technet.com/Media/Powershell-tips-and-tricks-from-the-field-with-Ben-Pearce

2.       Windows, PowerShell and WMI – Tech Ed 2008 Session http://www.microsoft.com/emea/spotlight/sessionh.aspx?videoid=996 

3.       Microsoft Windows PowerShell Step by Step Book- http://www.microsoft.com/MSPress/books/10329.aspx

 

Hyper-V + WMI

There are 2 key points you need to understand to start using the Hyper-V WMI provider. 

1.       All Hyper-V classes live in the “Virtualization” namespace.  Therefore whenever you want to instantiate an object you need to specify this namespace.  The following sample lists all the classes available in this namespace:

Get-WMIObject –namespace “root\virtualization” -list

 

2.       PowerShell must be elevated and running as an administrator.  If you run PowerShell in a non-administrative context you will not be able to connect to any guests, and will only be able to affect the host.  In Server 2008 you need to right-click the PowerShell icon, then click “Run As Administrator” to achieve this, even if logged on as an administrator.

VMStateQuery

Often, I find the best way to learn something is with a worked example.  Attached to this post is VMStateQuery.ps1, which is an example PowerShell script which can be used to determine the state of guests deployed to a Hyper-V host.  The script can be used to return the state of all guests on a host, or the state of 1 particular guest. 

Usage

.\VMStateQuery.ps1

This returns a list of all guests and their state, sorted alphabetically.

.\VMStateQuery.ps1 -vhost myremotehost -sortbystate

This returns a list of all the guests on MyRemoteHost, and sorts the guests by state.

.\VMStateQuery.ps1 –vhost myremotehost –vguest MyGuest1

This returns the state of the guest MyGuest1, running on the host MyRemoteHost.

Explanation

Let’s dig into some interesting parts of this script. 

The only time we use WMI in this example is in this 1 line:

$vms = Get-WMIObject -Class Msvm_ComputerSystem -Namespace "root\virtualization" -ComputerName $vhost

 

This line connects using WMI and retrieves all instances of MSVM_ComputerSystem on the computer specified by $VHost.  This line returns an array of all guests and the host, each one represented by an object.  In order to find out what we can with this object type we can do two things.  Firstly, use Get-Member to obtain all properties and methods, or use this MSDN link, which details each property and method. 

Having looked at the properties of this object we can see 2 properties that will be particularly useful when trying to query a guest’s state: elementname and enabledstate.  ElementName is the name of the guest that you see in the Hyper-V MMC console, and enabledstate is a number that represents the state of the machine.

This bit of code filters our array of guests, and returns any that match the following

$vms = $vms | where-object {$_.elementname -eq $vguest}

 

We simply use where-object to filter, such that only guests whose elementname equals $vguest are retained.

We use the enabledstate property to identify the state of the machine.  However, the state of the machine is a number which might not make too much sense.  Therefore I’ve created a function called ConvertStateToFriendly which simply uses a switch statement to return a friendly word for the state.  The call to this function is nested as an expression that can be used by the format-table cmdlet to display the information nicely.  Here’s the code:

$statefriendly = @{Expression={convertStateToFriendly $_.enabledstate};Label="State";width=25}

$vms | format-table Elementname, $statefriendly

 

This code looks a little bid nasty, but is simply a way of creating custom tables. More details on how this mechanism works can be found here.

One final part I want to explain is this line:

$vms = $vms | where-object{$_.caption -ne "Hosting Computer System"}

 

When you get all instances of MSVM_ComputerSystem, one of the returned objects represents the host system.  In this script I am not really interested in the state of the host, just the state of the guests.  Therefore the above line simply looks at the caption property of the objects, and drops the object with the name “Hosting Computer System”.

All the rest of the script is generic PowerShell code, used for parameters, error checking and other useful bits and pieces.

Hyper-V WMI Resources

The two best resources for Hyper-V WMI scripting that I have come across so far are the MSDN page, and James O’Neil’s Hyper-V management library on CodePlex.  The MSDN page is the definitive source on the WMI provider and is here:

http://msdn.microsoft.com/en-us/library/cc136992(VS.85).aspx

The Code Plex project which James uploaded is a pretty comprehensive library on managing Hyper-V and WMI.  It’s an excellent source, but be warned it is pretty hardcore and very code efficient in places, which can sometimes be quite tricky to understand (maybe that’s just me J)

http://www.codeplex.com/PSHyperv

 

My colleague Richard Macdonald has written a very similar script, but using C# instead of PowerShell.  Check out his blog here for the code.

Well that’s it for part 1.  Stay tuned for Part 2 –Hyper-V Data Gathering.

 

Enjoy


BenP

Inteverview with me on Technet Edge

Hi All

I got kidnapped by the Tech Net Edge guys whilst I was at Tech Ed the other week, and intereviewed about the PowerShell and WMI session that I was presenting there.  If you'd like to see the interview in full it's here:

 http://edge.technet.com/Media/Powershell-tips-and-tricks-from-the-field-with-Ben-Pearce/

You might need to use "the force" whilst watching the demos, as sadly some of the commands I was using were slightly off the screen.

 Have fun


BenP

How to Configure a Server Core Domain Controller: Vanilla to First DC in a Forest

Hi All

 

Sometimes you just want a new Domain created quickly for a bit of testing.  Given that Windows 2008 ships with server core, a light footprint version of the OS, it’s ideal for being the domain controller.  As I am fairly inexperienced with Server Core I had to search all over the place to find information on how to go from a vanilla server core build, to a dc running a brand new domain.  I figured out a set of commands that achieve this, so thought I would share them with the world. 

 

Rename Host

Netdom renamecomputer <OldName> /NewName:<NewName>

 

Set IP

netsh int ip set address "Local Area Connection" static 192.168.0.210 255.255.255.0 192.168.0.1 1

 

Set DNS

Netsh interface ipv4 add dnsserver name=”<idxname>” address=<IP Address> index = 1

 

Install DNS Role

start /w ocsetup DNS-Server-Core-Role

 

Create New Domain

dcpromo /unattend:c:\unattend.txt

 

Unattend.txt Contents

[DCINSTALL]
AutoConfigDNS=Yes
DomainNetBiosName=benpdom
NewDomainDNSName=benpdom.com
ReplicaOrNewDomain=Domain
NewDomain=Forest
ForestLevel=3
DomainLevel=3
SafeModeAdminPassword=Password1234
RebootOnSuccess=Yes

 

Another cool Server Core reference can be found on Mark’s blog here:

 

http://blogs.technet.com/mempson/archive/2008/03/19/server-core-quick-reference-guide.aspx

 

Hope this helps

 

Cheers


BenP

 

Tech Ed 2008 - Demo 5 - Administering Failover Clustering

Finally, here is the last demo.

Demo 5 – Administering Failover Clustering

I have already written a detailed post, and a similar script on this subject, here.  However, I promised all the demos would be on my blog, so attached is the exact script I used at Tech Ed 2008.

Enjoy!


BenP

Tech Ed 2008 - Demo 4 - Administering Hyper-V

So here is Demo  4 – Administering Hyper-V

 

I am planning to put more posts on my blog, looking at this subject in more depth, so stay tuned for more in depth demos.  This was is what I demo’d at Tech Ed 2008.  Notice the namespace that is used:

Gwmi –namespace “root\virtualization” –list

 

Gwmi –namespace “root\virtualization” –class msvm_computersystem | get-member

 

Gwmi –namespace “root\virtualization” –class msvm_computersystem | format-table elementname, enabledstate

 

 

Thanks


BenP

 

Tech Ed 2008 - Demo 3 - How do I Know Which Classes to Use

Ola

Demo 3 – How Do I Know Which Classes to Use

In this demo I firstly used WMI Browser, which provides a GUI that can be used to visually display WMI information.  That can be downloaded from here:

I then browsed for classes in PowerShell.  I have already documented this on my blog and it can be found here:

Phew, that was a short post.

Enjoy!


BenP

Tech Ed 2008 - Demo 2 - Administering Servers in Bulk

Bonjour Bonjour

It’s time for Demo 2 – Administering Servers in Bulk.  I’ve attached the 4 scripts that I used.

Demo 2 – Administering Servers in Bulk

BulkServers1.ps1 – This script reads in a text file, containing 1 server per line.  It simply then writes the server names back to the console

BulkServers2.ps1 – This script extends the first script and simply gets the hostname, operating system and service pack level for each server listed in the input file.

BulkServers3.ps1 – This script gets a little bit more complex and in fact is rather exciting.  It again reads an input file and for each server, gets operating system information, bios information, writes this to a CSV file and then opens the csv file in your default CSV file handler.

BulkServers4.ps1 – The piece de resistance!  This script is very similar to the above script, except that rather than read an input file with server names, it connects to the Domain Controller container in the Active Directory, and gets information from all computers in that container.

Please note, there is no error checking in these scripts, and are purely working illustrations.  I would flesh these scripts out a bit more before I used them in anything other than a test infrastructure.

All done, stay tuned for Demo 3 – How Do I Know Which Classes to Use

That is all.


BenP

Tech Ed 2008 - Demo 1 - Administering Windows

Hello Again

Well I’ve delivered my session “Windows, PowerShell and WMI: Unveiling Microsoft’s Best Kept Secret”, and as promised here are the scripts for the Demo’s I used during my session:

Demo 1 – Administering Windows

All these demos are simple command lines that I just typed straight in PowerShell, no need for any fancy scripts.

Basics

The following lines of code show help on how to use the Get-WMIObject cmdlet in PowerShell, how to list all classes in the cimv2 namespace and finally how to use some basic parameters.

 

Get-Help -name Get-WMIObject

Get-Help -name Get-WMIObject –det

get-wmiobject -namespace "root\cimv2" –list

Gwmi -namespace "root\cimv2" –list

Gwmi -namespace "root\cimv2" -class Win32_LogicalDisk

Gwmi -class Win32_LogicalDisk

Gwmi Win32_LogicalDisk

Gwmi Win32_LogicalDisk –computername localhost

$cred = get-credentials

Gwmi Win32_LogicalDisk –credential $cred

 

Disks

These lines of code show how to get disk information from a system, identify all the properties and methods of the disk objects that can be used, then uses some properties.

Gwmi Win32_LogicalDisk | Get-Member

$disks = gwmi Win32_LogicalDisk –computername localhost

$disks[0].freespace

$disks[0].freespace/1gb

$disks[0].filesystem

 

Hotfixes

These lines connect to a system and list all the Hotfixes that have been installed.

$hotfixes = gwmi Win32_QuickFixEngineering –computername localhost

$hotfixes | get-member

$hotfixes | format-table Hotfixid

 

 

OperatingSystem

These lines enumerate basic operating system information: the OS version, service pack level and OS architecture type.

$os = gwmi win32_OperatingSystem -computername Serverxxx

$os | get-member

$os | format-list caption, CSDVersion,OSArchitecture

 

Network Adapter

The following lines modify the IP Address and Subnet Mask of a network adapter using the EnableStatic method.

$nics = Gwmi win32_NetworkAdapterConfiguration

$nic = $nics | where{$_.description –like “*XXXXXXXXXXXX*”}

$IPAddress = x.x.x.x

$subnetmask = x.x.x.x

$nic.EnableStatic($IPAddress, $SubnetMask)

 

Well that’s the first demo stay tuned for Demo 2 – Administering Servers in Bulk.


Enjoy!


BenP

Listing WMI Namespaces installed on a host

Ladies and Gents

Many months ago I posted a script on how to search a namespace for different classes.  The post is here

A common question I then get asked is “How do I know what WMI namespaces are installed on a system?”  The answer is not immediately obvious so I thought I’d share it with you all.

 

 

Get-WMIObject -class __Namespace -namespace root | Format-Table name

 

 

I get the following output from my Vista RTM machine.

 

name

----

subscription

DEFAULT

MicrosoftDfs

CIMV2

Cli

Nap

SECURITY

SmsDm

RSOP

ccm

WMI

directory

Policy

ServiceModel

SecurityCenter

MSAPPS12

Microsoft

Aspnet

 

So by searching the host for a list of namespaces, and then searching each namespace for the classes available you can find some really useful stuff.

 

Hope this helps

 

BenP

PowerShell To Be Added to Common Engineering Criteria

Hi All

Some of you may of heard about this already, but it's recently been announced that PowerShell will be in the Microsoft Common Engineering Criteria for 2009.

What is the Common Engineering Criteria?

The Common Engineering Criteria is a set of criteria that each Microsoft server product should adhere to. The criteria was set up in 2005 and has been updated each year with a new set of requirements.  The word on the street is that in 2009, PowerShell support will be added to this list, meaning that from 2009 all server products that are released should have full PowerShell support.  Wahoo!

For more details on the Common Engineering Criteria check out the homepage: http://www.microsoft.com/windowsserversystem/cer/allcriteria.mspx

For a checklist of the current criteria, and a report on which products implement them, check out this link: http://www.microsoft.com/windowsserversystem/cer/report.mspx

So to all those that haven't learnt PowerShell yet ... it is time.  PowerShell is not going away!

 

Cheers all


BenP

Intro to SCVMM

Hi All

I had the pleasure of presenting a joint session at the PowerShell UK User Group this week.  I presented a joint session with Jeremy Peck from HP on an Introduction to SCVMM and scripting it with PowerShell.  I have attached my slide deck from the first half of the session.  In order to see Jeremy's deck with PowerShell examples, and the other sessions that were presented at the event please see the links on the Get-PSUGUK homepage (if they are not there yet Richard Siddaway should have them up soon)

http://www.culminisconnections.com/sites/get-psuguk/default.aspx

Enjoy


BenP

Vista Event Logs and PowerShell
Hello Everybody
 
Sorry for the huge delay in posting anything, I promise I will never leave it so long again. 
 
I got asked a question the other day.  Can I use Get-EventLog to access all the new logs that are in Vista?
 
Which logs am I referring to you may ask. Well, there are loads of new logs that can provide a massive set of troubleshooting information. Here's a screen shot from my Vista laptop that shows some of the logs:
 
image
 
So the question is can I query the Backup, Bits-Client, DiskDiagnostic and all the other logs using the Get-Eventlog cmdlet.
 
In short no.  You can however still use PowerShell, but you need to use a command line tool that ships in Vista, wevtutil.exe.  You can find out all the logs that can be accessed using Get-Eventlog with the -list parameter. 
 
PS C:\Users\benp> Get-EventLog -list

  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
  15,168      0 OverwriteAsNeeded       1,381 Application
  15,168      0 OverwriteAsNeeded           0 DFS Replication
  20,480      0 OverwriteAsNeeded           0 Hardware Events
     512      7 OverwriteOlder              0 Internet Explorer
     512      7 OverwriteOlder              0 Key Management Service
   8,192      0 OverwriteAsNeeded           0 Media Center
  16,384      0 OverwriteAsNeeded           0 Microsoft Office Diagnostics
  16,384      0 OverwriteAsNeeded          29 Microsoft Office Sessions

  15,168      0 OverwriteAsNeeded       4,109 System
  15,360      0 OverwriteAsNeeded          40 Windows PowerShell
 
All of the above logs are part of the standard Windows Event Log.  However, all of the the other logs in the screenshot use Windows Eventing 6.0.  Get-EventLog does not hook into Windows Eventing 6.0.
 
So how can I get at these logs using PowerShell?  Check out the sample below:
 
PS C:\Users\benp> wevtutil.exe qe Microsoft-Windows-UAC/Operational /c:2 /f:text
Event[0]:
  Log Name: Microsoft-Windows-UAC/Operational
  Source: Microsoft-Windows-UAC
  Date: 2007-10-30T11:14:00.524
  Event ID: 1
  Task: N/A
  Level: Error
  Opcode: Info
  Keyword: N/A
  User: S-1-5-21-1721234763-462695806-1538865281-2692397
  User Name: testdom\benp
  Computer: vista.test.microsoft.com
  Description:
The process failed to handle ERROR_ELEVATION_REQUIRED during the creation of a child process.

This sample connects to the UAC Operational log and displays the newest 2 items as text.  (There is only 1 event listed, because I only have 1 entry in the log).

So yes I can access these logs using PowerShell, but no I can't use the Get-EventLog cmdlet to do it.  Check out the following link for detailed syntax for using wevtutil.exe

http://technet2.microsoft.com/windowsserver2008/en/library/d4c791e0-7e59-45c5-aa55-0223b77a48221033.mspx?mfr=true

Thanks to Narayanan Lakshmanan for answering the many questions I had about this.

That is all


BenP

Scripting Virtual Server with PowerShell - Create-ChildVM.ps1

Hello

I hate writing up scripts.  Writing the scripts themselves is great, it’s just explaining them after which is really boring J

 

Here is the second demo script I used last week, Create-ChildVM.ps1.  This script is invaluable if you need to quickly deploy machines in a test lab.  I say test lab rather than production because this script uses differencing disks, which do not perform as well as fixed disk.  They are great to use when you have disk space constraints, but on a beefy production system I would use fixed disks.  A differencing disk has a read-only parent disk which can be used to store the operating system.  Then any changes made to the disk are actually stored in the differencing disk.  In this example my parent disk is a Windows 2003 SP2 sysprepped disk.  The child then holds any differences.  Multiple children can point to the same parent and parent disks can be chained together.

 

This script takes no parameters, and provides a menu system.  The VM is created in seconds and the machine is up running in a matter of minutes.

I won’t explain the whole script, but just shout if you have any questions.  There is no error checking in this script.  Version 2 will have some error checking built in – I promise J

Thanks go to Steven Adler who's code I plagiarised for some (most) of the sections.

Cheers


BenP

Scripting Virtual Server with PowerShell - CAP-ISO.ps1

Hello Everyone

As promised, attached is the first fo the demo scripts that I used at the “Scripting Virtual Server with PowerShell” session I ran.  I`m not going to go through the whole script but here is an over view and bit more detail on a few key sections.

Script Synopsis

CAP-ISO.ps1 stands for CreateAndPresent-ISO.ps1.  This script can be used to create an ISO file comprising of a given set of files.  This iso is then presented to a guest VM.  I find this particularly useful to run on my laptop with Virtual Server installed.  Essentially this is a quick way of getting files from a host to a guest without having to worry about the network setup. 

Interesting Bits

I should probably give this section a more descriptive title, but you get the idea.  Here’s some of the more interesting sections of the script.

 

Firstly, this script just wraps around an existing command line tool to create the ISO.  This tool is called OSCDIMG.EXE and ships with the Windows Automated Installation Kit (WAIK).  You will need to download the tool, and modify the script to point to its install location.  The WAIK can be downloaded here: http://www.microsoft.com/downloads/details.aspx?familyid=C7D4BC6D-15F3-4284-9123-679830D629F2&displaylang=en

Let’s look at some code.  I don’t want to duplicate what Virtual PC Guy, Ben Armstrong has already written so for a basic guide to scripting Virtual Server with PowerShell go here: http://blogs.msdn.com/virtual_pc_guy/archive/2006/06/13/630165.aspx

So, as Ben Armstrong discussed, you must first have the dll somewhere on the system, and then must reference it from the script.  You also need to be running as admin (and elevated if in Vista).  Here is how to reference the dll.

$result = [System.Reflection.Assembly]::LoadFrom(“$profdir\VSWrapperForPSH.dll”)

 

$profdir is a variable I have created in my profile that points the variable to my profile directory.

I then create a Virtual Server Com Instance like this:

$vs = new-object -com VirtualServer.Application -Strict

 

The next essential part is to set the security on the object.  I do this using a function called setsecurity which can be called anytime.  Here’s the function and an example call to it:

function setsecurity($Object)

{

     $result = [Microsoft.VirtualServer.Interop.PowerShell]::SetSecurity($Object)

    

}

 

$result = SetSecurity $VS

 

I then have to call this function every time I create a new Virtual Server based object.  Whether it’s a VM object, DVD Drive, Hard Disk or any other object I have to set the security once I have created the object.

Have a look through the script and if you have any questions, just post them in the comment section.

For more information on scripting Virtual Server with PowerShell check out Ben Armstrong’s most excellent book, Professional Microsoft Virtual Server 2005, Wrox Publishing.  Check out Ben’s blog for more information on the book:

http://mumblingtomyself.spaces.live.com/blog/cns!64FFB030F5637A64!128.entry

 

Enjoy!

 

BenP

Scripting Virtual Server with PowerShell

Bonjour Bonjour

Last night I was kindly invited to speak at the PowerShell UK User Group meeting.  The subject I delivered was "Scripting Virtual Server with PowerShell".  I was asked if I could post my slide deck, so here it is in both pptx and ppt format (I got burned for using just the new office format before :) )

The slide deck is not very verbose, so might not make the most sense if you didn't attend the session, but could still be useful.  I will publish the demo scripts that I used somtime next week.  I just need to clean them up a little bit before I show them to the world.

 

Enjoy


Ben

More Posts Next page »
Page view tracker