Controlling Virtual Server through Microsoft PowerShell

In his post by the same name, Ben describe a series of steps required in order to manipulate Virtual Server from PowerShell.

I'm still a PowerShell novice, so I decided to use this problem as an opportunity to see if I could make things a little easier. 

The reason it's hard is that you have to make a call to a native Win32 API, which is not accessible from PowerShell directly.  Ben's solution includes a peice of C# code that makes this call via interop, and then you have to compile it & load the assembly before you can do any work.  In my solution, my script does that work, as well.

Here's the code:

$csc = (join-path ($env:windir) Microsoft.NET\Framework\v2.0.50727\csc.exe)

$code = [IO.Path]::GetTempFileName() + ".cs"

echo @"
        using System;
        using System.Runtime.InteropServices;

        public class PowershellComSecurity
        {
            [DllImport("Ole32.dll", CharSet = CharSet.Auto)]
            public static extern int CoSetProxyBlanket(IntPtr p0, uint p1, uint p2, uint p3, uint p4, uint p5, IntPtr p6, uint p7);

            public static int EnableImpersonation(object objDCOM) { return CoSetProxyBlanket(Marshal.GetIDispatchForObject(objDCOM), 10, 0, 0, 0, 3, IntPtr.Zero, 0); }
        }
"@ > $code

$assembly = [IO.Path]::GetTempFileName() + ".dll"

& $csc /nologo /target:library /out:$assembly $code
[System.Reflection.Assembly]::LoadFrom($assembly) > $null

function SetSecurity { [PowershellComSecurity]::EnableImpersonation($args[0]) }

$vs = new-object -comObject "VirtualServer.Application"
SetSecurity($vs)

$vm = $vs.FindVirtualMachine("public")
SetSecurity($vm)

$guest = $vm.GuestOS
SetSecurity($guest)

$guest

It could use a little tuning.  If I was going to do this a lot, I'd put it all in to a new script.

Comments