Tuesday 3 April 2012

Tick box HTA in a SCCM Task Sequence?

I really like SCCM, System Center Configuration Manager. I think its pretty awesome and I mean we are still only using the 2007 version since, well we are still following the golden rule of waiting for SP1 to come out and/or for Windows 8 to force us to SCCM 2012 but I guess we will cross that bridge when we come to it.

The SCCM with all its goodness, can be a pain in the ass. It is incredibly flexible with the use of Task Sequences for deploying an OS and I believe that we have taken this to the most extreme point possible with SCCM. We are imaging our machines with only 2 task sequences for every model of computer in the school but why do we have two? because of one being x32 bit and one being x64. That's the only difference between the two since they both require enough differences that it was just easier to make two task sequences. Not to mention that our x64 Task Sequence is already massive and loads a little slow in the console :).
Anyway onto the actual subject at hand which is that we had a problem during development that we wanted to select custom software options for the task sequence to install but we did not have a static information source that could be gained from the local computer to perform this. ie we want some computers of the same model to have the Adobe CS4 software installed, but not all, and more over we did not want to have a separate task sequence for every possible combination of custom software to be installed. We then thought about moving on to using a custom screen after the task sequence had started that would allow us to select what software we wanted installed. Sounds simple enough until you actually try to do this since SCCM has now native support for this what so ever which I find amazing that a system so flexible can sometimes be so limiting....
So in our great search of the mighty google I stumbled across this post which kinda got me started on the whole saga
http://technet.microsoft.com/en-us/systemcenter/cm/bb507744

There are some other people that have also done a "similar" thing since we have now implemented(thanks a lot everyone! if you had done this a year earlier it would have made my job a lot easier!)
So off I went and implemented the above post with one exception, that there was no good way to get rid of the Task sequence progress window, or was there?

So lets get started
PreReqs
You will need the following to get this all up and going
-We will need to download the Windows AIK(Automated Installation Kit) from here
and install it onto the computer.

First we need to add HTA support to the WinPE which is not natively in the WinPE which MDT installs

Now since someone else has done all the hard work for me I will just link to there instructions :P
http://t3chn1ck.wordpress.com/2010/01/28/hta-support-in-sccm-boot-images/

Once you have added the HTA support to the WinPE we can now add the scripts and package.
The scripts I have been using are from a collection of sources but the main ideas came from here and here so credit where its due for these two websites :)
The VBS Script I use is as follows
' Hides current Progress UI to bring the HTA to the front
Set ProgressUI = CreateObject("Microsoft.SMS.TsProgressUI")
ProgressUI.CloseProgressDialog
' Create a WshShell object
set sh = CreateObject("Wscript.Shell")
' Call the Run method, and pass your command to it (eg. "mshta.exe MyHTA.hta").
' The last parameter ensures that the VBscript does not proceed / terminate until the mshta process is closed.
call sh.Run("select.hta", 1, True)
 My script name is "select.vbs" when I have used it and the HTA page script is as follows

 <html>
<head>
<title>OSD Front End Script</title>
<HTA:APPLICATION APPLICATIONNAME="OSD GATHER" SCROLL="yes" SINGLEINSTANCE="yes" WINDOWSTATE="normal" BORDER="thin">
</head>

<script language="vbscript" type="text/vbscript">

' Set objects and declare global variables
Set env = CreateObject("Microsoft.SMS.TSEnvironment")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Sub Window_onLoad
    window.resizeTo 400,550 ' Resize the HTA window on first load
    window.moveTo 100, 10 ' Move the window to the center
End Sub

Sub ButtonFinishClick
    ' ButtonFinishClick is executed by the "Finish" button.
  
    ' Set value of variable to true/false based on whether the checkbox is selected or not
    If FullImage.Checked Then
        strFullImage = "true"
        else strFullImage = "false"
    End If
  
    If Office2010.Checked Then
        strOffice2010 = "true"
        else strOffice2010 = "false"
    End If
    If Office2007.Checked Then
        strOffice2007 = "true"
        else strOffice2007 = "false"
    End If
  
    If AdobeCS4.Checked Then
        strAdobeCS4 = "true"
        else strAdobeCS4 = "false"
    End If
  
  
    ' Set value of variables that will be used by the task sequence, then close the window and allow the task sequence to continue.
    env("OSDFullImage") = strFullImage

    env("OSDOffice2010") = strOffice2010
    env("OSDOffice2007") = strOffice2007

    env("OSDAdobeCS4") = strAdobeCS4
  
    window.Close
End Sub

</script>

<body STYLE="font:14 pt arial; color:white; background-color: #000000">
<span id = "List"></span>
<p>Disk Partition<br>
<input type="checkbox" name="FullImage"> Full Image - C: 100GB<br>
<br>
<br>
<input type="checkbox" name="Office2010"> Office 2010<br>
<input type="checkbox" name="Office2007"> Office 2007<br>
<br>
<input type="checkbox" name="AdobeCS4"> Adobe CS4<br>
<br>
<button accesskey=N type=submit id=buttonFinish onclick=ButtonFinishClick >Install</button>
</body>
</html>
 The HTA Script is called "select.hta". I know I am so creative with my naming!!


As you can see in the script above I have environmental variables being set with the tick boxes which you can customize to your own including adding/removing some of the tick boxes to add more or less options.
piccy of HTA page















Once the enviromental variables are set, they are then accessible by the SCCM Task Sequencer which allows us to make variable dependent Software installs which I will go through how to add a bit later.
both scripts can be downloaded from here


Once you have both the scripts you can dump them into a package to be added to the Task Sequence. As a side note for some reason I have to add Read Access for Guests to my package for it to run correctly but I have not seen anyone else having to do this and this is the only package I have had to do it for. To add a guests access to the package right click on the Access Accounts and Select Generic Access Account.



Click Set, select Guests and OK. Make sure that the Permissions is set to "Read" then select OK

 All this means is the Distribution Point(DP) share can be accessed by anyone, not that there is anything particularly interesting to look at in the scripts but it is something to be aware of because if you have anything with sensitive data that you where planning to include in this bundle, you may want to make another one that doesn't have Guests Access :) I suspect that the problem "may" have to do with the way a VBS script tries to open the HTA page which doesn't really make sense but the important thing is that this fixes it!

The package name I have used is SCCM UI(yeh i know another creative name:P) and now 
Its time to add the Package to the Task Sequence
Add a "Run Command Line" step to the TS and enter the "cscript select.vbs" or what ever your vbs script is called and select the Package that currently contains the scripts








*Edit*

I have had a couple of people have problems with the Task Sequence not continuing when you click finish because the TS is not correctly detecting that the VBS has actually finished and closed. I didn't get this problem, but I have seen it with other software installs. If this happens to you change the following under "Option", "Success codes:"


And Viola! next time you start the TS you will be prompted on which Tick Boxes you would like!







but how do we make the Software installs variable dependent? Its actually surprisingly easy
Select a package or Group you would like the variable dependence to be on and select Options, Add Condition then Task Sequence Variable











 

Type the name of the Variable, set the Condition to equals and the Value as True

This will cause the group/software to only run if that task sequence "condition" is met, which is this case is that OSDOffice2010 is set to true and since all Env variables will return a null or false value unless otherwise set the Variable will only be set during the HTA page.





Since we have our package to download locally from the DP I have then run into the problem of the package generating an error when it tries to run sometimes. This turned out to be that if the Hard Drive did not have a usable NTFS partition, the software would not be able to download and then be run locally. To fix this problem a format and partition setup step must be added before the HTA page that runs to check for a partition and if it does not exist, to create one on the drive.

To do this add a "Format and Partitions Disk" prior to the HTA Page running
Create the partitions that are used in a clean disk scenario since this will only run if it is a clean disk.
and don't forget to select the "Quick format" tick box under the properties of the partition created






  After that this is where we add the condition to only run if there is not an existing partition.
Go to options add add the "If" Statement specifying if "None" of the conditions are true. This will cause the Partitioning to run if the following query returns a false value which would mean that the partition infact does not exist.
 
Select the If statement then add a Query WMI with the following statement 
SELECT * FROM Win32_DiskPartition WHERE Caption LIKE "%Disk #0, Partition #0%"
this will run a WMI Query which will check to see if a partition on Disk 0, and if it does it will cause the Query to return a True value which will then cause the disk partitioning to not run. Simple enough :)

Please note because you are playing with disk partitions, you could potentially wipe disks if you make a mistake so please PLEASE test these before going into production

HAVE FUN!!!

EDIT
I have also been made aware of yet another way of doing the same thing I have done(great, more work wasted, but I will stick with what I have :P). Feel free to have a look
linky: http://osdappchooser.codeplex.com/