HaveComputerWillCode.Com

Welcome!
Life is a Non-Deterministic Finite State Automata
Automation ? (*pGeekiness)++ : Code /eneration;

December 3, 2010

Launching LEViewer.EXE from within SCVMM

Filed under: ALM,Testing — Tags: , , , — admin @ 8:31 am

(and using SCVMM PowerShell to query running Lab Center Environments)

You can download the PowerShell script here (CORRECTION: 4th December: I fixed a bug in Filter-LabMachines so it returns $machine instead of $InputObject).

The PowerShell interface that drives SCVMM is awesome but it doesn’t provide anything out of the box that helps you write queries against virtual machines deployed by Lab Center. As far as SCVMM is concerned, any VM’s deployed by Lab Center are just VM’s. This post will (eventually) provide a few crude helper methods so you can use PowerShell to show all running virtual machines grouped by Project, Lab Center environment or whatever.

When using Lab Center and you right click on a running environment and select “Connect”, it launches the Lab Environment Viewer (LEViewer.EXE):

Ultimately, the virtual machine(s) you connect to using LEViewer.EXE are running on a Hyper-V host managed by SCVMM in a mysterious part of your Enterprise. For reasons of pure geekiness, I wanted to launch that viewer from within the SCVMM PowerShell console based on Virtual Machine queries. How?

By using Process Explorer, it’s easy to inspect the running LEViewer.EXE command line and you’ll see something like this:

Kool! So if we can get at the TFS Collection, the Environment and the Virtual Machine we want to connect to from within SCVMM, we can launch LEViewer in that context from PowerShell. We can do that!

When you deploy a virtual machine using Lab Center, it is given an aesthetically pleasing random-GUID name like so:

But it’s “Description” field within SCVMM yields all of the useful information we require (the Description field is set by Lab Center). Right click the machine and select Properties:

So all we have to do is to extract that information and construct the command line. To make it easier, I’ll do things ‘the properish way’ and write helper functions that can be used in the PowerShell pipeline:

function global:Filter-LabMachines 
{
param([Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        	[PSObject[]]$InputObject)

    BEGIN 
	{
   	}	
    PROCESS 
    {
        	foreach ($machine in $InputObject) 
		{
			try
			{
				# Turn the Description into an Object so we can walk it. [xml] has to be one of the most underrated PowerShell features *EVER!*
				$labDescription = [xml] $machine.Description;
				$crudeThrowawayChecker = $labDescription.LabManagement.LabEnvironment;
		
				# Add some dynamic member properties
				Add-Member -MemberType NoteProperty -Name LabTfs -InputObject $machine -Value $labDescription.LabManagement.TFS;
				Add-Member -MemberType NoteProperty -Name LabProject -InputObject $machine -Value $labDescription.LabManagement.Project;
				Add-Member -MemberType NoteProperty -Name LabProjectCollection -InputObject $machine -Value $labDescription.LabManagement.Collection;

				Add-Member -MemberType NoteProperty -Name LabEnvironmentId -InputObject $machine -Value $labDescription.LabManagement.LabEnvironment.Id;
				Add-Member -MemberType NoteProperty -Name LabEnvironmentName -InputObject $machine -Value $labDescription.LabManagement.LabEnvironment.InnerText;

				Add-Member -MemberType NoteProperty -Name LabSystemId -InputObject $machine -Value $labDescription.LabManagement.LabSystem.Id;
				Add-Member -MemberType NoteProperty -Name LabSystemName -InputObject $machine -Value $labDescription.LabManagement.LabSystem.InnerText;

				# If we get to here, it is probably a candidate for being a Lab-Deployed Virtual Machine
			        $machine;
			}
			catch
			{
	
			}
		}
        }
    	END 
	{
    	}
}

The idea is that you use something like this to identify all Virtual Machines managed by Lab Center:

Get-VM | Filter-LabMachines

Get-VM is part of SCVMM; when the virtual machines are piped through our Filter-LabMachines, we only pass lab machines down the pipeline. I have decided that a VM is a Lab Machine if it has a ‘Description’ field that looks like XML. The additional crude test for this is to use the [xml] caster in PowerShell and then walk the object to extract the properties we need. Note the use of ‘Add-Member’: I augment the $machine with the value of the Lab properties so I don’t have to recalculate them. The PowerShell type system *ROCKS!*

So with a list of machines that were (probably) deployed by Lab Center, we can now dump the SCVMM Name and the name of the Virtual Machine as seen in Lab Center (see LEViewer.EXE above):

Get-VM | Filter-LabMachines | Select-Object -Property LabProject,LabEnvironmentName,LabSystemName

So it looks like this:

Now we can use PowerShell to show all running Lab Center environments and the projects to which they belong. ie:

Get-VM | Filter-LabMachines | Where-Object { $_.Status -eq "Running" } | Select-Object -Property LabEnvironmentName,LabSystemName | Sort-Object -Property LabEnvironmentName | Format-Table -GroupBy LabEnvironmentName

And finally to launch LEViewer to connect to our environment from PowerShell in SCVMM, we just need to pick an environment with a running virtual machine and pipe it into Start-LEViewer:

Get-VM | Filter-LabMachines | Where-Object { $_.LabProject -eq "Grom" } | Where-Object { $_.Status -eq "Running" } | Sort -Property LabEnvironmentName -Unique | Start-LEViewer

The helper method ‘Start-LEViewer’ is here:

function global:Start-LEViewer 
{
param([Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
        	[object[]]$InputObject)

    BEGIN 
	{
    }	
    PROCESS 
	{
        foreach ($machine in $InputObject) 
		{
			# Turn the Description into an Object so we can walk it. [xml] has to be one of the most underrated PowerShell features *EVER!*
			$labDescription = [xml] $machine.Description;
		
			# The Command Line of a spawned LEViewer looks something like this:
			#
			# "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\leviewer.exe" /tfsUri:http://win-tskurfclu7g:8080/tfs/defaultcollection /environmentUri:vstfs:///LabManagement/LabEnvironment/192 /systemUri:vstfs:///LabManagement/LabSystem/193
				
			$executable = "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\leviewer.exe";
			$p = "/tfsUri:$($labDescription.LabManagement.TFS)/$($labDescription.LabManagement.Collection) /environmentUri:vstfs:///LabManagement/LabEnvironment/$($labDescription.LabManagement.LabEnvironment.Id) /systemUri:vstfs:///LabManagement/LabSystem/$($labDescription.LabManagement.LabSystem.Id)";
 
			[System.Diagnostics.Process]::Start($executable, $p);
		}
	}
	END
	{
	}
}

Thanks to this link for information on writing PowerShell Advanced Functions to use the Pipeline.

Tchau!

Powered by WordPress