How to automate SCCM administration

(From Susana Guedes (Microsoft) Blog and myself )

SCCM and SDK kit

The Microsoft System Center Configuration Manager 2007* (SCCM) has an Software Development Kit (SDK) that allows you to build plug-ins for the SCCM Management Console, to build automation scripts for batch processing, and to manipulate Configuration Manager 2007 client settings.
In this post I will explain how to create a VB Script to automate the following tasks**:
  • Create a software distribution package (including corresponding programs)
  • Add the package to every distribution point
  • Advertise one of the package programs to a specific collection
  • Generate Program and remote flag

Preparing the environment

The environment must have SCCM and corresponding SDK installed. You can download the SCCM SDK version 4.0 on the following link: System Center Configuration Manager 2007 Software Development Kit (SDK) v4.0 (http://www.microsoft.com/downloads/details.aspx?FamilyId=064A995F-EF13-4200-81AD-E3AF6218EDCC&displaylang=en). Create a new file with a .vbs file extension to make the VBScript code. The scripts will use WMI classes provided by the SCCM SDK to manipulate SCCM. In order for you to inspect those classes and even see the SCCM database data relative to those classes, you can use the a WMI explorer tool, I have used a PowerShell GUI named Wmi Explorer made by Marc van Orsouw (http://thepowershellguy.com/blogs/posh/archive/2007/03/22/powershell-wmi-explorer-part-1.aspx).
 
At this point we are ready to start scripting.
Let's move on to the first task "Create a software distribution package (including corresponding programs)" 

Connect to provider namespace for local computer

The WMI namespace for SCCM is root\sms. Inside root\sms you will have a different namespace for each SCCM site you have, in the format root\sms\site_<sitecode>. Beside them, other namespaces may also exist, like, for instance, root\sms\inv_schema. Before you can do any operation, you must first connect to the WMI namespace root\sms\site_<sitecode> where the <sitecode> corresponds to the SCCM site code to which you want to add the package. SWbemLocator object is used to establish an authenticated connection to a WMI namespace and can be understood as the top object on the WMI scripting library.
 
The following code connects to root\sms, iterates through all its sites to locate the local site, and connects to it. You can also connect to a remote site (see How to Connect to an SMS Provider in Usefull Links). For future use, a reference to the Site object will be kept.
 
'Connect to provider namespace for local computer.
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices= objSWbemLocator.ConnectServer(".", "root\sms")
Set ProviderLoc = objSWbemServices.InstancesOf("SMS_ProviderLocation")
 
For Each Location In ProviderLoc
        If Location.ProviderForLocalSite = True Then     
            Set objSWbemServices = objSWbemLocator.ConnectServer _
                 (Location.Machine, "root\sms\site_" + Location.SiteCode)
            Set Site = objSWbemServices.Get("SMS_Site='" & Location.SiteCode  & "'")
         End If
Next
 
 

Create the software distribution package

Once you have a connection to SCCM Site, you can create a new package. The package is an object of the SMS_Package class which you can inspect with WMI Explorer. Using that tool you will find the following properties of an SMS_Package: ActionInProgress, AlternateContentProviders, Description, ExtendedData, ExtendedDataSize, ForcedDisconnectDelay, ForcedDisconnectEnabled,  ForcedDisconnectNumRetries, Icon, IconSize, IgnoreAddressSchedule, ISVData, ISVDataSize, Language, LastRefreshTime, Manufacturer, MIFFilename, MIFName, MIFPublisher, MIFVersion, Name, PackageID, PackageType, PkgFlags, PkgSourceFlag, PkgSourcePath, PreferredAddressType, Priority, RefreshPkgSourceFlag, RefreshSchedule, ShareName, ShareType, SourceDate, SourceSite, SourceVersion, StoredPkgPath, StoredPkgVersion, Version.
 
The following code creates a new package, configures some of the package properties, saves changes using the Put method and, lastly, gets the package ID automatically generated from the put method. The package ID will identify the new package latter on the script.
'Create package.
Set newPackage = objSWbemServices.Get("SMS_Package").SpawnInstance_()
 
'Configure package properties
newPackage.Name = "Adventure Works Cycles Sample"
newPackage.Description = "Dinamically generated using VBS"
newPackage.Version="2.0"
newPackage.Manufacturer="Microsoft"
newPackage.Language="ALL"
newPackage.PkgSourceFlag = 2 
newPackage.PkgSourcePath = "C:\Softwares\StoreCSVS v2"
 
'Save changes
Path=newPackage.Put_
wscript.echo "Created package " +PackageName
 
'Get the automatically assigned package ID for future use.
Set Package=objSWbemServices.Get(Path)
PackageID= Package.PackageID

Create the package programs

Now you can create the package programs and associate them with the already created package. A program is an object of the class SMS_Program which you can also inspect using WmiExplorer. SMS_Program from sdk version 4.0 has the following properties: ActionInProgress, ApplicationHierarchy, CommandLine, Comment, DependentProgram, Description, DeviceFlags, DiskSpaceReq, DriveLetter, Duration, ExtendedData, ExtendedDataSize, Icon, IconSize, ISVData, ISVDataSize, MSIFilePath, MSIProductID, PackageID, ProgramFlags, ProgramName, RemovalKey, Requirements, SupportedOperatingSystems, WorkingDirectory.
  
The following code creates two new programs, one for install and one for uninstall, configures some of their properties, and saves changes using the Put method and. Note that one of the properties of the program is the package ID of the package to which it bellongs,, is this property that creates a relation between the already created package and the new program.
'Create de install program, and configure some of the properties
Set newProgram = objSWbemServices.Get("SMS_Program").SpawnInstance_()
newProgram.ProgramName = InstallProgramName
newProgram.PackageID = PackageID
newProgram.Comment = "Dinamically generated using VBS"
newProgram.CommandLine = "msiexec /qn /quiet /i AdventureWorksCycles.msi"
 
'Save the install program
newProgram.Put_
wscript.echo "Created program " +InstallProgramName
 
'Create the unistall program, and configure some of the properties
Set newProgram = objSWbemServices.Get("SMS_Program").SpawnInstance_()
newProgram.ProgramName = UninstallProgramName
newProgram.PackageID = PackageID
newProgram.Comment = "Dinamically generated using VBS"
newProgram.CommandLine = "msiexec /qn /quiet /uninstall AdventureWorksCycles.msi"
 
'Save the uninstall program
newProgram.Put_
wscript.echo "Created program " +UninstallProgramName
At this point we have completed the first task "Create a software distribution package (including corresponding programs)".
Let's move on to the task "Add the package to every distribution point ". 

Add the package to every distribution point available

Once created, the package is ready to be added to distribution points. You can add the package to specific distribution points, but in this example we will show you how to add it to every distribution point available on the current site, to show you how to query the SCCM database to get the distribution points list. A distributoin point is an object of the class SMS_DistributionPoint, which describes a location (NALPath - Network Access Location Path) where package source files are distributed to clients. A distribution point is allways associated with a given package, and a package can have several distribution points. The SMS_DistributionPoint class has the following properties: BitsEnabled, IsPeerDP, IsProtected, ISVData, ISVDataSize, LastRefreshTime, PackageID, RefreshNow, ResourceType, ServerNALPath, SiteCode, SiteName, SourceSite, Status.
 
The following code queries the SCCM database to get a list of all distribution points, they are stored on the SMS_SystemResourceList table with the role name "SMS Distribution Point". For each distribution point resource found, a new instance of SMS_DistributionPoint is created, configured, and saved. 
Comment by Neven Radic; This code will add packages to all site DPs , not to every DP in environment if SCCM SDK isn't installed on the server.

Set AllDPs = objSWbemServices.ExecQuery("Select * From SMS_SystemResourceList WHERE RoleName='SMS Distribution Point' AND SiteCode='" & Site.SiteCode & "'")
For Each DP In AllDPs
    Set newDP = objSWbemServices.Get("SMS_DistributionPoint").SpawnInstance_()
    newDP.ServerNALPath = DP.NALPath
    newDP.PackageID = PackageID
    newDP.SiteCode = Site.SiteCode
    newDP.SiteName = Site.SiteName
    newDP.Put_
Next
At this point we have completed the second task "Add the package to every distribution point ".
Let's move on to the task "Advertise one of the package programs to a specific collection". 

Advertise the Install Program to a specific collection

In this task we will advertise the Install program to the collection named "All Business Application Servers". A collection is an object of the class SMS_Collection and contains the following properties: CollectionID, CollectionRules, CollectionVariablesCount, Comment, CurrentStatus, LastChangeTime, LastMemberChangeTime, LastRefreshTime, MemberClassName, Name, OwnedByThisSite, RefreshSchedule, RefreshType, ReplicateToSubSites, ServiceWindowsCount. An advertisement is an object of the class SMS_Advertisement and has the following properties: ActionInProgress, AdvertFlags, AdvertisementID,  AdvertisementName, AssignedSchedule, AssignedScheduleEnabled, AssignedScheduleIsGMT, AssignementID, CollectionID, Comment, DeviceFlags, ExpirationTime, ExpirationTimeEnabled, ExpirationTimeIsGMT, HierarchyPath, IncludeSubCollection, ISVData, ISVDataSize, MandatoryCountdown, PackageID, PresentTime, PresentTimeEnabled, PresentTimeIsGMT, Priority, ProgramName, RemoteClientFlags, SourceSite, TimeFlags.
 
The following code queries the SCCM database to find all the collections and iterates the received list to find the specified collection. If the collection was found, a new advertisement is created, configured and then saved.
'Step Configuration
AdName  = "Adventure Works Cycles 2.0 Advertisement"
CollectionName = "All Business Application Servers"
 
'Get all collections, and search for the desired one by name
Set colCollections = objSWbemServices.ExecQuery("Select * From SMS_Collection")
For Each objCollection In colCollections
    If objCollection.Name=CollectionName Then
        CollectionFound=True
        CollectionID=objCollection.CollectionID
   End If
Next
 
If (CollectionFound) Then
    
    'Create new advertisement, and configure some properties
    Set newAdvertisement = objSWbemServices.Get("SMS_Advertisement").SpawnInstance_()
    newAdvertisement.AdvertisementName = AdName
    newAdvertisement.comment = "Dynamically created using VBS"       
    newAdvertisement.CollectionID = CollectionID
    newAdvertisement.PackageID = PackageID
    newAdvertisement.ProgramName = InstallProgramName
    newAdvertisement.PresentTime=datetime
    newAdvertisement.ExpirationTime= expdatetime
    newAdvertisement.AdvertFlags=32
    newAdvertisement.Priority=1
   
    'Save advertisement
    newAdvertisement.Put_
 
End If
 
 How to set program platforms

You have to define the instOSDetails variable as an array as I did at the top. I have a 1 defined for the array indicating that there are 2
values (0 and 1). You have to then use a different ProgramFlag to select "This program can run only on specified client platforms" on the
Requirements tab. If you don't select this then it will ignore any selection in the list of OS's. Then of course you do a Put_ on the program
to save it.
 
Dim instOSDetails(1)
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator") 

Set objSWbemServices= objSWbemLocator.ConnectServer _ 
(".", "root\sms") 

Set ProviderLoc = _ 
objSWbemServices.InstancesOf("SMS_ProviderLocation") 

For Each Location In ProviderLoc 
If Location.ProviderForLocalSite = True Then 
Set objSWbemServices = objSWbemLocator.ConnectServer _ 
(Location.Machine, "root\sms\site_" + Location.SiteCode) 
End If 
Next 

'create package 

Set newPackage = objSWbemServices.Get("SMS_Package").SpawnInstance_() 
newPackage.Name = "Test for OS" 
newPackage.Description = "created by script" 
newPackage.PkgSourceFlag = 2 
newPackage.PkgSourcePath = "C:\temp" 
Path=newPackage.Put_ 

Set Package=objSWbemServices.Get(Path) 
PackageID = Package.PackageID 

'The values for the SMS_OS_Details instances come from 
SMS_SupportedPlatforms 
set instOSDetails(0) = objSWbemServices.Get("SMS_OS_Details").SpawnInstance_ 
instOSDetails(0).MaxVersion = "5.00.9999.9999" '9999 signifies all 
instOSDetails(0).MinVersion = "5.00.0000.0" 'versions of Windows 2000 
instOSDetails(0).Name = "Win NT" 
instOSDetails(0).Platform = "I386" 

set instOSDetails(1) = objSWbemServices.Get("SMS_OS_Details").SpawnInstance_ 
instOSDetails(1).MaxVersion = "4.00.9999.9999" 
instOSDetails(1).MinVersion = "4.00.0000.0" 
instOSDetails(1).Name = "Win NT" 
instOSDetails(1).Platform = "I386" 

' Create install program 
Set objNewProgram = objSWbemServices.Get("SMS_Program").SpawnInstance_() 
objNewProgram.ProgramName = "InstallTest" 
objNewProgram.PackageID = PackageID 
objNewProgram.Comment = "My Company" 
objNewProgram.CommandLine = "FWStart.bat /I" 
objNewProgram.ProgramFlags = 2148581376 
objNewProgram.SupportedOperatingSystems = instOSDetails 
objNewProgram.Put_ 

How to find out what are supported OS platforms

This VBS script will allow you to enter a ConfigMgr 2007 site server name and site code and will list the supported platforms and write them to an excel spreadsheet. 
 
strComputer = InputBox ("Enter SMS Server Name")
strSiteCode = InputBox ("Enter Site Code")
 
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
objExcel.Workbooks.Add
intRow = 2
 
objExcel.Cells(1, 1).Value = "Operating System"
 
Set objWMIService = GetObject("winmgmts://" & strComputer & " ootsmssite_" & strSiteCode)
Set colItems = objWMIService.ExecQuery("Select * from SMS_SupportedPlatforms")
For Each objItem in colItems
objExcel.Cells(intRow, 1).Value = objItem.DisplayText
intRow = intRow + 1
Next
 
objExcel.Range("A1").Select
objExcel.Selection.Interior.ColorIndex = 19
objExcel.Selection.Font.ColorIndex = 11
objExcel.Selection.Font.Bold = True
objExcel.Cells.EntireColumn.AutoFit
 
Set objSheet = objExcel.ActiveWorkbook.Worksheets(1)
Set objRange = objExcel.Range("A1")
objRange.Sort objRange,1,,,,,,1
 
MsgBox "Done"

How to set the remote flag for the program

Flags specifying how the program should run when the client is connected either locally or remotely to a distribution point. The default value is 48.  Following the binary to decimal conversion process (http://www.wikihow.com/Convert-from-Binary-to-Decimal).  In the case of the 11th digit the binary value is a one with 10 trailing zero's (1000000000).  When you want to specify multiple flags, you must use the OR operator with the the decimal values.  The following flags (I converted its binary digit to decimal):  
2048 = Always Rerun,
4 = Run from Local 
64 = Run from Rem
ote

  To determine if a specific flag is set, you use the AND operator (with decimal values).  If I wanted to determine if "Always Rerun" was already set, I would use the following: 

 iFlags = 2184

If iFlags AND 2048 = 2048 Then Wscript.Echo "Always Rerun: Enabled"  

Do not forget to verify the  scrip result in the SCCM Administration Console.

Comments