MDT Scripting: Creating custom scripts Getting Started

Although MDT is very powerful, there will still be times when dealing with complex tasks that you will require a custom script. Fortunately you can use your own custom VB scripts in MDT as a task sequence step by calling the command line:

cscript.exe "%SCRIPTROOT%\CustomScripts\MyScript.wsf"

It is however, best practice (and to save time) to use the MDT Custom Script Template to create your custom scripts for use within task sequences. This also applies to Zero-Touch custom scripting in SCCM. The MDT Custom Script Template is a WSF(Windows Scripting Host) script that calls functions (pre-written subroutines) in another script called ZTIUtility.vbs. The template is below:

<job id="Z-Sample">
<script language="VBScript" src="ZTIUtility.vbs"/>
<script language="VBScript">

' //***************************************************************************
' // ***** Script Header *****
' //
' // Solution: Solution Accelerator for Microsoft Deployment
' // File: Z-Sample.wsf
' //
' // Purpose: Template
' //
' // Usage: cscript Z-Sample.wsf [/debug:true]
' //
' // Customer Build Version: 1.0.0
' // Customer Script Version: 1.0.0
' // Customer History:
' //
' // ***** End Header *****
' //***************************************************************************

'// Global constant and variable declarations

Option Explicit

Dim iRetVal

'// End declarations

'// Main routine

On Error Resume Next
iRetVal = ZTIProcess
ProcessResults iRetVal
On Error Goto 0

'// Function: ZTIProcess()
'// Input: None
'// Return: Success - 0
'// Failure - non-zero
'// Purpose: Perform main ZTI processing
Function ZTIProcess()

     iRetVal = Success

     ZTIProcess = iRetval

     '!!!!!!!!!!!   INSERT YOUR CODE HERE   !!!!!!!!!!!!

End Function


This is nothing new, people have been scripting in MDT and SCCM using this template with the ZTIUtility for a while now. Ben Hunter has an old article on this here. However, some customers that I have encountered recently have not been aware of this so hopefully this article will raise awareness for them and also for my regular blog readers.

Why do this? Well, the ZTIUtility.vbs is full of pre-written functions designed to manage files and folders, registry settings and it can use MDT’s collected variables etc. so you don’t have to waste time designing and generating your own custom code. Plus, there are fantastic logging features available to help with monitoring and debugging.

How does it work? Simply copy the template and save it with a .WSF extension then add custom code at the INSERT YOUR CODE HERE section that calls functions. Here you can call in the ZTIUtility subroutines.

You typically save the script in the scripts folder of your deployment share with a ZTI prefix. Next, create a Run command line task sequence step to call the script in your deployment. eg.

cscript.exe "%SCRIPTROOT%\ZTIMyScript.wsf"

Over the next few blogs, I’m going to explain further and write and post some scripting examples showing how to use the template to tackle everyday real world deployment tasks.

About Andrew Barnes

A Scripting and Deployment Specialist.
This entry was posted in MDT 2010, Scripting and tagged , , , . Bookmark the permalink.

15 Responses to MDT Scripting: Creating custom scripts Getting Started

  1. Jean Doyon says:

    Great article! Thank you!


  2. Hastur says:

    Great article as usual, for a beginner like me your blog is a gold mine, thx a lot !


  3. James King says:

    Question: what if I want to keep my custom scripts in a subdirectory of the Scripts folder? For example %SCRIPTROOT%\Custom. What is the proper way to reference ZTIUtility in the header where it says src=ZTIUtility.vbs? Thanks for the help, this blog as been really helpful as I am just getting started with MDT!


    • Like you said, just use %SCRIPTROOT%\Custom\script.wsf


      • James King says:

        Hey thanks for the reply. I was actually referring to the header of the template: . If I use the template for my custom scripts but I want to put them in a subfolder of the Scripts directory, I have to do something like because my folder structure looks something like \Scripts\CustomScripts\FinalConfiguration. I have some supporting files that my final configuration script needs so I was trying to keep it neatly organized.

        I was hoping there was a way to do something like to make my script a little more portable in case I need to change the folder structure in the future, but doing so results in an error that it can find the referenced URL. Is there any way to do something like that? Is it best practice to keep custom scripts organized in a subfolder or just drop them directly in the Scripts folder? Thanks for your thoughts.


      • James King says: VBscript got filtered out in my previous post. What I was trying to say is I have to do script language=VBScript src=”..\..\ZTIUtility.vbs” and I was wondering if there is a way to do something more like script language=VBScript src=”%SCRIPTROOT%\ZTIUtility.vbs” in case I ever need to change my folder structure.


      • Set up a test area as in this post. You should be able to use %scriptroot% or a relative path. You could also just drop a copy of the utility in the script folder. Interesting one this. Let me know how you get on, please.


      • James King says:

        Well I tried src=%scriptroot%\ZTIUtility.vbs and src=\Scripts\ZTIUtility.vbs. Both resulted in the error that the referenced URL could not be found. I think I will keep src=ZTIUtility.vbs and just drop the ZTIUtility.vbs file into my script’s folder. I was hoping there was a more elegant solution, as having multiple copies of the same file is kind of ugly, but at least it keeps my script independent of folder structure plus ZTIUtility doesn’t change so no worries about keeping the same version in the right places.


    • HN says:

      I think src=”..\ZTIUtility.vbs” will do…


      • I agree. I’ve seen many examples of this in production. The above example is ‘by the book’. Option Explicit is best practice along with declaring all variables using Dim. Also returning error codes through logging would prove useful in troubleshooting.

        This post will help you with getting started and I encourage any and all expansion upon it.


  4. Jonathan R. says:

    Hey Andrew,
    I have a custom script that require elevated privilege,
    Does MDT launch the command line task in an elevated prompt using Administrator account (post OS installation) by default ? can I make it use an elevated prompt ?
    Thank for all this material on your blog.


  5. ¡Hi Andrew!

    I hope that you’re very well. Currently I’m working in a project where i need to move all the task sequences and medias generated to SCCM. I was searching a script or something but there is not exist nothing at this time.

    Basically i want to confirm with you because the situation is this:

    Given that requires moving this, I found that I need to create jobs again in MDT sequence, create a media task again and create the appropriate removable media to make a successful migration and implementation.
    My precise question is: At this point is it feasible to integrate MDT with SCCM to create removable media?
    In addition to this, given that the company does not have the necessary for deployment across the network infrastructure, I think it would not be optimal integration but only to let the installation of MDT as they continue to use removable media only for implmentaciones.
    Finally, does the execution of scripts that I have configured in the MDT task sequence if I set work just the same way in SCCM?
    I know there are many questions, I thank in advance the time you took to read these paragraphs and lean on resolving these concerns.

    Best regards,

    Jason Corchuelo.


  6. Jason, it’s all feasible. Start a thread in the MDT forum and I’ll weigh in there.


Leave a Reply

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

You are commenting using your 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