Video Screencast Help

SVS and WMI (Windows Management Instrumentation)

Created: 20 Feb 2008 • Updated: 29 Jul 2010 | 8 comments
Language Translations
Jordan's picture
+1 1 Vote
Login to vote

One of my many roles here at Symantec is testing software compatibility with SVS. In this role, I basically test to see if a program -- virtualized with SVS -- runs as if it was non-virtualized. However, I really don't do GUI-based testing and so if it's a process I can automate via VBscript (using WMI, COM or whatever's available) I prefer to write a script that will do the work for me while I do something else.

Back when the new WMI provider came out for SVS we were supposed to release some official documentation with the SDK (that I don't think ever came out) but you don't need the SDK to use SVS's WMI provider.

There really hasn't been much talk about SVS and WMI on the Juice outside of one tip that suggested using a WMI code generator from Microsoft. This is helpful to a point. There are several tricks to get SVS's WMI provider to work in VBscript that I've learned, and spent way too much time on the MSDN researching workarounds to not share with the community. First off I'm going to cover the actual WMI provider for SVS, listing the classes and methods. Then I'll go into how to use the WMI provider with VBscript.

WMI Documentation

VirtualSoftwarePackage Class

This is your layer class and is where all the standard SVScmd/SVSadmin functions are located the descriptions here are provided by Jeremy who wrote the WMI provider.

Properties

Name

Datatype Description
Id string Layer Id.

This is a GUID.
Name string Layer Name. Writeable.
Active boolean Current active/inactive state of the layer
AutoActivate bool The layer is activated automatically when the system is started. Writeable.
Type uint32 Type of the virtual software package.
0 = Application
1 = Data
CreatedTime datetime When the layer was created.
ActivatedTime datetime When the layer was last activated. May be null if the layer has never been activated.
ResetTime datetime When the layer was last reset. May be null if the layer has never been reset.

Methods

If you're familiar with SVS in any way, these should be self explanatory. If there's a switch for in SVScmd you can do it with WMI.

Import

static uint32 Import(
[in] string Filename,
[in] bool Overwrite,
[out] string PackageId
)

Imports a new layer. Once the import is complete, the layer can be enumerated, and the other (non-static) methods can be called.

Activate

uint32 Activate(
)

Activates a layer.

Activating a layer through SVSAdmin or SVSCmd will result in the current user's desktop being refreshed. Due to security limitations, activating through WMI will not refresh the desktop, nor will it refresh SVSAdmin if it is open.

Deactivate

uint32 Deactivate(
[in] boolean Force,
[out] uint32 ProcessId
)

Deactivates a layer. Optionally, you can force the deactivation if there is a process still running from the layer The same security limitations that apply to activation apply to deactivation.

Reset

uint32 Reset(
[in] boolean Force,
[out] uint32 ProcessId
)

Resets a layer. Similar to SVSAdmin, this call will deactivate the layer if necessary, and thus supports the same parameters as deactivate. The layer will be returned to its state from prior to being reset: e.g., if active prior to being reset, it will be restored to the active state afterward.

SetAutoActivate

uint32 SetAutoActivate(
[in] boolean AutoActivate
)

Sets the value of the AutoActivate property.

Export

uint32 Export(
[in] string Filename,
[in] bool Overwrite
)

Exports the layer to an archive file (.vsa) on the disk.

Delete

uint32 Delete(
)

Deletes the layer. The layer must be deactivated prior to being deleted.

Rename

uint32 Rename(
[in] string Name
)

Renames the layer.

VirtualSofwareSublayer Class

Here's the class for pulling information about each sublayer, the read-only and the read/write layers, there are no methods for this class.

Properties

Name Datatype Description
Id string Layer Id.
This typically takes the form of a GUID.
PackageId string Package Id. This is a foreign key to a VirtualSoftwarePackage class instance. [In the current implementation this is also the same as the Id of the primary (non-peer/read-only) sublayer.]
FileRedirectPath string File system path where the redirect area of the layer is
located.
RegistryRedirectPath string Registry path where the redirect area of the layer is
located.
Type uint32 Type of the layer.
0 = Normal
1 = Peer
2 = Data

Using SVS and WMI

Object Binding

To use all the methods in SVS you'll need to switch between objects you're binding too, which can be annoying at first but are easy to work around. I'll cover each below as well as give some sample subroutines that you can use to do the work for you.

VirtualSoftwarePackage

To access several, but not all, SVS methods you need to bind to \root\default:VirtualSoftwarePackage this will give you access to Import and Export, you'll notice the Restor and Backup impersonation are set, this is because Import and Export require them to function.

To quickly switch just copy and past the following code into your script and then call setWMIForSVS.

SUB setWMIForSVS
  SET objWMIService = GetObject( _
    "winmgmts:{impersonationLevel=impersonate,(Restore, Backup)}!\\" & _
    strComputer & "\root\default:VirtualSoftwarePackage" )
    WScript.Echo "WMI Set to SVS mode"
END SUB

Default

For the rest of the SVS methods you'll need to bind to \root\default, here we have Debug set, you might need this impersonate level if you're trying to deactivate a layer, like Apache, that has a process that's not owned by the user that launched it-it depends on you're set up and it's worth trying without the debug level before running your script with it since setting your level to debug removes many security barriers. It's also worth noting that if you're using the cimv2 object to kill a process in a layer you'll need the same debug impersonation level.

To quickly switch just copy and past the following code into your script and then call setWMIToDefault.

SUB setWMIToDefault
  SET objWMIService = GetObject( _
    "winmgmts:{impersonationLevel=impersonate,(Debug)}!\\" & _
    strComputer & "\root\default" )
    WScript.Echo "WMI Set to default mode"
END SUB

Cimv2

While there are no SVS methods attached to this object you'll probably have to use it in a VBscript so I'm placing it in here for sake of completeness. Note that I do have the Debug impersonate level set which you'll need to have if you try to kill any process you don't own when not using SVS's Deactivate method.

To quickly switch just copy and past the following code into your script and then call setWMIToDefault.

SUB setWMIToCimv2
  Set objWMIService = GetObject( _
  "winmgmts:{impersonationLevel=impersonate,(Debug, Restore,Backup)}!\\" & _
  strComputer & "\root\cimv2" )
    WScript.Echo "WMI Set to cimv2 mode"
END SUB

Sample Functions

I've written up some sample SVS functions that deal with Import, Activate, deactivate to show how those methods are used, these are all intended to be used with ON ERROR RESUME NEXT for error handling.

Activate

'function activate(guid) - Activates a Layer by GUID
'   guid: String --guid of VSA to be activated
'    Returns Success: Boolean
FUNCTION activateSVS(guid)
  SET objItem = objWMIService.Get( "VirtualSoftwarePackage.Id=" & _
    """"& guid &"""" )
  IF Err.Number <> 0 THEN
    activateSVS=false
  ELSE
    WScript.Echo "Activating layer: " & objItem.Name
    x = objItem.Activate()
    IF Err.Number <> 0 THEN
      activateSVS=false
    ELSE
      activateSVS=true
    END IF
  END IF
END FUNCTION

Deactivate

'function deactivate(guid) - deactivates a Layer by GUID
'   guid: String --guid of VSA to be deactivated
'    Returns Success: Boolean
FUNCTION deactivateSVS(guid)
  SET objItem = objWMIService.Get( "VirtualSoftwarePackage.Id=" & _
    """"& guid &"""" )
  IF Err.Number <> 0 THEN
    deactivateSVS=false
  ELSE
    WScript.Echo "Deactivating layer: " & objItem.Name
    x = objItem.Deactivate()
    IF x <> 0 THEN
      WScript.Echo "Error Code: " & x
      deactivateSVS=false
    ELSE
      deactivateSVS=true
    END IF
  END IF
END FUNCTION

Import

'function import (vsa,path) - imports the VSA into SVS
'   vsa: String --Name of VSA to be imported
'  path: String -- path to VSA
'    Returns Success: GUID or False
FUNCTION importSVS(myVSA,myPath)
  WScript.Echo "Importing layer: " & myPath & myVSA
  result = objWMIService.Import( myPath & myVSA , True, packageId )
  WScript.Echo "Importing Finished"
  IF Err.Number <> 0 THEN
    importSVS=false
  ELSE
    importSVS=packageId
  END IF
END FUNCTION

Sample Scripts

These are simple sample scripts that show what you can do with SVS and WMI.

Enumerating Active Layers

strComputer = "." 
SET objWMIService = GetObject( _ 
"winmgmts:{impersonationLevel=impersonate}!\\" & _ 
strComputer & "\root\default" ) 
SET colItems = objWMIService.ExecQuery( _ 
"Select * from VirtualSoftwarePackage Where Active = True" )
FOR EACH objItem IN colItems 
WScript.Echo "Id: " & objItem.Id 
NEXT

Finding Sublayers for a Layer

strComputer = "."
SET objWMIService = GetObject( _
  "winmgmts:{impersonationLevel=impersonate}!\\" & _
  strComputer & "\root\default" )

SET colItems = objWMIService.ExecQuery( _
  "Select * from VirtualSoftwareSublayer " & _
  "Where PackageId = ""guidguid-guid-guid-guid-guidguidguid""" )

FOR EACH objItem IN colItems
  WScript.Echo "Id: " & objItem.Id
NEXT

Conclusion

This article is meant to cover the core of WMI for SVS and give you enough to build the scripts you need to automate SVS processes. If you feel anything was left out of this document or have more specific questions post them in the comments below and I'll try to keep this article updated with any information that I left out.

Comments 8 CommentsJump to latest comment

Jordan's picture

The table for VirtualSoftwarePackage Class had the wrong propriety information, I apologize for this, and I've corrected the information.

I'm also curious if anyone is interested in a second article on SVS and WMI that covers how to use SVS's WMI provider in C#?

If a forum post solves your problem please flag is as the solution

+1
Login to vote
erikw's picture

I really appriciate a article of using the WMI provider in C#. Please

Regards
Erik
www.dvs4sbc.nl

Regards Erik www.DinamiQs.com Dinamiqs is the home of VirtualStorm (www.virtualstorm.org)

*************************************************************
If your issue has been solved, Please mark it as solved
***********

+1
Login to vote
Jordan's picture

Wow did everyone miss this article?
http://juice.altiris.com/article/3677/svs-wmi-and-net

Maybe I need to rename it?

If a forum post solves your problem please flag is as the solution

+1
Login to vote
erikw's picture

It contains the .net code, and for most people it is okay, but i wish to see the c# piece of it.

Regards
Erik
www.dvs4sbc.nl

Regards Erik www.DinamiQs.com Dinamiqs is the home of VirtualStorm (www.virtualstorm.org)

*************************************************************
If your issue has been solved, Please mark it as solved
***********

+1
Login to vote
Jordan's picture

The C# class is a download attached to that article.

If a forum post solves your problem please flag is as the solution

+1
Login to vote
Scot Curry's picture

Unfortunately, it is giving a "the requested page could not be found."

Thanks,
Scot

0
Login to vote
Jordan's picture

https://www-secure.symantec.com/connect/articles/svs-wmi-and-net

If a forum post solves your problem please flag is as the solution

0
Login to vote
keldude's picture

I created a svs-wmi-.net solution several years back with svs 2.1. Now some of my company's computers have been updated to 6.4 and my app no longer works. Any thoughts on compatibilty with 6.4?

 

 

 

ManagementScope pScope = new ManagementScope("\\\\" + sMachineName + \\root\\default,coOptions);

pScope.Connect();

 ManagementPath pPath = new ManagementPath("VirtualSoftwarePackage");

ManagementClass pMgmtObject = new ManagementClass(pScope, pPath, null); **--fails right here, can't find methods --**

 ManagementBaseObject pInParams = pMgmtObject.GetMethodParameters("Import");

pInParams["Filename"] = sFile;

pInParams["Overwrite"] = bOverWrite;

 

ManagementBaseObject pOutParams = pMgmtObject.InvokeMethod("Import", pInParams, null);

0
Login to vote