Controlling Virtual Server through PowerShell

Controlling Virtual Server through PowerShell

  • Comments 4

A number of people have been asking me about using PowerShell to control Virtual Server.  This is a very cool idea - however, out of the box it does not work.  If you try and access the Virtual Server COM object (with a command like: $vs=new-object –com VirtualServer.Application –Strict) it will succeed - but inspecting the object will show no data:

Virtual Server and PowerShell

The reason this happens is that PowerShell is a .Net application - and as a .Net application it does not run with sufficient privilege to be able to talk to our COM interfaces.  In order to address this - you will need to make a library that allows you to set the COM security level on an object to 'impersonate'.  Below is a chunk of C# code that does exactly this (I have attached this code in a file to this post as well):

using System;
using System.Runtime.InteropServices;
using System.Reflection;

namespace Microsoft.VirtualServer.Interop
{
   
using System;
   
using System.Runtime.InteropServices;
   
using System.Reflection;

   
public class 
   Powershell
   {
      
const uint EOAC_NONE = 0;
      
const uint RPC_C_AUTHN_WINNT = 10;
      
const uint RPC_C_AUTHZ_NONE = 0;
      
const uint RPC_C_AUTHN_LEVEL_DEFAULT = 0;
      
const uint RPC_C_IMP_LEVEL_IMPERSONATE = 3;

      [
DllImport(
         
"Ole32.dll"
         CharSet =
CharSet.Auto
         )
      ]
      
public static extern int 
      CoSetProxyBlanket(
         
IntPtr pProxy, 
         
uint dwAuthnSvc, 
         
uint dwAuthzSvc,
         
uint pServerPrincName, 
         
uint dwAuthLevel,
         
uint dwImpLevel, 
         
IntPtr pAuthInfo,
         
uint dwCapabilities
      );

      public static int 
      SetSecurity(
         
object objDCOM
         )
      {
         
IntPtr dispatchInterface = Marshal.GetIDispatchForObject(objDCOM);
         
int hr = CoSetProxyBlanket(
            dispatchInterface,
//pProxy
            
RPC_C_AUTHN_WINNT, //dwAuthnSvc
            
RPC_C_AUTHZ_NONE, //dwAuthzSvc
            
0, //pServerPrincName
            
RPC_C_AUTHN_LEVEL_DEFAULT, //dwAuthnLevel
            
RPC_C_IMP_LEVEL_IMPERSONATE, //dwImpLevel
            
IntPtr.Zero, //pAuthInfo
            
EOAC_NONE //dwCapabilities
         
);
         
return hr;
      }
   }
}

You can compile this code into a DLL by saving it in a .CS file, opening the Visual Studio 2005 Command Prompt and running 'csc /t:library VSWrapperForPSH.cs'.  Once you have done this - you can load this DLL into PowerShell by running '[System.Reflection.Assembly]::LoadFrom(“<<path to DLL>>”)' (note that you need to use the full path to the DLL - if the path is excluded - PowerShell will look in Windows\System32 and complain if the file is not there).

Once you have done all of this - you can now change the COM security level on an object by running '[Microsoft.VirtualServer.Interop.Powershell]::SetSecurity($objectName)'.  And as you can see here - you will then be able to access the object properly:

Virtual Server and PowerShell

However - if you make any new objects (which you will):

Virtual Server and PowerShell

You will get bitten again.  This is simply handled by setting the COM security on objects as you create them:

Virtual Server and PowerShell

Well.  Now that we have all of that working - you can expect to see some posts from me in the near future about how to perform different tasks under PowerShell.  But for now - a couple of final notes to make are:

  1. Under Vista hosts - PowerShell needs to be running 'As Administrator' for this to work (otherwise you will fail to create the first COM object)

  2. I could not have done this without the help of Mike Kolitz and Jon White (from the PowerShell team) - thanks guys!

Cheers,
Ben

Attachment: VSWrapperForPSH.cs
Leave a Comment
  • Please add 1 and 2 and type the answer here:
  • Post
  • > you can expect to see some posts from me in the near future about how to perform different tasks under PowerShell

    Hmm, why don't you give us some ideas that we could try implementing? I'm not familiar enough with Virtual Server to come up with ideas myself.
  • Persone los pioneros non rabata. Great...
  • Do you think there might be some way to roll up 'change files' with online backups using powershell?
  • adsi4nt - sure. It's just scripting.

    Since this is over COM Interop of the VS Admin COM API, you can write the same logic in JScript/VBScript, C/C++, .Net, or PowerShell and then invoke it in any.

    It is your choice where the programming language and logic resides.

    //David
Page 1 of 1 (4 items)