HOWTO: Remotely start and stop a Virtual Machine on Virtual Server 2005


Here is one of the usual questions about Virtual Server – how to remotely control the Guest VM. Actually, Virtual Server 2005 Administration API is pretty rich and supports these scenarios – you just need to write a little bit of code to do so. Small price to pay for automation.


Question:


I would like to remotley save and turn off my guest OS once a week so I can back up all the files associated.


Is it possible to have the backup server send a command to the Host OS and have it save then turn off the OS do the backup then turn the Guest OS back on?


Answer:


The Virtual Server 2005 Administration API definitely supports this. In general, if you can do it from within the web-browser based Administration interface, you can automate it via script and do everything remotely. The key here is that you must learn a tiny bit of basic scripting and a little bit about how to use Virtual Server.


The documentation is included with the default Virtual Server installation at:



I highly recommend that you look through product documentation to write the necessary automation that you need for your scenario


Now, if you are like 99.99% of the Virtual Server user base, you probably did want to hear me say “it’s possible – just write the code yourself.” Instead, you probably want me to just give you free, functional code. Well, I will get to that… but first, you will have to listen to the explanation because without it, you will not get very far. I will show you enough of the basics to do what you need – if you want to make it useful for your needs, you can take initiative to finish it up. I deliberately left the “do the backup” part up to you to decide – I just show you how to get the filenames of the VHDs that you want to backup.


The Task


This task actually has two separate components:



  1. The ability to have the script act on a remote machine
  2. The script to turn on/off a Virtual Machine by name

Let’s do the easy one first – how to enable remote administration of a Virtual server.


Enabling Remote Administration


Given a default installation of Virtual Server 2005 with some Virtual Machines, to enable remote administration you need to ensure:



  1. Virtual Server DCOM component allows remote instantiation and activation by the remote NT user.

    1. dcomcnfg
    2. Navigate to “Component Services\My Computer\DCOM Config” node
    3. Right click on “Virtual Server” package and select Properties
    4. Select the “Security” tab
    5. Click “Edit” for the “Launch and Activation Permissions” section
    6. Give “Authenticated Users” Remote Activation and Local Activation Permissions
    7. OK out of everything

  2. The ports of the Virtual Server DCOM server is accessible by the remote caller (i.e. Firewall is not blocking).

    1. If the Host is running Windows Server 2003 SP1 or Windows XP SP2 the Windows Firewall may be already running. Or you may have some other Firewall running. In any case, you want to make sure that there is no firewall blocking access between your remote client and the Virtual Server
    2. If using Windows Firewall, you can run the following NETSH command to make sure Virtual Server DCOM server is accessible through the Windows firewall.
      NETSH.EXE Firewall set AllowedProgram “%ProgramFiles%\Microsoft Virtual Server\vssrvc.exe” VS2005 Enable

  3. The remote caller also has Virtual Server Core Component installed so that they can originate the DCOM call
  4. The NT user making the DCOM call is allowed access to both the Virtual Server DCOM component (what we did in step #1) AND has Execute permission in Virtual Server security (only Administrators have this right by default).

You can configure Virtual Server security by:



  1. Navigating from the homepage of the VS Administration Website and choosing “Server Properties”.
  2. Then selecting “Virtual Server security”.
  3. Finally Adding an entry to allow the NT user at least the “Control” permission (which gives that user access to the VS Admin API) and probably also the “Modify” and “Read” properties.

JScript Code to turn On/Off a Virtual Machine


Assuming that you have Remote administration enabled, the following JScript code should be able to run on the remote computer as the NT user with privileges to both remotely activate and access the VS Admin API and remotely contact the DCOM Server of Virtual Server to start/stop a virtual machine.


You are going to want to also read the following blog entry for the “WaitForTask” script routine useful for managing and waiting for various Virtual Machine operations to “finish”.


//David

//
// Remote Start/Stop a Virtual Machine
//
var CRLF = “\r\n”;
var VM_STATE_OFF = 1;
var VM_STATE_RUNNING = 5;

var strServer = “VS Server”
var strVMName = “Guest VM Name”

var objVS = new ActiveXObject( “VirtualServer.Application”, strServer );
var objVM = objVS.FindVirtualMachine( strVMName );
var objTask;
var enumHardDiskConnection;
var objHardDiskConnection;
var objHardDisk;
var strFileToCopyFrom;

//
// If the Virtual Machine was found
//
if ( objVM != null )
{
WScript.Echo( “Found Virtual Machine named: ” + strVMName );

//
// Only attempt to wait for graceful shutdown of a running VM
//
// This requires VM Additions to be installed in the Guest.
//
// I have seen it not work on occassions and the VM is just
// “hanging” and never shuts down.
//
if ( objVM.State == VM_STATE_RUNNING )
{
try
{
WScript.Echo( “Gracefully shutting down VM…” );
task = objVM.GuestOS.Shutdown();
WaitForTask( task );
}
catch ( e )
{
//
// Failed graceful shutdown. Just turn the power off on
// the Guest VM
//
WScript.Echo( “Forcefully shutting down VM…” );
task = objVM.TurnOff();
WaitForTask( task );
}
}

//
// Run your backup operation on the VHDs
//
enumHardDiskConnection = new Enumerator( objVM.HardDiskConnections );
for ( ;
!enumHardDiskConnection.atEnd();
enumHardDiskConnection.moveNext() )
{
objHardDiskConnection = enumHardDiskConnection.item();
objHardDisk = objHardDiskConnection.HardDisk;
strFileToCopyFrom = objHardDisk.File;

WScript.Echo( “Source VHD (relative to ” + strServer + “): ” + CRLF +
strFileToCopyFrom );
}

//
// Only attempt to start up the turned-off VM
//
if ( objVM.State == VM_STATE_OFF )
{
WScript.Echo( “Starting up VM…” );
objTask = objVM.StartUp();
WaitForTask( objTask );
}
}
else
{
WScript.Echo( “Did not find Virtual Machine named: ” + strVMName );
}

Comments (31)

  1. Joshua Morgan says:

    This is Awesome…. Does this process save the state of the running Guest OS prior to the shutdown?

  2. David Wang says:

    Joshua – Nope, this script turns off the Guest OS to do a backup, first by using Graceful Shutdown and if that fails, turn off the Guest OS. Then, run some command to backup the VHD(s) of the specified Virtual Machine, and then turn it back on.

    It is closer to taking an image snapshot of the Virtual Machine than a running backup. If you want a running backup, run a backup agent inside the Guest OS.

    Procedures are a little different if you want to capture "running state". Just a few more files to copy, but the info is all there in the VS2005 COM Admin API. It won’t take long to revise this script.

    //David

  3. Joshua Morgan says:

    Again, thanks so much for your response….

    I guess I misunderstood the Microsoft technet stuff. If I am understanding what you are saying a "Shutdown" OS is saved vs. the memory resident portions of the running OS.

    If this is true then backing up the files should not be a problem.

    Question then is moving the files from one virtual machine to another that big of an issue, assuming you fix the NIC issues that may arrive?

  4. Joshua Morgan says:

    David,

    I want to make sure I am not missing something … Is the script you put up in VB or some other language? I Copied and pasted it into a .vbs File and I get an error on Run.

    Knowing me I’m just doingsomething wrong, I’m a little light when it comes to scripting abilities…

  5. David Wang says:

    Joshua – oops, I never mentioned that my code sample is in JScript. I just corrected the blog entry.

    You want to copy the content into a .js file to run it.

    //David

  6. Joshua Morgan says:

    Ok so this script works Great on a Machine with Virtual Server installed…. Is there a way to run it without VS installed ? Ideally I would like to run the script from my backup server and it does not have VS installed fro performance and licensing reasons….

  7. David Wang says:

    Joshua Morgan – Well, the script depends on the Virtual Server COM API working on the machine that it is run on. So, you should work on figuring that out…

    //David

  8. Joshua Morgan says:

    Sorry about he last Post…. When I installed VS I totaly missed the Custom Option.

    Thanks for all your help.

  9. Scott Lenninger says:

    I have something like this working on my VS. The problem I am having is after the script has run the option to shutdown guest OS doesn’t reappear in the dropdown list for turning on and off the VM until after I reboot agian. Do you know of any fix for this.

  10. David Wang says:

    Scott – Ability to Shutdown is dependent on the GuestOS having VM Additions installed and running.

    I have never had problems invoking Shutdown on a Guest OS when it is in a state that allows it. Thus, functionality-wise, it all looks good to me.

    I have not confirmed your observations, but if true, it sounds like a UI bug. My guess is that if it is not fixed in VS2005 R2 then it probably will never be fixed.

    //David

  11. damir says:

    I have implemented some program in .net20, which can do many thins supported by the COM-API. All works mostly fine. However, sometimes, when the program tries to shutdown the remote machine, the machine just popup following message:

    "if you shut down this remote computer, no one can use it until someone at the remote location manually restarts it. DO you want ot continue shutting down ?"

    After this message-box appears, the administrator has to confirm to proceed with the shutdown.

    Question: How to enforce silent shut-down?

  12. David Wang says:

    damir – Are you saying that Virtual Server is popping up the confirmation dialog in the Host when you attempt GuestOS.Shutdown(), or something inside the GuestOS Virtual Machine is popping up a dialog?

    I have never seen such a dialog from Virtual Server, so I suspect the latter is happening — something is popping up the confirmation dialog from within the GuestOS of the Virtual Machine — in which case the issue is NOT "how to enforce silent shutdown" because it has nothing to do with Virtual Server at all — it would happen if you tried to shutdown a real physical machine.

    Now, I believe that I have seen the dialog you are talking about, and it has nothing to do with Virtual Server. When you Remote Desktop into some other Windows Server, and then you try to select shutdown from within the Remote Desktop, Windows will warn you about this since that remote server *will* need to be manually restarted before you can Remote Desktop into it again. Seems like a reasonable confirmation to me…

    Unfortunately, I do not know how to disable that confirmation within Remote Desktop.

    //David

  13. wil4pres says:

    Does anyone know how to run or start a virtual lab like microsofts virtual labs. Or demo labs like adobe?

  14. khurram says:

    Please guide me how can i start/restart the vmware? I can use the same script for this.

  15. Tony Hinkle says:

    Regarding damir’s "if you shut down this remote computer, no one can use it until someone at the remote location manually restarts it. DO you want ot continue shutting down ?" message, this is a message that Terminal Services displays in Windows 2003 when the machine is shut down via a TS session.  I have seen the same issue, so I just ended up using automation to pause and save virtual servers.  If I really want to shut them down I do it manually.

    Having this brought to mind again, though, I wonder if there is a method to end all TS sessions.  If that can be done, then the solution to this problem is to do that and then shut down.

    BTW, this same problem occurs with the VS web management–I just tested it.  

    To reproduce:

    1. Create a Remote Desktop session to a guest OS, log in as Administrator.

    2. Close the RD window (i.e., disconnect, don’t log off).

    3. Attempt to shut down the guest OS with the VS admin website or the COM object.

    4. Note that the server does not shut down.

    5. Use the VS remote control thingy to access the server–unlock the system and you’ll see the message.

    David, I’ll assume that you will make sure this is on the map for things to think about addressing.  If not, please let me know.  My email address is first.last@doubletake.com.

    Cheers!

  16. Tony Hinkle says:

    David,

    I didn’t read the third paragraph of your reply to damir before I wrote mine–sorry for repeating you somewhat.  Anyway, I agree that this dialog seems reasonable, but it is also annoying if it can’t be disabled, and breaks the VS admin tool (the OS doesn’t shut down when you tell it to, and there is no message indicating that the action you took failed).  Accordingly, VS should warn the user with an event at the very least (this would just be CYA, but not much real help).  Ideally, it would prompt the user with a yes/no whether to force the shutdown.

    Thanks for listening.  VS is definitely a cool, useful, and fun tool.

    I hope that my little bit of input can help make it better.

  17. Bryan says:

    Forgive my simple question here, I have copied the script above and named it script.js.  I have edited what I believe needs to be customized for my Virtual Configuration so-to-speak (i.e. var SetServer and var SerVMName).

    I run the cscript script.js command and am getting the following output:

    script.js(50, 13) Microsoft JScript runtime error: Object expected

    If I understand correctly, this script will attempt to gracefully shut down the guest OS and then wait for you to perform some time of backup or copy to the VHD file, then attempt to start the guest OS up again, correct?

    What modifications do I need to make to the script in order for it to work?  I have a 2003 Ent. Server running 4 Virtual Servers that need to be included in a backup strategy.  One of the things we are doing is trying to get the vhd file in order to restore to in the event of a disaster.  Any help would be appreciated.  Greater details can be provided on the architecture if needed via email or post.  Thanks.

    -Bryan

  18. David.Wang says:

    Bryan – I think you need to re-read my instructions under "JScript Code to turn On/Off a Virtual Machine" and copy the code for "WaitForTask()", which I provided the link for.

    This is just sample code that provides you information on how to do the Virtual Server side of things. You still need to do your part…

    This script shows how to:

    1. shutdown the Guest OS

    2. Obtain the full filename of the VHDs of the Virtual Machine (so that you can write code to do whatever you want with that file, such as copy it)

    3. start up the Guest OS

    It *can* wait for the backup operation to happen before restarting the GuestOS, but you will have to write two lines of code to make that happen.

    //David

  19. Rick Daniluk says:

    David – Regarding Damir’s problem and Tony’s additions to the neat little 2003 warning, I had the same issue, here is a possible solution.

    Although your code is quite eloquent, and very necessary for turning on a VM, I went super simple.  This assumes that you have network access to the VM, I believe in these applications (i.e. backup of the VHD) that is a requirement anyway.  

    Issue a "shutdown /s /m \computername".  I do believe the Guest OS and VM Addisions are actually using the same call when your code is used.  The /f switch can also be useful.  However, the /r switch does not work.

    The shutdown will occur regardless, even if the console in VMRC is at the warning prompt already.

    One other issue can be security, the machine/user issuing the command will have to have permission to shutdown the VM.  In a Domain not a big issue, but across non trusted, or no Domain, a little more work.

    Is this usable, or am I missing something here?

    Rick

  20. David.Wang says:

    Rick – yes, your approach is usable, but just be careful of the requirements:

    – To "backup the VHD", it should only require network access between the Host and some other backup device.

    – To use shutdown remotely, it requires network access between the Host and Guest.

    Those two requirements are not necessarily the same.

    So, while I do agree that your approach to shutdown is super simple, it also introduces a new requirement.

    The ideal solution from a requirements perspective is for a LocalSystem service to run via VMAdditions inside the Guest and it executes commands from the Host – i.e. the IVMGuestOS.ExecuteCommand() API call – but unfortunately, that was deemed a security vulnerability and removed from the Virtual Server Administration API. I was very sad when that happened.

    //David

  21. Rick Daniluk says:

    David – They don’t always take a pole before they do some of those things do they…

    On our machines which have to contain data due to requirements of apps, we run CA Backup Agent and backup nightly.  

    But for the VM itself, shutdown, backup VHD, and start (via David code) seems easier than doing a full system backup online  Because then in a recovery you have to install an OS, an agent, then restore, and not always with success.

    I admit to lazy when able.

    Rick

  22. David Wang says:

    The following are some of the more frequently asked questions when it comes to deploying a group Virtual…

  23. Vik says:

    David:

    How can I automatically restart the virtual servers after host OS restarts?

    Thanks

  24. Alexander Sebestian says:

    Hi all together!

    What a great page!

    I found nearly every post very helpful.

    But I’m missing a very necesserry question.

    The Backup Routine via Script is great. But in desaster case you will have  a problem to restore a Active Directory Domain Controller with this routine, don’t ya?

    I’m actually planning a VS Environment with 200 physical Servers, on each Server I will run an additional  Virtual Server in Active Directory Domain Controller Mode and will have to backup this VM easily and need to recover this VM without destroying the whole AD.

    Any idea?

    Post’s will be great.

  25. Victor Mier says:

    Does anyone have a full script that will successfully shutdown multiple virtual servers on a host one by one, xcopy the files to a different server (standby Virtual Server), and restart the virtual servers once each one by one xcopy is completed?

  26. Bony Lim says:

    Hi David,

    I programmed windows service to monitor the state of the Virtual Server (running or stop) in .net 2.0.

    But then try to accessing the Virtual Server COM library from the Windows service in a remote computer it produce this error:

    System.UnauthorizedAccessException: Retrieving the COM class factory for remote component with CLSID {DA3111BC-1BD7-4884-A535-8470D36028F7} from machine TSYDWNASXX failed due to the following error: 80070005.

    It works fine when I am testing it using windows form. The service is installed using installutil.exe as a "local system"

    Do you know what’s wrong with it? Do I need to impersonate a user before calling the Virtual Server COM from windows services?

    Thank’s for your help.

    Bony Lim

  27. Ameya says:

    Hi David,

    Your post on Virtual Server 2005 were very useful. I have one question regarding use of VMHostOS.ExecuteCommand() method. Is there any way where we implement it’s interface or inherit that above class to make this method work ?

    Thanks,

    Ameya

  28. David.Wang says:

    Bony Lim – You are correct. "Local System" has no permissions on a remote computer. You will either have to impersonate, or lower security on Virtual Server’s COM+ configuration.

    //David

  29. David.Wang says:

    Ameya – not really. You will have to reimplement the same hack that was disabled to have that functionality.

    Personally, I like to assume the OS is modern Windows and running as Administrator and use standard keystrokes to "execute" a programmatic command.

    Windows-R <command> <enter>

    //David

  30. Toby says:

    Wonderful post!  Exactly what I was looking for.  Thanks much for your expertise and taking the time to help the community with automating Microsoft VM backups!

  31. Jyotirmoy Dutta says:

    Hi,

    I am looking out for a simple script which will monitor the IIS service, and if it goes down it will send an alert to the mail server.

    Thanks a lot.