What we are trying to built here is a Boot Wizard which will show a dynamic list of available OSD Task Sequences from SCCM 2007 to choose from. The chosen Task Sequence shall then be executed on the local computer. To ease our job regarding the final deployment and the management of the Boot Images, we want to have a single Boot Image to be used for WDS/PXE/CD Deployment for all known and unknown computers.
In the last article (Create your custom Boot Wizard - some advanced stuff) we dived into some advanced topics for our custom Boot wizard extending the great Introduction to the Deployment Toolkit Wizard Editor from Todd Hemsell. This article now will concentrate on the dynamic data part. We will request the Task Sequences from SCCM and display them in our Boot Wizard.
So how are we going to get the necessary information? There are a couple of possible solutions. The most apparent way would probably be to get a list of all (OSD) Task Sequences from SCCM. With this we only have the Task Sequence itself, but we also would need to know the necessary Collection to put the computer into it. We could then get all collections the chosen Task Sequences has been advertised to but what if it has been advertised to several collections? (Think about scenarios to use the same Task Sequence for reimages and redeployments (No profile data and old applications on redeployments), adding a variable to the collection. If you are interested to hear more about this, just drop me a note).
What we will use for now are the collections which have an OSD Task Sequence advertised. To be able to use collections and to not create other problems we need to stick to some standards:
- Collections need to be created per Primary!
- Only one Task Sequence advertised per Collection
- Advertisement needs to be mandatory
- informative Name and Description for the collection
As a suggestion, create a collection which will contain all other collections used for OSD Deployments. This way you have them organized and you can advertise the approved Software Updates against the "hosting" collection so all updates are available for all deployments without future configurations. There might be cases where we want to have a collection not available for the general public (Testing new Drivers/Applications, Creating the Reference Image, etc). To be able to "hide" certain Collections from the list we simply add the word "Disabled" to the comment of the collection and filter them out.
OK, how do we get the collections? We can get them with a "simple" WMI query which we need to execute against the assigned Site. It could look like this:
SELECT * FROM SMS_Collection WHERE CollectionID IN
(SELECT CollectionID FROM SMS_Advertisement WHERE PackageID IN
(SELECT PackageID) FROM SMS_TaskSequencePackage WHERE Type = 2))
Then we filter out the "Disabled" Collections (another Option would be to include all of them and filter in the Boot Wizard) and all Collection starting with "SMS". Why? We don't want to have Collections like "All Systems" or "Unknown Computers" included. Read through the next articles and you will see that this makes sense :-)
As I don't like to have such code within an FrontEnd like the Boot Wizard we will create a new function for our Webservice. As there are already a couple of articles explaining how to write a webservice we will skip this step for now. Just have a look on our Codeplex page with MDT Scripts, Front Ends, Web services and Utilities for use with ConfigMgr/SCCM where you will find the complete Deployment webservice project to download and run in your environment. Also all scripts and files used for this and other articles. And if you are interested to dig deeper into it you will also find the complete source code.
Back to topic.
We now have a webservice which we can call to get a list of Collections. We now take our Boot Wizard from the last article and add some code to call the webservice and bind it to our Table. For larger or more complex wizards it's probably better to separate the code for the initialization and validation functions. However we will just store everything in the File "CustomBootWizard.vbs" which was created in the last article.
Start the Wizard Editor and Open the CustomBootWizard.xml file we created in the last article (or simply download the complete example :-) ). Choose the first pane called "MyPane" in our example. On the "Settings" Tab click on "Add" and choose "Initialization". Then click "OK". In the Text Area on the right side type "InitializeTSList". This is the name of the function which will call the webservice. Open the CustomBootWizard.vbs file and add the following function to it:
Function InitializeTSList
Dim oService
Dim oTSList
Set oService = New WebService
oService.IniFile = "SCCM_Bootstrap.ini"
oService.SectionName = "GetOSDCollections"
Set oTSList = oService.Query
If oTSList Is Nothing Then
oLogging.CreateEntry "Unable to call GetOSDCollections web service.", LogTypeWarning
Exit Function
End If
tasksequences.XMLDocument.LoadXML oTSList.xml
End Function
This function will execute a webservice call. The definition is stored in another file called "SCCM_Bootstrap.ini" which needs to be available in the same folder as the script. The section called could look like
[GetOSDCollections]
WebService=http://YourWebServer/Deployment/SCCM.asmx/GetOSDCollections
Parameters=AssignedSite
AssignedSite=siteCode
We will come to the "AssignedSite" Parameter in a bit. What will happen now if the wizard starts is, it will first call the "InitializeTSList" Function which executes the webservice and binds the result to the XML Data Island. Then the table will process the XML and create a dynamic list of Collections we can choose from. Make sure that you also have the "ReadyInitializeTSList" and "AppItemChange" Functions in the CustomBootWizard.vbs script (as shown in the last article.
Finally after a Collection has been chosen we need to clean up a bit and store the chosen Collection for further processing. In the Wizard Editor on the Settings Tab of the "MyPane" add a "Validation" Setting. This one will be executed when the User click on Next/Finish. In the Textarea on the right side add the name "ValidateTSList" and add the following function to your CustomBootWizard.vbs script:
Function ValidateTSList
Dim TSCollID
Dim Result
Result = False
SaveAllDataElements
TSCollID = oProperties("TSCollectionID")
If IsArray(TSCollID) And Not IsNothing(TSCollID) Then
oProperties("CollectionID") = TSCollID(0)
Result = True
ElseIf Not IsNothing(TSCollID) Then
oProperties("CollectionID") = TSCollID
Result = True
Else
oLogging.CreateEntry "No TaskSequence selected!", LogTypeWarning
End If
ValidateTSList = Result
End Function
This Function checks if a value has been selected and will then store the CollectionID to make it available for further script processing. There are three things to mention.
First, it calls the Function "SaveAllDataElements" which is a Wizard internal function. It will save all values from the wizard pane to the collection "oProperties".
The Second is the "IsNothing" Function. This is a custom function which will simply return True if the supplied value can be interpreted as "Nothing". In vbscript there are a lot of different "Nothings" like "", 0, Nothing, Null, Empty, etc all depending on the type you check. Especially Arrays can be quite challenging to check in vbscript. So to ease your (and my) job I added this function into this example which will take care about such issues. Find the complete "IsNothing" Function in the scripts to download.
Finally the Third is how we get the selected CollectionID. You might remember from the last article, that all but the selected hidden input field were disabled. The SaveAllDataElements will only save "enabled" elements so skip all disabled items. But it will still interpret it as an array as there are still several input fields with the same name. The selected CollectionID will always be the first item in the array. That's why we can get it with TSCollID(0). The ElseIf is only for the case where you have a single line in your table. Then it won't be an array rather a scalar value.
We have now completed the wizard. You should now have a basic understanding on how the Wizard Editor works, how to add you custom panes, initialize the values, get dynamic data, and finally validate and store the results. The next article will show you how to execute the wizard and process the results of the wizard.
As mentioned already, you will find all files, scripts etc. on our new codeplex page http://mdtcustomizations.codeplex.com/ (Download example files). It has been created as a repository for MDT Scripts, Front ends, Web services and Utilities for use with ConfigMgr/SCCM.
See also the next articles
Create your custom Boot Wizard - Execute the wizard, process the results and create the Boot Image
Create your custom Boot Wizard - make it available for all known and unknown Computers
Using a custom Boot Wizard to boot known and unknown computers in SCCM and choose a Task Sequence to run - Step by Step