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) > $nullfunction 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
Anonymous
January 27, 2007
Speedlinking #702 - SCVMM, Powershell, and the VHD program Here are some general Virtualization news...Anonymous
January 30, 2007
That's a good way to do it. In fact, for simple P/Invoke calls, you might also consider the Invoke-Win32 library I wrote some time back, or the inline C# library I wrote: http://www.leeholmes.com/blog/GetTheOwnerOfAProcessInPowerShellPInvokeAndRefOutParameters.aspx http://www.leeholmes.com/blog/MorePInvokeInPowerShell.aspx http://www.leeholmes.com/blog/LibraryForInlineCInMSH.aspx I believe this should work for the invoke -- I don't have the virtual server manager COM object to test with, though. $parameterTypes = [IntPtr], [uint32], [uint32], [uint32], [uint32], [uint32], [IntPtr], [uint32] $idispatch = [System.Runtime.InteropServices.Marshal]::GetIDispatchForObject($objDcom) $parameters = [IntPtr] $idispatch, [Uint32] 10, [UInt32] 0, [UInt32] 0, [UInt32] 0, [Uint32] 3, [IntPtr]::Zero, [Uint32] 0 Invoke-Win32 "ole32" ([Int]) "CoSetProxyBlanket" $parameterTypes $parameters