Tuesday, August 15, 2006

SMS Scripting - Introduction

SMS is a highly customizable system, you will quickly find out that the interface provided through the SMS Administrator Console is just the beginning. By extending SMS through custom scripts you will give yourself greater flexibility and find yourself spending less time doing repetitive task and more time managing your infrastructure. WMI provides the entry point to the SMS server, you can write scripts and applications using any language that supports WMI. However, we will focus on VBScript here because the Windows Script Host (WSH) is readily avaiable on all Windows systems and it is a fairly flexible language for creating WMI scripts. If you are not familiar with VBScript you can refer to the VBScript User's Guide from Microsoft. You also may want to check out the book Microsoft Windows Scripting Self-Paced Learning Guide (ISBN - 0735619816). In order to write effective SMS scripts you should feel comfortable writing basic scripts, and you should familiarize yourself with basic object-oriented programming concepts. Having prior working knowledge with WMI scripting will also decrease your learning curve significantly.

The SMS Provider is a WMI provider that serves as the gateway to all administrative functions of the SMS server. In fact the SMS Administrator Console uses the SMS Provider for all the functionality that it provides. Understanding how WMI works and the ways it integrates with SMS is crucial in developing scripts or applications that manipulate SMS.

Connecting to the SMS Provider


Below is a simple script that establishes a connection with the SMS Provider of your local site server.

Dim oSWbemLocator
Dim oSWbemServices
Dim oProviderLocSet
Dim oLocation

' Connect to the server's SMS Provider
Set oSWbemLocator = CreateObject("WBemScripting.SWbemLocator")
Set oSWbemServices = oSWbemLocator.ConnectServer("sms_server", "root\sms")

' Get Provider Locations
Set oProviderLocSet = oSWbemServices.InstancesOf("SMS_ProviderLocation")

' Process SMS Locations
For Each oLocation In oProviderLocSet
If oLocation.ProviderForLocalSite = True Then
Set oSWbemServices = oSWbemLocator.ConnectServer(oLocation.Machine, _
oLocation.Machine, "root\sms\site_" + oLocation.SiteCode)
Exit For
End If
Next

Lets take a look at how each piece of the above script works.

The first four lines of the script define the variables that we will use, VBScript does not require you to define variables. However it is a best practice to do so, and also use the Option Explicit setting in all your scripts which forces variable declaration.

After we define our variables we use VBScript's Set Statement to set the oSWbemLocator variable to be an instance of the WBemScripting.SWbemLocator object. Good practice is to prepend your variables with a string indicating the type of the variable. I use 'o' for object, 's' for string, 'a' for array etc... The CreateObject function creates an instance of the object class provided and returns a reference to it. The SWbemLocator object provides methods that allow us to connect to a WMI namespace on a remote or local host.

The next statement performs the actual connection to SMS Server. ConnectServer will accept many optional arguments which are detailed here. The two arguments that we utilize in this script are the server name and the WMI namespace. Both of these arguments are optional, if you do not provide the servername the local host will be used and if you do not provide the namespace the default wmi namespace "root\default" will be used. Here we specify a fictious SMS server "sms_server" and the SMS WMI namespace which is "root\sms".

Note: ConnectServer will fail if you do not have the appropriate security permissions on the server. The account you are running the script as must have access to WMI services on the server, or you must specify alternative credentials as documented in the WMI SDK documentation.

Once we have a valid connection to the SMS server we want to establish a connection with the local site server. This is done by first retriving an object set of SMS provider locations by calling:

Set oProviderLocSet = oSWbemServices.InstancesOf("SMS_ProviderLocation")

After we retrieve the set of providers we loop through each one until we find the provider for our local site. We then call ConnectServer once again and now we have established a connection to an SMS Provider on our local site server!

Executing a WMI Query

Well connecting to the SMS server sounds great and all, we really haven't done anything yet. Let's add a little to this script to query the SMS Provider for some basic information on collections.

We'll append our code above with the following:

Dim oCollectionSet
Dim oCollection

' Execute WMI Query
Set oCollectionSet = oSWbemServices.ExecQuery("SELECT * FROM SMS_Collection")

' Loop through results and output collection information
For Each oCollection In oCollectionSet
WScript.Echo oCollection.CollectionID & " - " & oCollection.Name
Next

This additional script will execute a WMI query and output a list of all Collection ID and Names from the SMS database.

Note: If you run this script by double-clicking on the file in windows you will receive a long series of popup boxes. It is recommended that you run this from the command line using cscript.exe scriptname.vbs. You may also want to set cscript as your default script host over wscript. You can do this by executing: cscript //h:cscript.

Let's take a look at how the above script works.

First we call the ExecQuery method of the WMI services object. This method executes a WMI query and returns a reference to a object set that contains the results. We will cover WMI queries in detail later on, but for starters this query simply retreives all resources that are contained within SMS_Collection.

After we retrieve the results we process each one individually using a For..Each loop similar to how we looped through the providers earlier. For each collection we execute WScript.Echo to output the Collection ID and and Collection Name. Notice we reference these properties by using the object reference oCollection followed by a . and then the member name. For a listing of all members of the SMS_Collection see the following document in the SMS 2003 SDK.

We now have a basic working script that connects to an SMS server and retreives some information. This is just a starting point and we will be covering SMS scripting in much more depth. We covered a lot of information in a short article and breezed over a lot of the basics of scripting. Brush up on your VBScript and WMI knowledge and next time we'll dig much deeper into the world of SMS scripting.

2 Comments:

Anonymous Anonymous said...

Please do something with this site!

You can't copy paste the code without having all linies on the same same !!

The code is filled with errors as the untrained eye will NEVER find!

Please make this better..

2:40 AM  
Anonymous Anonymous said...

Um, if you knew what you were doing you'd cut paste the code into wordpad, not notepad...

Try that!

Thanks for a GREAT site!!!!!

7:48 PM  

Post a Comment

<< Home