So COM is a huge topic that I can’t even imagine scratching the surface of in a single post; MSDN and CodeProject are two great places to learn about COM though. Note also that in many ways, COM has been replaced by .Net so you won’t even see many people using it anymore, but it still exists and won’t be going anywhere anytime soon.

Microsoft.SMS.TSEnvironment is the COM object used by Operating System Deployment in ConfigMgr 2007 to expose task sequence variables. It is only available during a task sequence and is typically easy to access using built-in task sequence tasks and conditions or automation aware scripting languages like VBScript.

For more “robust” development, accessing this object from a more traditional development platform, like Visual C++, is often desirable. Access from various languages was almost the entire motivation for building COM into Windows in the first place so this is perfectly supported and doable; however, automation aware languages typically hide all of the many details of accessing COM objects and thus make it very simple to use them — this is not the case with Visual C++. Usually, the simplification that accompanies VBScript comes at the cost of flexibility and power and always at the expense of speed.

Microsoft didn’t provide any specific documentation on using this COM object anywhere except in automation/COM friendly tools like VBScript so here’s my quick start guide.

Because COM has a lot of “overhead” from the developer’s perspective, a lot of engineering and work has gone into Visual C++ to help streamline some of this. Smart Pointers are one of these enhancements: they point to a COM object and control reference counting and automatic clean-up among other things. There are various ways to implement these, but the simplest is to use the Visual C++ #import directive to create the smart pointer classes for us (

– Use #import to tell the Visual C++ preprocessor to create header files and smart pointer based classes from a type library (or DLL in this case) that you can then easily use in code. The DLL to use is TSCore.dll as this DLL contains the implementation of Microsoft.SMS.TSEnvironment; it can be found in any boot image.

#import "TSCore.dll" named_guids

– Add a using directive to transparently use the proper namespace; the classes created above by the #import directive will be contained in the namespace TSEnvironmentLib.

using namespace TSEnvironmentLib;

– Initialize COM


Note that Microsoft.SMS.TSEnvironment is actually the ProgID of the COM object; a ProgID is a friendly name for a COM Object. The actual class name is ITSEnvClass:

– Create an object of the smart pointer class ITSEnvClassPtr which is created by the import directive; this class will “contain” the smart pointer to the COM object which is of type ITSEnvClass.

ITSEnvClassPtr tsEnv;

– Create an instance of the Microsoft.SMS.TSEnvironment COM object by initializing our class with the CLSID; the CLSID is contained in a static variable created by the import directive

tsEnv.CreateInstance (CLSID_TSEnvClass);

– Now use tsEnv to call the methods defined for the COM object, specifically GetValue and PutValue. The extra complication here is that COM objects do not by convention use C strings because of marshaling and compatibility issues and instead use basic/binary strings; aka BStrings.

_bstr_t b = tsEnv->GetValue (_T ("_SMSTSLogPath"));

– Don’t forget to uninitialize COM when you are done; smart pointers will clean themselves up as well as take care of reference counting (which are huge advantages when working with COM)


If that all seems really complex, it is. That’s one reason COM is (sort of) going away. Once you understand what’s going on, it’s not a huge deal, but there are a lot of moving parts involved and thus the complexity. VBScript (and other automation aware languages) do everything above for you without exposing you to the details.

No Comments