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/

13 comments:

  1. Not sure if you can help me but when I select my variable from my HTA and click on the Finish button, I get a blank page and the task sequence never continue.

    ReplyDelete
  2. Apologizes for the late reply, My wife recently gave birth so I haven't touched my computer for the past month.

    Anyway, I have actually ran into this problem and its due to the Task Sequence step not correctly detecting that the process has ended. I didn't have this problem but I have had another person email me about it. You can actually set a manual process success code which should then help TS to detect when the VBS has ended.

    Open the TS Editor and select the UI Run step.
    select Options then in the Success Codes type 0 3010

    I will also update my post to reflect this change for others to see

    ReplyDelete
  3. Hi Daniel,

    First of all thanks for the very detailed steps. I've managed to setup the hta and launch it from standalone media. However, it doesn't look like my TS actually picks up any of the information.

    Do I have to define empty variables on the TS before they can be set by the script?

    ReplyDelete
    Replies
    1. Hi Gary,

      From my understanding you can create TS Variables directly in the HTA Script just like I have done above.
      More so I actually re-created this same system in SCCM 2012 and it worked exactly the same way.

      Are you launching the HTA page manually?
      if you are you will need to make sure you launch the page AFTER the TS has actually started rather than at the TS selection page. The TS variables are only saved once the Sequence has been started thus if they are started at the selection page they will be cleared when you start the TS.

      also I know it seems in the script that I have doubled up on variables but unless the variable is specifically set as environment variable it will not be set in the TS such as

      env("OSDOffice2010") = strOffice2010

      also if you want to see if the variables are set, you can make and run the following VBS script to see what variables are set which should help you narrow the problem down.

      Dim oVar, oTSEnv

      Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")

      For Each oVar In oTSEnv.GetVariables

      WScript.Echo " "& oVar & "=" & oTSEnv(oVar)

      Next

      and as a note
      If you have a condition on a variable TS step that has not been created it will just return a null value.

      hope that helps!

      Daniel

      Delete
    2. Daniel,

      Thanks for your reply.

      I found my error a few days back. In my testing I had actually commented out all of the lines where the variables were being set in the environment. Felt like a bit of an idiot when I went back and saw that in the package.

      Thanks.

      Delete
  4. Interesting, thanks so much for sharing this. Are there any options if there are multiple programs that you want to install separately in a software package?

    ReplyDelete
    Replies
    1. If I am reading your question right, you have multiple programs to install in a single program package that you have separate run programs for each piece of software?

      if that is the case you add the program package multiple times to the TS and select a different run for each package you have added. You can also use the same variable check that you set with the tick boxes on multiple programs if you would like or, as I have done, create a folder in the TS and place all the programs you would like to run and add the variable check on the folder that contains all the programs.

      hope that helps

      Delete
    2. Yes, that is correct. multiple programs - one package. Each program has a specific cmd line install that has db info, server, etc. Thanks for the reply, I will check try that out.

      Delete
  5. Hi,
    I have created a task sequence to boot into WinPE and the hta launches sucesfully. I have left the hta and script untouched and added the variable OSDOffice2010 equals true to my Office 2010 package. After selecting Office 2010 and pressing finish it never installs. I do not have any other variables set.
    Would you know why Office is not installing. The package is ok as it normally installs fine in other task sequences.

    ReplyDelete
    Replies
    1. Hi Emma,

      Once you have selected the tickbox and hit the install button you can try running the script below
      Dim oVar, oTSEnv

      Set oTSEnv = CreateObject("Microsoft.SMS.TSEnvironment")

      For Each oVar In oTSEnv.GetVariables

      WScript.Echo " "& oVar & "=" & oTSEnv(oVar)

      Next

      to display if the variable is set

      If the Variable is set in the echo, then the problem is that the package has not had the variable check done on it.

      if its not set, then there is something wrong in the HTA script.

      Delete
  6. I ran the script and it showed the correct variable set to true.

    It turned out it was the office package. I recreated it and it is now installing successfully. Many thanks for this it has saved us doubling up on separate ts for office std and pro.

    ReplyDelete
    Replies
    1. Not a problem EmmoD!

      Glad it helped you out.

      Delete
  7. Can anyone help me how to get OSD Menu like adding machine to OU and User details in the AD computer description during the TS OSD ?

    ReplyDelete