Trevor Sullivan's Tech Room

Minding the gap between administration and development

HTA in SCCM Task Sequence

Posted by Trevor Sullivan on 2009/08/25


Summary

There has been lots of discussion about using Microsoft HTA (HTML Applications) files to prompt for user input, pop up notifications, and so on, in a ConfigMgr OSD Task Sequence. Although, by default, the task sequence engine prevents interactive programs from being seen, you can work around this functionality by simply writing a VBscript wrapper around the program you want to make visible.

WinPE

In order to use HTAs in your task sequence during the WinPE phase, you’ll need to make sure that you have HTA support built into your WinPE 2.0 boot image. This may require building a custom boot image using the Windows AIK, adding HTA support, and then importing it into your ConfigMgr console.

VBscript Code

To restate what I said earlier, in order to spawn an HTA interactively during a task sequence, all you have to do is wrap the MSHTA command into a VBscript. This assumes that you have already developed your own HTA called “MyHTA.hta” … Let’s take a look at how to do this:

' 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("mshta.exe MyHTA.hta", 1, True)

Packaging It Up

  1. Put your HTA and VBscript (we’ll assume it’s called SpawnHta.vbs) inside a standard ConfigMgr package
  2. Add a “Run Command Line” task sequence item into your task sequence, where you’d like the HTA to appear
  3. In the command line box, type “cscript SpawnHta.vbs
  4. Check the Package checkbox, and click Browse to locate the package you created

You have now successfully added your HTA to your task sequence! Here is a screenshot of what my task sequence looks like (my script sits in a subfolder of the package, and is named differently):

HTA Prompt

One Step Further: Hiding the Task Sequence Progress UI

Although the above VBscript code will spawn the HTA window interactively, you’ll still probably be disappointed that the task sequence progress UI window is set to be “always on top” meaning that you’ll have to manually move it out of the way to fully see the HTA. I have a little trick though, which lets you hide this, and bring it back, exactly to where it was …. automatically! Download and install AutoIT, and compile the following script:

dim $WindowName
dim $winpos
dim $winstate
dim $WindowWait
; Partial title of task sequence progress window
$WindowName = "Installation"
; Store current position of task sequence progress window
$winpos = WinGetPos($WindowName)
; Move the task sequence progress window way off-screen
if WinExists($WindowName) Then
 WinSetOnTop($WindowName,"",1)
 WinActivate($WindowName)
 WinMove($WindowName,"",10000,10000)
EndIf

; Give the hosting VBscript a couple of seconds to spawn off mshta.exe
Sleep(2000)
; Wait for mshta.exe to close
ProcessWaitClose("mshta.exe")
; Move the task sequence progress window back to its original position
if WinExists($WindowName) Then
 WinSetOnTop($WindowName,"",1)
 WinActivate($WindowName)
 WinMove($WindowName,"",$WinPos[0],$WinPos[1])
EndIf

  1. Place the compiled executable into the same folder where your VBscript and HTA reside
  2. Update your VBscript to look like this:

Option Explicit
dim sh, fso, scriptpath, ToolsFolder, HideUiExe
set sh = CreateObject("Wscript.Shell")
set fso = CreateObject("Scripting.FileSystemObject")
scriptpath = left(wscript.scriptfullname, len(wscript.scriptfullname) - len(wscript.scriptname))
ToolsFolder = sh.ExpandEnvironmentStrings("%SYSTEMDRIVE%\Tools\")
HideUiExe = ToolsFolder & "HideTSUI.exe"
If Not fso.FolderExists(ToolsFolder) Then
  call fso.CreateFolder(ToolsFolder)
End If

' *** Copy HideTSUI exe locally, otherwise the Windows Script Host
' *** can't find the file ... kind of weird, but oh well
If Not fso.FileExists(HideUiExe) Then
  call fso.CopyFile(ScriptPath & "HideTSUI.exe", ToolsFolder)
End If
dim Result, HtaCmd
wscript.echo "Hiding user interface (" & HideUiExe & ")"
Result = sh.run(HideUiExe, 1, false)
wscript.echo "Spawning HTA (" & HtaCmd & ")"
HtaCmd = "mshta """ & scriptpath & "OSPrompt.hta"""
Result = sh.run(HtaCmd, 1, true)

Conclusion

Once you’ve followed these directions, you should be able to spawn an interactive process during a ConfigMgr OSD task sequence! Please feel free to leave a comment or e-mail me if you have any trouble with this!

Advertisements

24 Responses to “HTA in SCCM Task Sequence”

  1. Greg Wood said

    FYI, no need to do all of this, you can hide this with a few lines of VBScript:

    Set ProgressUI = CreateObject(“Microsoft.SMS.TsProgressUI”)
    ProgressUI.CloseProgressDialog

    It will reappear after that step is done.

  2. pcgeek86 said

    Wow, thanks Greg. I guess that was a pretty big fail on my part.

    -Trevor

  3. Matt said

    Hi Trevor,

    In you task sequences have you got information on how to call applications via a collection rather then setting up app bundles and applications in deployment workbench?

    • pcgeek86 said

      Hi Matt,

      Thanks for your question. I don’t have any examples of how to do this, although I would imagine that you could use a combination of desired configuration management (DCM), or I think there’s a web service out there that can populate a client into a collection during a task sequence. I’d have to track down what that is though. I believe it’s posted on CodePlex.

      Cheers,
      Trevor

  4. Stefan Weber said

    Hi,
    i just walked thru your article which is exactly what we need. Unfortunatly the hta does not get display but runs in the background. iam using SCCM SP2. Any idea what could be wrong here ?

    Thank you,
    Stefan

  5. Tim said

    Having the same trouble that Stefan reported using SCCM SP2. I’m have an XP client. I can see cscript.exe and mshta.exe running as processes in task manager so I know it’s working but can’t seem to make the HTA visible. Tried lots of options, including running the command with a domain user account. Still no luck.

    • Trevor Sullivan said

      Yeah, I think it’s been proven that you can’t do this once you’re in the full OS.

      😦

      -Trevor Sullivan

      • Kev said

        FYI – with Windows PE 3.0 (and in Windows 7) found that “mshta.exe MyHTA.hta” doesn’t work but specifying the HTA only does. This is working in the wrapper for me:

        Set ProgressUI = CreateObject(“Microsoft.SMS.TsProgressUI”)
        ProgressUI.CloseProgressDialogset sh = CreateObject(“Wscript.Shell”)
        set sh = CreateObject(“Wscript.Shell”)
        call sh.Run(“MyHTA.hta”, 1, True)

  6. Jack Rudlin said

    Dude, this is excellent, but the bit I’m most interested in is the OSPrompt.hta. Any tips on how to put together this code?

    Thanks

    Jack

    • Trevor Sullivan said

      Hi Jack,

      It really depends on what you want to do in the HTA. Typically I’d recommend building a custom one for your needs, but here is one that somebody posted as an example:

      http://verbalprocessor.com/2009/05/05/configmgr-front-end-hta/

      Cheers,
      Trevor

      • Jack Rudlin said

        Hi Trevor,

        I’m spefically looking for the ability to choose which O/S to deploy to the PC. ie. Windows XP or Windows 7, which it seems you have coded already 🙂

        I guess the .hta just sets the variable which you then assign as a Conidtion on the task sequence options?

        Jack

      • Trevor Sullivan said

        Hi Jack,

        Yes, you would just create a custom task sequence variable in the HTA and then use that as a conditional within your task sequence. You’ve got it.

        Cheers,
        Trevor

  7. Trevor,
    I’m assuming you were only able to make this work during the actual OSD.

    I’m trying to do this with a Task Sequence that I’m using for software deployment. Nothing I’ve tried seems to work. I tried calling the HTA directly, calling a script to call the HTA, calling a script to call a script to call the hta, etc….

    Any ideas on how to make it work when the operating system is loaded (not during an OSD)?

    • Trevor Sullivan said

      Nick,

      Yeah, I realized later on that this won’t work in a full operating system; I had only tested it in a WinPE phase. I believe that someone developed a solution to this using the Modena toolset developed by Microsoft Internal IT. I’ll have to see if I can dig that up and send it over to you.

      Cheers,
      Trevor

  8. Mike said

    Good info. Thanks.

  9. Shawn said

    I have the same issue as Nick, trying to run something as a task sequence for distributing software inside of a full running OS, not PE. Any idea how to make things run in the foreground?

  10. tobewah said

    Dialogues won’t be displayed from a task sequence running in the OS as they run using the local system account and therefore can’t interact with the desktop.

    Have a look at ServiceUI which provides a way to interact with the desktop from a task sequence.

    I use it with a small exe called MessageBox to provide popups from task sequences. It can be combined with a vbscript (like the one posted above) to hide the task sequence UI using cmd.exe like this:

    cmd.exe /C cscript.exe hideTsProgressUi.vbs & ServiceUI.exe -process:tsprogressui.exe MessageBox.exe /C:Title... /M:Message... /T:4160

    cmd.exe /C is required as without it the Run Command Line task sequnce step ignores everything after the ampersand (&). Just replace “MessageBox.exe…” with you’re own application (“mshta.exe myapp.hta” etc.)

    • RDDvls1999 said

      Hi Tobewah,

      I have been struggling with the method you were able to get working using messagebox. I have been trying to use miniNotify (http://www.myitforum.com/forums/New-SMS-Simple-Notification-miniNotify-m176854.aspx) as the method of notifying users about pending updates, but each time I try the TS bombs out. Would you mind trying to replace messagebox with the mininotify app and seeing if it works for you? I’d be interested to hear if it did.

      Thanks!
      Paul

      • tobewah said

        Hi RDDvls1999,

        I haven’t had time to try miniNotify yet but was under the impression this was designed to run as a standard SCCM program before the task sequence using the “run this program first” function (advanced tab of task sequence properties).

        Also having read through the page that you linked to it seems there’s a issue with running this over the network so make sure that your task sequence is set to download content to the cache. Also make sure there’s no Group Policy in place that supresses system tray notifications.

        It looks good so I’ll try and have a go in the next couple of days.

  11. RDDvls1999 said

    Hi Tobewah,

    Thanks for the response. Just to give you a quick update. I was finally able to get this app to work by copying the files locally first and then calling the app from there. It works pretty well, the only issue now being that if someone selects the option to postpone but doesn’t pick a time (15,30,60 in our case), then the TS continues on as if they had selected “install now”. Not an ideal scenario, I’m sure you’ll agree.

    On a related note, would you mind giving more details on how you manage your software deployments? Do you notify your users ahead of time and allow them to postpone the updates if necessary? Do you have a mechanism for notifying the users that there is a job running if they try and log in to the computer before the job has finished?

    Any insight you have would be greatly appreciated.

    Thanks!
    Paul

    • tobewah said

      Hi Paul,

      Firstly, I should say I’m not an authority on SCCM! Every environment is different but I’m happy to tell you how we do things.

      Microsoft software updates: Users have a week to install in their own time before updates go mandatory.
      Small standard software (Flash, Java etc): Silently without notification.
      Larger standard software (Acrobat Reader etc): E-mail notification and/or popup message, then mandatory installation. We try to use a “passive” msi installation where possible so the users can see the installation progress.
      Non-standard software: Self-service (i.e. non-mandatory). Again we try to provide a progress dialogue where possible.

      Of course, there’s always exceptions but this is our general rule of thumb. Our users are mostly techies and pretty easy going so it works for us.

      Toby

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: