Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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