MDT

Title: Windows Setup Body: Windows could not parse or process unattend answer file [C:windowsPantherunattend.xml] for pass [specialize]. The answer file is invalid.

MDT Tutorial Part 11: Troubleshooting Part 3: Windows could not parse or process unattend answer file [C:\windows\Panther\unattend.xml] for pass [specialize].  The answer file is invalid.

Living Table of Contents

What These Guides Are:
A guide to help give you some insight into the troubleshooting process in general.

What These Guides Are Not:
A guide to fix all issues you’re going to encounter.

We’re going to role-play a bunch of scenarios and try to work through them.  Remember in math where you had to show your work?  Well, what follows is like that which is why this post is [more than] a [little] lengthy.

Windows could not parse or process unattend answer file [C:\windows\Panther\unattend.xml] for pass [specialize].  The answer file is invalid.

Your last victory is short lived as the same error message appears and this time unattend.xml looks fine:

Troubleshoot-010.PNG

Stumped, you might search for ‘Microsoft-Windows-Shell-Setup’ which might lead you here:
https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup

As you review each section carefully the issue becomes clear: The computer name is more than 15 characters.

 

Copypasta Closing

Hopefully these examples will help give you an idea of the overall troubleshooting process.  Most of the time the problems you’ll encounter will be caused by a typso, order of operations or a ‘known issue’ that requires a specific process to be followed.

As you make changes to your environment, here’s what I recommend:

  • Be diligent about keeping a change log so you can easily backtrack
  • Backup your CS.INI or Bootstrap.ini before you make any changes
  • Backup your ts.xml or unattend.xml (in DeploymentShare\Control\TaskSequenceID) before you make any changes
  • Introduce small changes at time with set checkpoints in between and set milestones markers where you backup core files (e.g cs.ini bootstrap.ini ts.xml unattend.xml etc) to help minimize frustration troubleshooting.

And if when you do run into some turbulence, upload relevant logs (at least smsts.log but be prepared to submit others depending on the issue) to a file sharing service like OneDrive, post on TechNet then give a shout to your resources on Twitter.

Good Providence to you!

Advertisements
Title: Windows Setup Body: Windows could not parse or process unattend answer file [C:windowsPantherunattend.xml] for pass [specialize]. The answer file is invalid.

MDT Tutorial Part 11: Troubleshooting Part 2: Windows could not parse or process unattend answer file [C:\windows\Panther\unattend.xml] for pass [specialize].  The answer file is invalid.

Living Table of Contents

What These Guides Are:
A guide to help give you some insight into the troubleshooting process in general.

What These Guides Are Not:
A guide to fix all issues you’re going to encounter.

We’re going to role-play a bunch of scenarios and try to work through them.  Remember in math where you had to show your work?  Well, what follows is like that which is why this post is [more than] a [little] lengthy.

Windows could not parse or process unattend answer file [C:\windows\Panther\unattend.xml] for pass [specialize].  The answer file is invalid.

You boot your special VM, click the ‘Run the Deployment Wizard to install a new Operating System‘ button and it immediately starts.  Excellent!  It applies the OS, reboots and you’re faced with this error:

Title: Windows Setup Body: Windows could not parse or process unattend answer file [C:\windows\Panther\unattend.xml] for pass [specialize].  The answer file is invalid.

Windows could not parse or process unattend answer file [C:\windows\Panther\unattend.xml] for pass [specialize]. The answer file is invalid.

Well this is strange, because you didn’t touch the unattend.xml so what gives?
Fortunately, this dialog provides some meaningful insight:

    • The unattend file is C:\Windows\Panther\unattend.xml
    • The specific area is the specialize pass

Press SHIFT+F10 here to open a command prompt and then open C:\Windows\Panther\unattend.xml with notepad

Troubleshoot-005

You search for ‘specialize’ and after taking a very close look see that your computer name is incorrect.  It should be some two or three character prefix not %OfficeCode%.

Troubleshoot-006

Since that is set via the CS.INI, you run the CustomSettings.ini test again and now you see what was missed before:

Troubleshoot-007.PNG

You review the CS.INI and find your problems

  1. You didn’t define the OfficeCode property: Wasn’t added to the Properties line
  2. You didn’t set a value for OfficeCode.

With that fixed, you run the test again, the variable is populated and as you reimage the machine, you see it is named correctly in the logs.

 

Copypasta Closing

Hopefully these examples will help give you an idea of the overall troubleshooting process.  Most of the time the problems you’ll encounter will be caused by a typso, order of operations or a ‘known issue’ that requires a specific process to be followed.

As you make changes to your environment, here’s what I recommend:

  • Be diligent about keeping a change log so you can easily backtrack
  • Backup your CS.INI or Bootstrap.ini before you make any changes
  • Backup your ts.xml or unattend.xml (in DeploymentShare\Control\TaskSequenceID) before you make any changes
  • Introduce small changes at time with set checkpoints in between and set milestones markers where you backup core files (e.g cs.ini bootstrap.ini ts.xml unattend.xml etc) to help minimize frustration troubleshooting.

And if when you do run into some turbulence, upload relevant logs (at least smsts.log but be prepared to submit others depending on the issue) to a file sharing service like OneDrive, post on TechNet then give a shout to your resources on Twitter.

Good Providence to you!

MDT Tutorial Part 10: CustomSettings.ini Validation Testing & Troubleshooting Part 1

Living Table of Contents

Today’s Agenda: Troubleshooting

  • CustomSettings.ini Validation Testing
  • Troubleshooting OSD Issues

Recommended Reading

CustomSettings.ini Validation Testing

If you haven’t already done so, go ahead and make some useful edits to your CustomSettings.ini.  Since my aim is to have a dedicated ‘build’ machine that boots and automatically images the proper Task Sequence, this is what my CS.INI looks like now:


[Settings]
Priority=MACAddress,GetAbbrModel,Build,Default
Properties=AbbrModel

;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
; BEGIN MACADDRESS SECTION
; This is my Windows 10 v1511 build VM
[00:15:5D:13:79:01]
SkipTaskSequence=YES
TaskSequenceID=B151164ENT
SkipComputerName=YES
SkipDomainMembership=YES
JoinWorkgroup=BLD-WrkGrp
SkipUserData=YES
SkipComputerBackup=YES
SkipProductKey=YES
SkipLocaleSelection=YES
SkipTimeZone=YES
SkipAdminPassword=YES
SkipCapture=YES
SkipBitLocker=YES
SkipSummary=YES
; END MACADDRESS SECTION
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
; BEGIN GETABBRMODEL SECTION
; Lets get the abbreviated model
[GetAbbrModel]
UserExit=jgp_GetAbbrModel.vbs
AbbrModel=#GetAbbrModel#
; END GETABBRMODEL SECTION
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
; BEGIN BUILD SECTION
; Set things here for use below
[Build]
OSDComputerName=%OfficeCode%-%AbbrModel%-#UCase(Right(Replace(Replace("0000000%SERIALNUMBER%"," ","",1,-1,1),"-","",1,-1,1),8))#
; END GETABBRMODEL SECTION
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
; BEGIN DEFAULT SECTION
[Default]
OSInstall=Y
SkipTaskSequence=NO
SkipComputerName=NO
SkipDomainMembership=NO
SkipUserData=NO
SkipComputerBackup=NO
SkipProductKey=NO
SkipLocaleSelection=NO
SkipTimeZone=NO
SkipAdminPassword=NO
SkipCapture=NO
SkipBitLocker=NO
KeyboardLocale=en-US
UserLocale=en-US
UILanguage=en-US
; https://msdn.microsoft.com/en-us/library/ms912391(v=winembedded.11).aspx
TimeZoneName=Eastern Standard Time
SLShare=%DeployRoot%\TSLogs
SLShareDynamicLogging=%DeployRoot%\TSLogs\%OSDComputerName%
; END DEFAULTSECTION
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Following the methods outlined in the recommended reading section, set up an area for testing your CustomSettings.ini.  When I execute my test, it runs, I see a bunch of data:

There are no obvious errors, I see see some custom properties and various built-in properties getting set so it looks good.  Time to execute for real!

Troubleshooting – Part 1

Troubleshooting MDT (and SCCM) is something of an art and this is not a once-size-fits-all silver bullet post.

I ran across this post SCCM 2012 – How to catch errors in Task Sequence around the same time I started using MDT and found it greatly helped me to hone in on OSD issues.  Because it has worked well for me, I’m recommending it – and others like it – to you.

Task Sequence Setup

Take a look at the links at the top to see how others are setting up their Task Sequences and adjust to suit your needs but here’s a basic example:

Troubleshoot-041.PNG

Right now when your Task Sequence fails you see this dialog:

Troubleshoot-042.PNG

This dialog is incredibly helpful without making any adjustments and you should ge able to get an idea as to what went wrong without having to go super deep into the logs.  But once you get into a production scenario, you’ll likely suppress this dialog and I find that having the Try/Catch steps in the Task Sequence makes it easier from a log reviewing perspective, especially after the Task Sequence gets busy.

Crack open the smsts.log and immediately you see red:

Troubleshoot-043.PNG

With the Try/Catch model you can easily hone in on the offending step:

  1. Scroll to the bottom of the log
  2. Search for key text in the log
    • Option 1: Search for: Try) ignored
    • Option 2: Search for: Catch) has been

Either one will get you just a few short lines away from the failure, so scroll up a bit and it should become apparent.

Troubleshoot-044.PNG

  • The blue line above is the ‘Catch) has been‘ match.
  • The first red line above that is the ‘Try) ignored‘ line
  • Just above that we see the second red line which is the actual failure:
    Failed to run the action: This will break it.
  • Above that are the details for that specific step.

This is obviously a very simple example, but the process is the same for all errors:

  • Review the smsts.log
  • Find the actual error
  • Evaluate if it’s a problem specific to that step OR if it was caused by an environmental issue such as dependencies.
  • Review other logs as necessary based on what you’re seeing in the smsts (e.g.: domain join failure)

In Closing

I don’t expect you to be an expert at this point, but I hope it and the links in the recommended reading section have helped to get you a little more comfortable with searching the smsts.log for errors.

When doing BnC’s I like to keep my changes small and modular:

  • Test that the basic BnC works fine: OS is installed, sysprep & capture is succesful
  • Add Windows Updates into the mix & repeat the test
  • Prepare your application payload:
    • for some complex applications you’ll rely on scripts so test them outside of the Task Sequence to confirm they are syntactically correct
    • for simple installations make sure you have the correct command line arguments
    • once installed validate the installation & configuration
  • Introduce applications a few at a time doing BnC’s to ensure nothing is broken.
  • Set milestones for yourself so you don’t have to go back to square one
  • Backup files (ts.xml, unattend.xml, scripts etc) before you make any changes.

Good Providence to you!

MDT Tutorial Part 9: Logging

Living Table of Contents

Today’s Agenda:

  • Centralized Logging
  • Enable Logging
  • Log Locations

At some point you’re going to run into a problem with your imaging process and knowing where to look to get some answers is going to be paramount.

Recommended Reading:

Centralized Logging

I prefer to keep logs in a central location so they’re easy to find when needed, and for that, we’ll create a new share on our MDT server.  Run the below from the MDT server.


New-Item -Path "C:\DeploymentShare\TSLogs" -ItemType directory

New-SmbShare -Name "TSLogs$" -Path "C:\DeploymentShare\TSLogs" -FullAccess Administrators

Enable Logging

Open your CustomSettings.ini and find a suitable place to add the entries for SLShare and SLShareDynamicLogging depending on your preferred scenario.  Either is fine, just depends on your preference and environment.

Hard Coded Path


SLShare=\\MDTServer\TSLogs$

SLShareDynamicLogging=\\MDTServer\TSLogs$

Relative Path


SLShare=%DeployRoot%\TSLogs

SLShareDynamicLogging=%DeployRoot%\TSLogs

Set Logging via Task Sequence

Alternatively you could add steps to the Task Sequence itself to set those variables to their appropriate values, be it hard coded or relative.

Logging-001

Get Creative!

You can get pretty creative, and for automated deployments, I usually default to something like this:


SLShare=%DeployRoot%\TSLogs\%TaskSequenceID%

SLShareDynamicLogging=%DeployRoot%\TSLogs\%TaskSequenceID%\%OSDComputerName%

This way I can see what Task Sequence a particular machine ran.
But, to each their own.

SLShare vs SLShareDynamicLogging

Both values do different things:

  • When the SLShare property is set, MDT will copy the deployment logs to that location in a directory named after the computer, pulled from the %OSDComputerName% Task Sequence property (aka variable).  So if you named your machine PC-1511amd64 the full path to find the logs will be \\MDTServer\TSLogs$\PC-1511amd64.
    .
  • The SLShareDynamicLogging property is used for real-time debugging as ALL MDT logs will be written to that file during the Task Sequence.  It will create a file named BDD.log in the specified directory which means if you set SLShareDynamicLogging it to \\MDTServer\Logs you’ll find a file named BDD.log in that directory.  This obviously presents a problem if multiple machines are being imaged at the same time: they’d all be logged in the same file which might make it challenging to follow along.  This is why I recommend appending \%OSDComputerName% to the path so that the BDD.log is in the ‘correct’ directory.
    For our purposes, you can leave this property enabled, but please note this enabling SLShareDynamicLogging does add a bit of overhead, so in a production environment:

    • Only enable it when actually actively troubleshooting an issue and
    • Ideally have it log to a location close to the machine being imaged versus a remote server to avoid traversing the WAN

Putting It All Together

With the CustomSettings.ini updated, image a machine and check your log directory for a folder structure:

Logging002

  • The %OSDComputerName% directory is an artifact caused by the fact that the property (or variable) OSDComputerName wasn’t set at the time the SLShareDynamicLogging property was processed in the CustomSettings.ini.  In my production environment, I have logic in the CustomSettings.ini to properly name the machine based on specific criteria so that by the time we get to the area where SLShareDynamicLogging is assigned, the OSDComputerName property (aka variable) is set resulting in properly named directories.  However in our lab, this logic doesn’t exist (yet), hence why that directory exists.  To fix this, just add something like OSDComputerName=LAB-%SerialNumber% to your CustomSettings.ini and please note that the OSDComputerName property (variable) does not need to be declared.
    .
  • The other directory is the correct directory and it contains the BDD.log that’s actively being updated.

While a machine is imaging, open the BDD.log (in the latter directory mentioned above) with CMTrace from your MDTServer (or whatever machine you’re working on) and you will see live updates:

Logging-003

When the Task Sequence is finished go back into the log directory for that machine and you will to find the logs that were copied up by MDT:

Logging-004

Log Locations

MDT Logs can be a little challenging to locate initially so I recommend you study up those links mentioned in the recommended reading section above.

  • In WinPE & the disk is NOT partitioned:
    • X:\MININT\SMSOSD\OSDLOGS
      .
  • In WinPE & the disk IS partitioned:
    • C:\MININT\SMSOSD\OSDLOGS
    • X:\MININT\SMSOSD\OSDLOGS (very small amount)
      .
  • In WinPE & Task Sequence is running
    • smsts.log will be in X:\Windows\Temp\SMSTSLog
    • All other logs will be in their respective directories mentioned above
      .
  • In Windows & Task Sequence is running
    • smsts.log will be in C:\Users\Administrator\AppData\Local\Temp\SMSTSLog
    • C:\MININT\SMSOSD\OSDLOGS

Keep in mind there are other non-MDT logs you’ll probably need to review that are not listed here.

In Closing

You now have some historical data to dig into if something goes wrong, which will hopefully be few & far in between!

Good Providence to you!

MDT Tutorial Part 8: Unattend.xml

Living Table of Contents

Today’s Agenda:

  • View Unattend.xml
  • Generate Catalog
  • Edit Unattend.xml

Recommended Reading

View Unattend.xml

The unattend.xml lives in subdirectory named after your Task Sequence ID that sits in the Control directory of your Deployment Share.  For example, if your Task Sequence ID is BC151164ENT then you can find the unattend.xml in either:

  • C:\DeploymentShare\Control\BC151164ENT
  • \\MDTServer\DeploymentShare$\Control\BC151164ENT

You can edit it using your favorite text editor, but I recommend using the Windows System Image Manager (SIM).

  1. Edit your Task Sequence
  2. Go to the OS Info tab
  3. Click the Edit Unattend.xml button
  4. Go make a pizza

Generate Catalog

Doing the above will require you to generate a catalog file for the WIM you imported.  Fortunately this process happens automatically.

Unattend-003

Unfortunately this process can take a while depending on your configuration.

Once the generation is complete, you’re free to make changes to your Unattend.xml.

Also, you may want to pre-generate catalogs in a separate SIM session since it takes a while:

Unattend-010

Edit Unattend.xml

Typically my first step is to run the Validation check to see what the SIM isn’t happy about.

Unattend-011

Double click on any results to be taken right to that setting to remediate any issues.

  1. For the first four in the screenshot above, I simply revert the change by secondary mouse-clicking on the setting and selecting that option.
    .
  2. For the NetworkLocation warning, I typically leave it as-is & ignore warning.  Even though it’s officially deprecated, it still seems to work but for how long is anyone’s guess.

Since we’re already in amd64_Microsoft-Windows-Shell-Setup__neutral/OOBE, why don’t we set ProtectYourPC to 3.

Make any other necessary changes, verify the answer file, save and exit.

In Closing

You can do a lot in the unattend.xml but since I’m prone to forgetting  🙂  I try to add just the bare minimum and put the rest in a Task Sequence; It’s much easier to manage/maintain that way but there are legitimate reasons to put something in the unattend.  Do what works for you.

Good Providence to you!

MDT Tutorial Part 7: Customizing Base MDT Template & ADK WinPE Template WIM

Living Table of Contents

Totally Optional NOT Required!

Nothing in this post is required for following along.  It’s merely here to make you aware that this level of customization is possible.  Think of this as an extension of Part 6.

Customizing the MDT Template

When you create a new Deployment Share a set of files and folders are populated in the desired location.  This isn’t generated on the fly from thin air but rather pulled from a template which can be found here:


C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution

If for whatever reason you find yourself constantly creating deployment shares, you can modify this template to include your customizations:

  • Pre-configured CustomSettings.ini
  • Pre-configured Bootstrap.ini
  • Modifications to out-of-box scripts
    • This is a no no to be honest so I recommend avoiding that at all costs.
      If you must, make sure you backup the original file(s).
  • Including your own custom scripts

A good example of this would be making sure that DaRT was an option for any newly created deployment shares.  To do that, add the appropriate architecture DaRT .CABs into the appropriate directories below


C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64

C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x86

Once you make your changes to the ‘template’, create a new Deployment Share and you’ll see all of your customizations.

Note: Although you could include a pre-built bootable .ISO, it’s not ideal as it would be hard-coded to look at DeploymentShareA not NewDeploymentShareB requiring you to update the deployment share anyway.

Customizing WinPE Templates

Similarly you can also customize the base WinPE .WIM file by editing the winpe.wim file here:


C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us

C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\en-us

Make a copy of the existing .WIM file


Copy-Item -Path "${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim" -Destination "${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim.orig"

Create a temporary mount directory & mount the .WIM


New-Item -Path "$env:SystemDrive\tmpDISMMount" -Type Directory

dism /mount-wim /wimfile:"${env:ProgramFiles(x86)}\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim" /index:1 /mountdir:$env:SystemDrive\tmpDISMMount

Make your changes to the mounted .WIM


Copy-Item -Path "\\MDTServer\DeploymentShare$\Boot\ExtraFiles\amd64" -Destination "$env:SystemDrive\tmpDISMMount" -Recurse

Commit the changes


dism /Commit-Wim /MountDir:$env:SystemDrive\tmpDISMMount

Unmount the .WIM


dism /Unmount-Wim /MountDir:C:\test\offline /commit

Repeat for the x86 architecture

Why Should I Even Bother?

Paraphrasing Stephen Owen of FoxDeploy.com: TO solve the REAL problems!  By now, you’ve probably had to use CMTrace in WinPE a few times, and each time you launch it, you have to answer that ridiculous question:

Do you want to make this program the default viewer for log files?

Mike Terrill posted some very easy to follow instructions on his site, to solve this problem that has plagued many of us.

The process is fairly easy, and I altered Mike’s instructions for the MDT audience.

  1. Create DISM Mount Directory like:
    mkdir C:\tmpDISMMount
  2. Mount your winpe.wim from an elevated command prompt:
    dism /mount-wim /wimfile:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim" /index:1 /mountdir:C:\tmpDISMMount
  3. Load the DEFAULT registry hive from the WinPE image:
    reg load HKU\winpe C:\tmpDISMMount\Windows\System32\config\default
  4. Create the entries needed to suppress that annoying pop up box:
    reg add HKU\winpe\Software\Classes\.lo_ /ve /d Log.File /f
    reg add HKU\winpe\Software\Classes\.log /ve /d Log.File /f
    reg add HKU\winpe\Software\Classes\Log.File\shell\open\command /ve /d "\"X:\Windows\System32\CMTrace.exe\" \"%1\"" /f
  5. Unload the WinPE registry hive:
    reg unload HKU\winpe
  6. Unmount the WIM file and commit the changes:
    dism /unmount-wim /mountdir:C:\tmpDISMMount /commit
  7. Repeat the process with the x86 media in “C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\en-us\winpe.wim”

In Closing

This is a good little nugget to keep in mind.  Is this everything you can do?  No, just scratching the surface.  Remember, the objective of this tutorial is to just help you get started and get those creative juice flowing.

Just remember that every time a new MDT build or ADK is released, you’ll have to re-do these customizations for the new environment.  I’d recommend creating a script to do these customizations for you and keep good notes in the script to justify why you did it so you can easily ‘rebuild’ in the future.  But before you do anything, jump on Twitter or the TechNet forums to seek guidance; chances are someone else has already overcome the challenge you’re facing so there’s no need to recreate the wheel.

While you decide whether or not you want to do this, I bid you Good Providence!

MDT Tutorial Part 6: Customizing Boot Media

Living Table of Contents

Today’s Agenda:

  • Adding Files to Boot Media
  • Adding a Cool/Corporate Background
  • Adding Features to Boot Media

Although you can deploy an image with this boot media and so some basic tasks, we can add some additional, and very useful, functionality with ease.

Adding Files to Boot Media

In Part 5 we verified the changes we made to the Bootstrap.ini by not only experiencing it, as in the case of missing authentication prompt and the text customization, but also by viewing the BDD.log in notepad.  For most people that log might as well have looked like this:

If I said it would get easier with a little practice I wouldn’t be lying, but fortunately for us we can have access to a log viewer that’ll make the log viewing process a breeze.

To start, I recommend creating a folder structure to store all the files you want to add and I strongly urge you to separate between architectures.

If you’re remote:

mkdir \\MDTServer\DeploymentShare$\Boot\ExtraFiles\x64\Windows\System32
mkdir \\MDTServer\DeploymentShare$\Boot\ExtraFiles\x86\Windows\System32

If you’re on the MDT Server:

mkdir C:\DeploymentShare\Boot\ExtraFiles\x64\Windows\System32
mkdir C:\DeploymentShare\Boot\ExtraFiles\x86\Windows\System32

The reason is that the 64-bit WinPE media can only run 64-bit EXE’s and not 32-bit EXE’s.  Attempting to run a 32-bit EXE will result in an error similar to the following:

AddFiles-001

Be mindful of that when you select the files you want to bake into your boot media so you’re not bitten by the “Bitness Bug”!  Also, don’t go crazy because the more files you add, the larger the boot media.  Add just enough so you have what you need, not what you might need.

So just carve out the folder structure you want and drop the files wherever you need them to be.

CMTrace

These days CMTrace is the default go-to log viewer and is available publically:

  1. System Center 2012 R2 Configuration Manager Toolkit
  2. SCCM Evaluation ISO in
    1. SMSSETUP\TOOLS directory
    2. SMSSETUP\OSD\bin\I386
    3. SMSSETUP\OSD\bin\x64

However, as pointed out by Johan Arwidmark although the tool is ‘freely available’ it is not free as the EULA licensing states:

INSTALLATION AND USE RIGHTS. You may install and use any number of copies of the software on your devices running validly licensed copies of Microsoft System Center 2012 or later.

While disappointing, it is free to use during your evaluation.  So to quote Cathy Moya:

For anyone just using MDT, hey, install the eval copy and see what you’re missing with Config Manager. 🙂

That said once you have your eval setup you can move on with grabbing the EXE.  It’s probably easiest to grab it from the SCCM Evaluation ISO in the SMSSETUP\OSD\bin directories: I386 for x86 or 32-bit version and x64 for the 64-bit version.  If you’re using the toolkit hower:

  1. Download the MSI
  2. Run the installer (or perform an administrative installation)
  3. Copy the CMTrace.exe in the ClientTools folder
  4. Paste it in \\MDTServer\DeploymentShare$\Boot\ExtraFiles\x86\Windows\System32

This nets you the 32-bit version of CMTrace which is good for 32-bit boot media, but what about the 64-bit executable?  If you’re on a 64-bit machine you can:

  1. Run the CMTrace.exe in the ClientTools folder
  2. Open Task Manager
  3. Go to the Processes tab
  4. Sort by Apps and look for CMTrace_amd64.exe
  5. Secondary mouse click it and select ‘Open file location
  6. It will take you to %Temp% and point you to a file named TRAXXXX.tmp where XXXX are four random characters like 9644 or 1CD7.
  7. Copy the file, for example, TRA9644.tmp
  8. Paste it in \\MDTServer\DeploymentShare$\Boot\ExtraFiles\x64\Windows\System32
  9. Rename TRA9644.tmp to CMTrace.exe

Note: The above step works on Windows 10 and Server 2016; should work on Windows 8 and Server 2012 R2; if not use Process Explorer (or Process Monitor) to figure out where it’s running from.

Open the Deployment Workbench, go to your Deployment Share properties and click on the ‘Windows PE’ tab which will take you to the ‘General’ subtab.  Near the bottom look for ‘Extra directory to add’ next to an empty field where you can point to a location that contains the extra files you wish to add.  Type or browse to the path you created above and click Apply.

AddFiles-002.PNG

Once you finish with x86, at the top of the properties window just under the ‘Windows PE’ tab is a ‘Platform’ drop down.  Click it, select x64 and repeat your change there as well.

Adding a Cool/Corporate Background

While you’re on Extra Files tab, let’s add a Cool/Corporate background to the media!
This is totally optional but many do find it useful.

On the same ‘General’ subtab of the ‘Windows PE’ tab of the Deployment Share properties is a ‘Custom background bitmap file’ field that’s already filled in.  Just substitute that bitmap with one of your own.

AddBackground-001.PNG

Remember to also add the image to your x64 boot media via the ‘Platform’ drop down!

Adding Features to Boot Media

The WinPE boot media is lacking some key features we’re going to want to use so we need to fix that by adding some Optional Components.

Up until now we’ve been working in the ‘General’ subtab of the ‘Windows PE’ tab of the Deployment Share properties and we’re now going to move to the ‘Features’ subtab under the same ‘Windows PE’ tab.

AddFeatures-001

The Features available in this list are pulled from supported .CABs in

  • C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs
  • C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\WinPE_OCs
  • C:\DeploymentShare\Tools\x64
  • C:\DeploymentShare\Tools\x86

Just like before when adding files, add only what you need, and I recommend:

Software Assurance Subscribers Only

If you have an active SA subscription you can download MDOP and add DaRT to your boot media.

  1. Download the MDOP ISO
  2. Mount the ISO
  3. Go into the DaRT\DaRT 10\Installers\Language (e.g.: en-us)
  4. Go into the appropriate architecture subfolder and run the MSI (or perform an administrative installation)
  5. Go into C:\Program Files\Microsoft DaRT\v10
  6. Copy the two Tools .CAB files and place them into the appropriate architecture directory in C:\DeploymentShare\Tools (i.e.: Toolsx64.cab into C:\DeploymentShare\Tools\x64)
  7. Go back to the ‘Windows PE’ tab of your your Deployment Share properties
  8. Go into the ‘Features’ subtab and check ‘Microsoft Diagnostics and Recovery Toolkit (DaRT)’
  9. Repeat for the x64 platform

Updating Boot Media

Once you’ve finished customizing your boot media, it’s time to update the boot media, so whip out your PowerShell code you pulled from before and run it in an elevated PowerShell console or PowerShell ISE.


Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"
New-PSDrive -Name "DS001" -PSProvider MDTProvider -Root "C:\DeploymentShare"
update-MDTDeploymentShare -path "DS001:" -Verbose

From there, boot your updated ISO and you will see all of your changes:

UpdateBootMedia-001.PNG

  1. PowerShell is present
  2. Storage cmdlets present
  3. CMTrace is present
  4. Cool Background
  5. SA Subscribers: DaRT is present

In Closing

You now have feature rich bootable media that you can leverage to your advantage for various tasks related to OSD.

Good Providence to you!

MDT Tutorial Part 5: Bootstrap.ini

Living Table of Contents

Today’s Agenda:

  • Bootstrap.ini Overview
  • Facilitating Authentication
  • Skipping the Welcome Screen
  • Putting it All Together

Recommended Reading

Bootstrap.ini Overview

The BootStrap.ini is similar to the CustomSettings.ini in that the format, structure and processing logic is the same.  The major difference is mainly that the Bootstrap.ini is processed first and once when you boot into WinPE.  The CustomSettings.ini on the other hand is processed after the Welcome screen and at various points during the Task Sequence.

Just like the CustomSettings.ini, the Bootstrap.ini is accessible two ways:

  1. Via the ‘Edit Bootstrap.ini’ button on the ‘Rules’ tab of the Deployment Share properties.
  2. Via the Bootstrap.ini in the Control subdirectory of your Deployment Share, for example:
    1. C:\DeploymentShare\Control
    2. \\MDTServer\DeploymentShare$\Control

Currently your Bootstrap.ini is more bare bones than your CustomSettings.ini:


[Settings]
Priority=Default

[Default]
DeployRoot=\\ITF1MDT01\DeploymentShare$

Unlike the CustomSettings.ini however, when you make changes to your Bootstrap.ini, the changes are not ‘live’ immediately:  Because the Bootstrap.ini is baked into your boot media – hence its ability to be processed when WinPE loads – anytime you update your Bootstrap.ini you must update your Deployment Share to generate new media that contains your updated Bootstrap.ini.  Because of this, you probably want to keep edits to this file to a minimum, adding just the essentials to get you connected to the Deployment Share.

According to the documentation, there are only a handful of properties configured by Bootstrap.ini; so few I’ll include them here for reference:

_SMSTSOrgName Database DBID
DBPwd DeployRoot DestinationDisk
DestinationLogicalDrive DestinationPartition Instance
KeyboardLocale KeyboardLocalePE Location
NetLib Order Parameters
ParameterCondition Port Priority
Properties ResourceRoot Role
SkipBDDWelcome SQLServer SQLShare
StoredProcedure Table UserDomain
UserID UserPassword

However that same document doesn’t state you can use the ‘DefaultGateway’ in the Bootstrap.ini which is a completely valid configuration, so I’ll assume the documentation is dated or it was an oversight.

It’s also been said that you can customize the Bootstrap.ini to nearly the same degree as the CustomSettings.ini.  I personally have not done this so I can’t validate that (e.g.: will User Exit scripts work etc.) but since the documentation is clearly not complete, I also refute it either.  So yes, you can create new sections and custom properties but I will say this: Because edits to the Bootstrap.ini require rebuilding the media each time a change is made, I personally prefer to to keep it simple with the most static information possible.

Facilitating Authentication

The first thing I typically do is rid myself of that dreadful authentication prompt that appears after clicking the ‘Run the Deployment Wizard…’ button:

SBTS-002

And I accomplish that by adding the UserID, UserPassword and UserDomain properties to the Bootstrap.ini:


[Settings]
Priority=Default

[Default]
DeployRoot=\\ITF1MDT01\DeploymentShare$
UserID=Administrator
UserPassword=my sekret 1337 Cyph3r!
UserDomain=ITF1MDT01

The documentation states:

For a completely automated LTI deployment, provide this property in both CustomSettings.ini and BootStrap.ini.  However, note that storing the user credentials in these files stores the credentials in clear text and therefore is not secure.

This is an important thing to remember when setting this up and a documented risk for the security team.  Leading practice would be to use a dedicated MDT account with limited rights (like execute) to the Deployment Share and write access to the ‘Captures’ directory.  I would advise against using a privileged account, be it local to the ‘MDT Server’ or the a domain account.

Skipping the Welcome Screen

If you’re not a big fan of this screen:

SBTS-001

You can suppress it by adding the SkipBDDWelcome property and setting it to YES to the Bootstrap.ini.


[Settings]
Priority=Default

[Default]
DeployRoot=\\ITF1MDT01\DeploymentShare$
UserID=Administrator
UserPassword=my sekret 1337 Cyph3r!
UserDomain=ITF1MDT01
SkipBDDWelcome=YES

To undo, set it to NO or comment the code by placing a semicolon in front of it like ;SkipBDDWelcome=YES.

The documentation states:

For this property to function properly, it must be configured in both CustomSettings.ini and BootStrap.ini. BootStrap.ini is processed before a deployment share (which contains CustomSettings.ini) has been selected.

I’ll tell you that I don’t always add it to my CustomSetting.ini and yet the Welcome screen is been suppressed for every build and build & capture with that configuration.  Again, this could be a change in MDT behavior that wasn’t reflected in the documentation but I always recommend following the documentation.

Putting It All Together

Ok so now you’ve got the hang of it, let’s make some changes common to many environments.  Comments added to emphasize certain elements.


[Settings]
Priority=Init,DefaultGateway,BootStrapSection,Default
Properties=Office,MyBootStrapProperty

[Init]
DeployRoot=\\DFS\Namespace\DeploymentShare$
;SkipBDDWelcome=YES

[DefaultGateway]
; Put your real gateway for HQ
10.0.1.1=HQ
10.10.1.1=DC

[HQ]
; HQ is your current environment so put real information here
Office=HQ
; Point this to the real Deployment Share you setup
DeployRoot=\\ITF1MDT01\DeploymentShare$
; Use real credentials to connect to the above share
UserID=svc_ImagingAccount
UserPassword=Tr0ub4dor&3
UserDomain=ITF1MDT01

[DC]
; This is a fake location for illustration purposes
; But you could be in an environment with multiple Deployment Shares
Office=DC
DeployRoot=\\DCServer\DeploymentShare$
UserID=lclMDTUser
UserPassword=Correct Horse Battery St4pl3!
UserDomain=DCServer
SkipBDDWelcome=NO

[BootStrapSection]
MyBootStrapProperty=THIS IS MY BOOTSTRAP PROPERTY
_SMSTSOrgName=MDT Lab@%Office%

[Default]
SkipBDDWelcome=YES
; This is fake information because I set the real information above
; Again purely for illustration purposes
UserID=MDTAccount
UserPassword=my sekret 1337 Cyph3r!
UserDomain=DOMAIN.FQDN

And here’s how it’s going to be processed:

  1. [Init] Section – This is the ‘Init’ section where I can set some default settings.  This isn’t required and you may or may not need something like this; just know that you can do something like this.
    1. DeployRoot is set to \\DFS\Namespace\DeploymentShare$
      This would be a catch-all default for offices that don’t have a separate Deployment Share.  In this scenario, if someone’s gateway was 10.20.20.1 they would default to this Deployment Share because there’s no rule below for that particular gateway.
      .
    2. SkipBDDWelcome was initially set to YES at some point but commented out because technicians in some offices wanted to use the other options on the Welcome screen.
      SkipBDDWelcome, like most MDT properties, is a write-once property so if we set it to ‘YES’ in [Init] we can’t alter it later.  Better to leave it alone to allow offices to customize it to their liking.
      .
  2. [DefaultGateway] Section
    1. 10.0.1.1 – If the default gateway matches this, it will go to the [HQ] section
      1. [HQ] Section
        1. We set a new property called Office to HQ.
          This could be useful for a variety of things like naming computers based on location
        2. The DeployRoot is set to \\ITF1MDT01\DeploymentShare$.
          DeployRoot is one of 9 properties that are re-writable out of the box so I can set this as many times as I need to.
        3. UserID is the username we’re going to use to connect to the above Deployment Share, in DeployRoot.  We have to do this because they’re smart and not using common username & password like other offices.
        4. UserPassword is the password for the above user
        5. UserDomain is the domain we’re authenticating against, in this case the DCServer.
        6. SkipBDDWelcome is set to NO because this office prefers to see the screen.
          .adsasdasd..
    2. 10.10.1.1 – If the default gateway matches this, it will go to the [DC] section.
      1. [DC] Section
        1. We set a new property called Office to DC.
        2. The DeployRoot is updated to point to a local Deployment Share in that office.
        3. UserID is the username we’re going to use to connect to the above Deployment Share, in DeployRoot.  We have to do this because they’re smart and not using common username & password like other offices.
        4. UserPassword is the password for the above user
        5. UserDomain is the domain we’re authenticating against, in this case the DCServer.
        6. SkipBDDWelcome is set to NO because this office prefers to see the screen.
          .
  3. [BootStrapSection] Section – An arbitrary section I created just because I can
    1. A new property called MyBootStrapProperty is set to ‘THIS IS MY BOOTSTRAP PROPERTY” – again purely to show that it can be done.
    2. The _SMSTSOrgName property is set and it references the Office code set further up.
      .
  4. ​​[Default] Section
    1. SkipBDDWelcome is set to YES because most offices don’t want to see it.
      If it’s not already set, it will get set to YES.
    2. UserID is the username we’re going to use to authenticate to the default Deployment Share, held in property DeployRoot, that we set in the [Init] section.
    3. UserPassword is the password for the above username
    4. UserDomain is the domain we’re authenticating against.

The proof is in the pudding:

  • After making the changes to the Bootstrap.ini, update your Deployment Share to create new media
  • Boot your new media
  • You will no longer see the Welcome screen
  • You will no longer receive an authentication prompt
  • You will be taken directly to the Task Sequence page
  • If you run a Task Sequence (build or build & capture) you’ll see the updated text in the progress bar area:
    • Bootstrap-002

I recommend opening the BDD.log file to review the processing, but this is something we haven’t touched on yet so brace yourself.

While in WinPE – say when you’re looking at the Task Sequence list – press F8 on your keyboard to open a command prompt which is unequivocally indispensable when it comes to troubleshooting!  Please note that on some laptops you may need to press the Function (Fn) key and F8 simultaneously to get this to work.  This isn’t an MDT problem but a hardware specific issue.

Bootstrap-003

In the command window just type notepad hit return and notepad will open.  From there you can go to File > Open & browse to find the BDD.log, which is in one of two locations depending on the state of the hard drive of the machine you’re testing:

  • Drive has NOT been partitioned:
    The BDD.log – and others – can be found in X:\MININT\SMSOSD\OSDLOGS
    .
  • Drive HAS been partitioned:
    The BDD.log – and others can be found in C:\MININT\SMSOSD\OSDLOGS

This slideshow requires JavaScript.

Once you navigate to that location, you won’t see anything because of the default ‘Files of type’ filter in notepad.  Change the drop down from ‘Text documents (*.txt)’ to ‘All Files’ and like magic a bunch of files will appear.  Now open the BDD.log

MDT generated logs are a little difficult to navigate in notepad but this is the kind of thing that really builds character.  In the log, search (CTRL+F) for one of the properties you set, like _SMSTSOrg or ‘MDT Lab@’ and you should find what you’re looking for it pretty quickly.

Below is my marked up version of the BDD.log highlighting the custom properties, the order of operations (Rule Priority) as well as the sections it processed; between each you’ll find log entries for the actions performed, like setting Properties (aka variables) like UserID, MyBootstrapProperty etc.

Bootstrap-001

As you can see, everything was processed accordingly and set correctly.

In Closing

This Bootstrap.ini example is a little complex only because it accounts for possible real world scenarios: Office specific configuration, Multiple Deployment Shares (aka DeployRoot), Different Credentials for each Deployment Share, customizing the progress bar with your branding/corporate information and so on.

For your lab environment, you really just need a bare bones config like this:


[Settings]
Priority=Default

[Default]
; Customize this to your liking
_SMSTSOrgName=My Custom MDT Lab
; Point this to the real Deployment Share you setup
DeployRoot=\\ITF1MDT01\DeploymentShare$
; Use real credentials to connect to the above share
UserID=svc_ImagingAccount
UserPassword=Tr0ub4dor&3
UserDomain=ITF1MDT01
; You might want to skip this but maybe not - your call
SkipBDDWelcome=YES

But at least you know how to handle those scenarios and scale up.

Good Providence to you!

MDT Tutorial Part 4: CustomSettings.ini

Living Table of Contents

Today’s Agenda:

  • CustomSettings.ini Overview

Recommended Reading

CustomSettings.ini

The CustomSettings.ini is a rules file processed by ZTIGather.wsf after the Bootstrap.ini is processed (more on that in my next post) as well as periodically during the Task Sequence.  The CustomSettings.ini contains instructions to perform specific actions and set various parameters in MDT.  You can great very creative when it comes to customizing the CustomSettings.ini, but that’s beyond the scope of this post.  Today I just want to focus on explaining what’s currently in your CustomSettings.ini to whet your appetite for getting this setup in your environment.

The CustomSettings.ini can be accessed two ways:

  1. In the ‘Rules’ tab of the Deployment Share properties
  2. The CustomSettings.ini file in the Control subdirectory of your Deployment Share, for example:
    1. C:\DeploymentShare\Control
    2. \\MDTServer\DeploymentShare$\Control

At the moment your current CustomSettings.ini it pretty bare bones


[Settings]
Priority=Default
Properties=MyCustomProperty

[Default]
OSInstall=Y
SkipCapture=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=NO
SkipBitLocker=NO

I want to start by pointing out that everything in the [Default] section is set to ‘NO’ except for ‘SkipAdminPassword’ and ‘SkipProductKey’.  If you recall when we created the first Deployment Share, we saw the screen below:

NDS-004

Everything was checked except for ‘Ask for a product key’ and ‘Ask to set the local Administrator password’ which if you can guess corresponds to what we’re seeing in the CustomSettings.ini.

The OSInstall property is provided out of the box and I suppose it’s meant to tip the MDT Admin that you can set it to N if need be.  It’s important to note that this property is not required, and if it’s missing an OS installation will proceed by default.  So don’t go thinking that by deleting that you’re going to prevent OS’ from installing.

Another baked in property is MyCustomProperty which has no references anywhere.  This is really just to let the MDT Admin know that this is where they can declare properties (like declaring variables) for use in the CustomSetitngs.ini and thus the MDT environment.  We’ll get into that more a little later but just know that you can delete ‘MyCustomProperty’ – and in fact that whole line – and things would work fine.

At the moment there are two Sections – the square bracket surrounded text – in your CustomSettings.ini:

  1. Settings
  2. Default

And the rest are properties, or variables, that we’ll explore further.

The [Settings] Section

The settings section holds just two properties

  • Prioroty
  • Properties

Priority

The Priority property is a reserved property used for determining the order in which sections within the CustomSettings.ini will process items.  I like to think of Priority as a listing of declared Functions I want to call in a specific order when the CustomSettings.ini is processed, and each of these functions do something.  Let’s go over some basic real-world examples to help explain.

Say your CustomSettings.ini looked like this:


[Settings]
Priority=MACAddress,Default

[00:11:22:33:44:55]
SkipAdminPassword=NO

[00:11:22:33:44:56]
OSInstall=Y

[TestGroup]
SkipCapture=YES

[Default]
OSInstall=Y
SkipCapture=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=NO
SkipBitLocker=NO

When the CustomSettings.ini is processed it will read the Priority line to determine the order in which the sections need to be processed.

  1. MACAddress
  2. Default

The MACAddress directive is a special one that is built-into MDT that doesn’t look for a section called [MACAddress] but instead determines your machine’s MACAddress and looks for a section that matches your machine’s MAC Address, like [00:11:22:33:44:55].  If a matching section is found, it processes the properties in that section, which in this case is just SkipAdminPassword=NO.  When that’s done it’ll move into the [Default] section and process everything there and then it’s done.

But wait a minute, what about that third section called [TestGroup] with it’s own set of properties?  Well the [TestGroup] section would not be processed because it was not specified on the Priority line, so it’s ignored completely.

Let’s try another example: Suppose you wanted to add a section to do something special for machines using a particular default gateway IP address:


[Settings]
Priority=DefaultGateway,MACAddress,Default

[192.168.1.1]
SkipProductKey=NO
SkipAdminPassword=NO

[00:11:22:33:44:55]
OSInstall=N

[00:11:22:33:44:56]
OSInstall=Y

[TestGroup]
SkipCapture=YES

[Default]
OSInstall=Y
SkipCapture=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=NO
SkipBitLocker=NO

From a processing perspective this is the order:

  1. DefaultGateway
  2. MACAddress
  3. Default

Like MACAddress, DefaultGateway is a special directive that looks up the default gateway IP address of the machine in question.  In this scenario, any machines with a Default Gateway of 192.168.1.1 will always display the MDT screens that prompt for the product key and administrator password, which may seem a little odd considering in the [Default] section we’re suppressing them, which brings me to my next important point.

For most MDT properties, once it has been set, it becomes ‘read-only’ and won’t be changed again via processing of the CustomSettings.ini.  The ‘documentation’ calls these variables ‘first value wins’ but I usually refer to them as ‘write-once’.  This is very important because once an internal MDT property is set, say in Section A, it will not be altered in Section C even if it’s present with a different value.

However, there are some variables that are ‘last value wins’, meaning they can be overwritten multiple times, and I’m only aware of 9 that fit into this category:

  1. DeployRoot
  2. ResourceRoot
  3. DeployDrive
  4. ResourceDrive
  5. DeploymentMethod
  6. DeploymentType
  7. Phase
  8. DestinationDisk
  9. DestinationPartition

Can you override this behavior?  Yes, by editing the ZTIGather.xml, but I’d advise against it unless you know what you’re doing.  Plus by doing so you may not be in a supported configuration and Microsoft Support would probably ask you to undo your changes.

Properties

The Properties property is more like a variable declaration directive.  In the CustomSettings.ini you can’t just create lines for various properties all willy nilly:


[Settings]
Priority=DefaultGateway,MACAddress,Default
Properties=SkipWindowsUpdates

[192.168.1.1]
SkipProductKey=NO
SkipAdminPassword=NO

[00:11:22:33:44:55]
OSInstall=N

[00:11:22:33:44:56]
OSInstall=Y

[TestGroup]
SkipCapture=YES

[Default]
OSInstall=Y
SkipCapture=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=NO
SkipBitLocker=NO
SkipWindowsUpdates=YES
InstallOffice2016=YES

In the above example, I declared a new property (or variable) called SkipWindowsUpdates via the ‘Properties’ line.

In the [Default] section I added the new declared property, SkipWindowsUpdates, and set it to YES.

In the [Default] section I also added a property called InstallOffice2016 and set that to YES.

Unfortunately only the SkipWindowsUpdates property (or variable) is going to get picked up by MDT.  The InstallOffice2016 property is ignored because it’s not ‘declared’ in the Properties line in the [Settings] section.

Please note that SkipWindowsUpdates is NOT a built-in MDT property; I just made it up and that is why I had to ‘declare’ it.  Any custom properties you create must be declared – added to the Properties line under Settings – before you can use them.

The [Default] Section

There’s no special meaning behind the name ‘Default’ – it’s just the name of a section.  It could be called Chazwazza and it would work just as well.  But generally speaking the ‘Default’ section is the last section to be processed and that’s where you set all of the ‘Default’ settings not set in the sections above.

  • OSInstall=Y – Indicates an OS will be installed.
  • SkipCapture=NO – Indicates the Capture screen will NOT be suppressed and thus visible.
  • SkipAdminPassword=YES – Indicates the Password screen WILL be suppressed and thus NOT visible.
  • SkipProductKey=YES – Indicates the Product Key screen WILL be suppressed and thus NOT visible.
  • SkipComputerBackup=NO – Indicates the Computer Backup screen will NOT be suppressed and thus visible.  Please note that this is not a screen we’ve seen yet.
  • SkipBitLocker=NO – Indicates the BitLocker screen NOT be suppressed and thus visible.

You can completely change the ordering of the Default section or even have other sections execute after the Default section, provided you added (aka declared) it in the Priority line in the Settings section after Default.

Putting It All Together

Going back to our current stock CustomSettings.ini we’re going to alter some defaults just to show how it works and how it can streamline imaging.


[Settings]
Priority=Default
Properties=MyCustomProperty

[Default]
OSInstall=Y
SkipCapture=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=NO
SkipBitLocker=YES
SkipUserData=YES

Since we’re not looking to backup and/or restore anything, and we’re not enabling BitLocker, we can skip those screens altogether by setting SkipBitLocker to ‘YES’ and adding a new property called SkipUserData and setting that to ‘YES’.

When you make changes to the CustomSettings.ini, they’re live right then and there so just boot your media and go again.

  • If you’re already in WinPE at the Welcome screen, the one with the ‘Run the Deployment Wizard…‘ button, click it and it’ll process your updated CustomSettings.ini.
  • However if you’re already at the Task Sequence screen you’ll need to reboot since the CustomSettings.ini was processed before you made you changes.

Now when I boot into WinPE and image, I no longer see those respective screens.
Before, I had both ‘Move Data and Settings’ and ‘USer Data (Restore)’ steps:

SBTS-011

After making the change, those screens are gone altogether:

NoBLNoUD

If I wanted to bring back BitLocker screen, I could Set SkipBitLocker to ‘NO’ or commend the line by adding a semicolon in front like ;SkipBitLocker=YES

In case you’re wondering, I didn’t declare SkipUserData because it’s a built-in MDT property that I’m just toggling.  Please see the links under recommended reading above for more information on [many] built-in variables.

In Closing

We’re really only scratching the surface here at what we can do with the CustomSettings.ini.  You can do so much from here including calling a UserExit script which is a way for the CustomSettings.ini to call an external vbscript that will return a value which will get set as the property (or variable) value.

In the next post we’ll talk about the other .INI file, Bootstrap.ini and we’ll make some other adjustments to both files to make some things a little easier for us.

For now, I bid you Good Providence.

MDT Tutorial Part 3: Imaging

Living Table of Contents

Today’s agenda: Image All The Things!

  • Image a machine with the Build Task Sequence
  • Image a machine with the Build, Sysprep & Capture Task Sequence

Prerequisites

  • Copy the bootable ISOs from the Boot directory in the Deployment Share Share (e.g.: \\MDTServer01\DeploymentShare$\Boot) to your Hyper-V server
  • Add the ISO to your VM
  • Set the DVD Drive as the first boot device
  • Boot your VM
  • Press any key to boot the media.

Build Task Sequence

Once the WinPE environment loads, you’ll be greeted by this window.

SBTS-001

Click ‘Run the Deployment Wizard to install a new Operating System‘ and it will prompt you for credentials.  If you created a dedicated MDT account, good on you – use those.  In my lab (torn down & rebuilt regularly) I just use the local Administrator account.SBTS-003

Assuming you entered the proper credentials, you’ll see the available Task Sequences.
Choose the Task Sequence you created and click next.

SBTS-004

On the ‘Computer Details’ step feel free to enter in a computer name and workgroup name; Or don’t – that’s fine too.

SBTS-005

On the ‘Move Data and Settings’ step you can leave the default, ‘Do not move user data and settings.‘, since there’s nothing to backup/move.

SBTS-006

On the ‘User Data (Restore)’ step leave the default, ‘Do not restore user data and settings.‘ because there’s nothing to restore from.

SBTS-007

On the ‘Locale and Time’ step, adjust the settings accordingly.

SBTS-008

On the ‘Capture Image’ step you can leave the default, ‘Do not capture an image of this computer.‘  Right now we’re just looking to lay down the OS and the B&C will come later.

SBTS-009

On the ‘BitLocker’ step you can leave ‘Do not enable BitLocker for this computer.

SBTS-010

The ‘Ready’ step is really just a summary of the configuration you set above.
Give it a once over to make sure it’s correct and click begin.

SBTS-011

Will run, doing the steps listed in the Task Sequence.  I like to follow along with the VM on one side of the screen and the Task Sequence on the other to ensure things are executing as I expect.  A number of steps take place in WinPE, like laying down the WIM on the disk.

Afterwards the machine will reboot and boot into Windows

Eventually you’ll see the desktop and you might think ‘it’s done’ or that ‘it stalled’ and be tempted to start playing around with it but please don’t!

SBTS-022

Give it a minute and you’ll see the process continue.

 

After a sigh of relief it’ll move on and finish up very quickly after that.

SBTS-025

Mid Boss Battle Complete!

This is the halfway mark and if this goes smoothly the next step should be just as easy.

Build, Sysprep & Capture Task Sequence

If you didn’t already guess, the Build, Sysprep & Capture – or B&C for Build & Capture because it’s assumed you’re going to sysprep the machine since you don’t want to be in an unsupported situation – process is the same as the above.

  • Add the ISO to your B&C VM
  • Boot from the media
  • Click ‘Run the Deployment Wizard to install a new Operating System
  • Enter your authentication credentials

This time you want to select your B&C Task Sequence

Cap-001

The screens that follow are identical to what you had before, and for the most part everything is the same…

EXCEPT when you get to the ‘Capture Image’ step!
This time we are going to select ‘Capture an image of this reference computer.‘ so that we can capture an image of this machine.  You’re welcome to adjust the Location and File name but the defaults are fine for our purposes.

Cap-007

Again, review your configuration to ensure it’s correct before clicking ‘Begin’

Cap-008

For the most part, it’s exactly the same as before: A number of steps take place in WinPE before rebooting into the OS.

Once in the OS, MDT will start up again, finish up the normal tasks

This slideshow requires JavaScript.

Run sysprep

Cap-010

Stage the boot media

Cap-009

Reboot into WinPE

Cap-012

Initialize the WinPE environment

Cap-013

Capture the WIM

This slideshow requires JavaScript.

Display a summary when complete

Cap-017

A High Five is in Order: Your First B&C via MDT!

Seriously, this is a big deal so request the highest of fives from someone.

 

The Importance of MDT in a WaaS World

I do not like doing the same thing over and over again, and the idea of building a physical machine that I need to patch, load software onto and configure is not how I want to spend my day.  You can expect a feature update release for Windows 10 twice a year which means you could be asked to perform a B&C twice a year.

So instead of spending days:

  • installing Windows 10
  • thumbing through a 40 page build document
  • locating build change notes scattered across sticky notes scattered throughout desk and emails

I would much rather spend a few hours or a couple of days:

  • cataloguing the OS level configurations required for the organization
  • packaging applications & testing them to ensure they’re complete and work
  • putting it all together in scripts
  • loading all these into MDT

This way I can have reliable, repeatable process for building machines & capturing images.

I promise, once you get this going you’ll never look back.

Good Providence to you!

MDT Tutorial Part 2: Initial Configuration

Living Table of Contents

Today’s agenda is to focus on the basics so you can start imaging.

  • Creating a Deployment Share
  • Import an OS into MDT
  • Create a stock Build Task Sequence in MDT
  • Create a stock Build, Sysprep & Capture Task Sequence in MDT
  • Update the Deployment Share

MDT Workbench

The MDT Workbench is where all the action is: It’s where you add your Operating Systems, create & edit your Task Sequences, import your Drivers – basically everything you need to image.  Fire it up and you should see a wonderful blank canvas.

MDT-001

Create Deployment Share

Secondary mouse-click the top-level ‘Deployment Shares’ node and select the option to create a new Deployment Share.

Enter the desired location to create the Deployment Share.NDS-001

Enter a share name for the Deployment Share

NDS-002

Enter a name for your Deployment Share – how you want it to show up in the Deployment Workbench.

NDS-003

These are the default options – I left them as is just for the purposes of documenting the out-of-box experience.

NDS-004

Review the summary to confirm all is well

NDS-005

Within seconds your new Deployment Share will be created.

NDS-006

NDS-007

I want to highlight something really important: The View Script button that exists on just about every MDT screen.  It kicks out code for each action like Creating Deployment Shares, Importing Operating Systems, Updating Deployment Shares etc.

Behind the scenes, this is the underlying code used to create the Deployment Share


New-Item -Path "C:\DeploymentShare" -ItemType directory
New-SmbShare -Name "DeploymentShare$" -Path "C:\DeploymentShare" -FullAccess Administrators
Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"
new-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root "C:\DeploymentShare" -Description "MDT Deployment Share" -NetworkPath "\\ITF1MDT01\DeploymentShare$" -Verbose | add-MDTPersistentDrive -Verbose

If you’re new to MDT and PowerShell, this is going to help you turn things around fairly quickly.

Import OS into MDT

Expand the top-level ‘Deployment Shares’ node then expand your newly created ‘MDT Deployment Share’ node to reveal the ‘Operating Systems’ node.

Create a Stock ‘Build’ Task Sequence

Secondary mouse-click on the ‘Task Sequence’ node & select ‘New Task Sequence’

On the first screen enter a Task Sequence ID – this is an identifier for this specific Task Sequence and all ID’s must be unique.

BTS-001

Under ‘Select Template’ leave the default, ‘Standard Client Task Sequence’.BTS-002

Select the Operating System you’re going to deploy.

BTS-003

Accept the default, ‘Do not specify a product key at this time.’

BTS-004

Set the ‘Full Nam’, ‘Organization’ and ‘Internet Explorer Home Page’ options.

BTS-005

Specify a password for the built-in local Administrator account.

BTS-006

Here’s your summary – review everything to ensure it’s correct.

BTS-007

Within seconds your Task Sequence will build.

BTS-008

As before, don’t forget about the ‘View Script’ button:


Import-Module "C:\Program Files\Microsoft Deployment Toolkit\bin\MicrosoftDeploymentToolkit.psd1"
New-PSDrive -Name "DS001" -PSProvider MDTProvider -Root "C:\DeploymentShare"
import-mdttasksequence -path "DS001:\Task Sequences" -Name "Build 1511 amd64 Ent" -Template "Client.xml" -Comments "" -ID "B151164Ent" -Version "1.0" -OperatingSystemPath "DS001:\Operating Systems\Windows 10 Enterprise in 1511_amd64_Ent install.wim" -FullName "Name Full" -OrgName "Org" -HomePage "about:blank" -AdminPassword "my s3kr3t" -Verbose

Create a Stock Build, Sysprep & Capture Task Sequence in MDT

On the heels of creating your build Task Sequence, we’re going to create a Build, Sysprep & Capture Task Sequence something I affectionately call a B&C.

The process is exactly the same as before: Secondary mouse-click on the ‘Task Sequence’ node, select ‘New Task Sequence’ and enter the details:

BCTS-001

Fill in the other fields as you did before, review the summary and execute.

BCTS-002BCTS-004

There’s no difference between what you did before and what you just created; this is intentional.  Later we’ll build off this and it’ll be handy to have a reusable B&C TS ready to go.

 

Update the Deployment Share

Since the objective is to take MDT for a spin in a straight out of the box configuration, we’re not going to make any customizations to the Deployment Share.  That will come later for sure – let’s just make sure it works before we invest time doing so.

The Deployment Share update process is simple, requires minimal input but does take a while to complete.  The reason we have to do this is to generate the bootable .ISO we’ll need for booting into the MDT WinPE environment to image our test VM’s.

Secondary mouse click on your Deployment Share root node – this would be the ‘MDT Deployment Share’ below:

MDT-002

For our purposes we can leave the default options set and click next.

The process will run for a while.

And it’ll look like it’s stuck in a loop.

This is expected because it’s building the x86 and amd64 images.

UDS-011

Finally it’ll finish

UDS-009

You should see some output like this:

<pre>=== Making sure the deployment share has the latest x86 tools ===

=== Processing LiteTouchPE (x86) boot image ===

Building requested boot image profile.
Determining if any changes have been made in the boot image configuration.
Loading the existing boot image profile for platform x86.
The Windows PE source has changed since a boot image was last generated, so a new image will be created.
Discarding existing boot image profile because a complete rebuild is required.
Calculating hashes for requested content.
Changes have been made, boot image will be updated.
Windows PE WIM C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\en-us\winpe.wim will be used.
WIM file mounted.
Set Windows PE system root.
Set Windows PE scratch space.
Added component winpe-hta
Added component winpe-scripting
Added component winpe-wmi
Added component winpe-securestartup
Added component winpe-fmapi
Added component winpe-mdac
Copy: C:\DeploymentShare\Control\Bootstrap.ini to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Bootstrap.ini
Copy: C:\Program Files\Microsoft Deployment Toolkit\Templates\Unattend_PE_x86.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Unattend.xml
Copy: C:\Program Files\Microsoft Deployment Toolkit\Templates\winpeshl.ini to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Windows\system32\winpeshl.ini
Copy: C:\DeploymentShare\Scripts\LiteTouch.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\LiteTouch.wsf
Copy: C:\DeploymentShare\Scripts\ZTIUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTIBCDUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIBCDUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTIDiskUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIDiskUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTIDataAccess.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIDataAccess.vbs
Copy: C:\DeploymentShare\Scripts\ZTIConfigFile.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIConfigFile.vbs
Copy: C:\DeploymentShare\Scripts\ZTIGather.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIGather.wsf
Copy: C:\DeploymentShare\Scripts\ZTIGather.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIGather.xml
Copy: C:\DeploymentShare\Scripts\Wizard.hta to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Wizard.hta
Copy: C:\DeploymentShare\Scripts\Credentials_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Credentials_ENU.xml
Copy: C:\DeploymentShare\Scripts\Credentials_scripts.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Credentials_scripts.vbs
Copy: C:\DeploymentShare\Scripts\WizUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WizUtility.vbs
Copy: C:\DeploymentShare\Scripts\Wizard.css to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Wizard.css
Copy: C:\DeploymentShare\Scripts\Wizard.ico to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Wizard.ico
Copy: C:\DeploymentShare\Scripts\BackButton.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\BackButton.jpg
Copy: C:\DeploymentShare\Scripts\plusicon.gif to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\plusicon.gif
Copy: C:\DeploymentShare\Scripts\minusico.gif to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\minusico.gif
Copy: C:\DeploymentShare\Scripts\Summary_Definition_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Summary_Definition_ENU.xml
Copy: C:\DeploymentShare\Scripts\Summary_scripts.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Summary_scripts.vbs
Copy: C:\DeploymentShare\Scripts\LTICleanup.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\LTICleanup.wsf
Copy: C:\DeploymentShare\Scripts\BDD_Welcome_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\BDD_Welcome_ENU.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Choice.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Choice.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Choice.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Choice.vbs
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_DeployRoot.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_DeployRoot.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_DeployRoot.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_DeployRoot.vbs
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Initialize.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Initialize.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Initialize.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Initialize.vbs
Copy: C:\DeploymentShare\Scripts\SelectItem.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\SelectItem.jpg
Copy: C:\DeploymentShare\Scripts\WelcomeBanner.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeBanner.jpg
Copy: C:\DeploymentShare\Scripts\btnout.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\btnout.png
Copy: C:\DeploymentShare\Scripts\btnover.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\btnover.png
Copy: C:\DeploymentShare\Scripts\btnsel.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\btnsel.png
Copy: C:\DeploymentShare\Scripts\LTIGetFolder.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\LTIGetFolder.wsf
Copy: C:\DeploymentShare\Scripts\NICSettings_Definition_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\NICSettings_Definition_ENU.xml
Copy: C:\DeploymentShare\Scripts\ZTINicUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTINicUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTINicConfig.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTINicConfig.wsf
Copy: C:\DeploymentShare\Scripts\BackButton.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\BackButton.png
Copy: C:\DeploymentShare\Scripts\FolderIcon.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\FolderIcon.png
Copy: C:\DeploymentShare\Scripts\ItemIcon1.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ItemIcon1.png
Copy: C:\DeploymentShare\Scripts\MinusIcon1.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\MinusIcon1.png
Copy: C:\DeploymentShare\Scripts\PlusIcon1.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\PlusIcon1.png
Copy: C:\DeploymentShare\Scripts\SelectItem.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\SelectItem.png
Copy: C:\DeploymentShare\Scripts\header-image.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\header-image.png
Copy: C:\DeploymentShare\Scripts\NavBar.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\NavBar.png
Copy: C:\DeploymentShare\Scripts\Computer.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Computer.png
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Background.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Background.jpg
Copy: C:\DeploymentShare\Scripts\DeployWiz_Administrator.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\DeployWiz_Administrator.png
Copy: C:\DeploymentShare\Tools\x86\BDDRUN.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Windows\system32\BDDRUN.exe
Copy: C:\DeploymentShare\Tools\x86\WinRERUN.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\WinRERUN.exe
Copy: C:\DeploymentShare\Tools\x86\CcmCore.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\CcmCore.dll
Copy: C:\DeploymentShare\Tools\x86\CcmUtilLib.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\CcmUtilLib.dll
Copy: C:\DeploymentShare\Tools\x86\Smsboot.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\Smsboot.exe
Copy: C:\DeploymentShare\Tools\x86\SmsCore.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\SmsCore.dll
Copy: C:\DeploymentShare\Tools\x86\TsCore.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TsCore.dll
Copy: C:\DeploymentShare\Tools\x86\TSEnv.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TSEnv.exe
Copy: C:\DeploymentShare\Tools\x86\TsManager.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TsManager.exe
Copy: C:\DeploymentShare\Tools\x86\TsmBootstrap.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TsmBootstrap.exe
Copy: C:\DeploymentShare\Tools\x86\TsMessaging.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TsMessaging.dll
Copy: C:\DeploymentShare\Tools\x86\TsmBootstrap.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TsmBootstrap.exe
Copy: C:\DeploymentShare\Tools\x86\TsProgressUI.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TsProgressUI.exe
Copy: C:\DeploymentShare\Tools\x86\TSResNlc.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\TSResNlc.dll
Copy: C:\DeploymentShare\Tools\x86\CommonUtils.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\CommonUtils.dll
Copy: C:\DeploymentShare\Tools\x86\ccmgencert.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\ccmgencert.dll
Copy: C:\DeploymentShare\Tools\x86\msvcp120.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\msvcp120.dll
Copy: C:\DeploymentShare\Tools\x86\msvcr120.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\msvcr120.dll
Copy: C:\DeploymentShare\Tools\x86\00000409\tsres.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\00000409\tsres.dll
Copy: C:\DeploymentShare\Tools\x86\Microsoft.BDD.Utility.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x86\Microsoft.BDD.Utility.dll
Copy: C:\Program Files\Microsoft Deployment Toolkit\Samples\Background.bmp to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Windows\system32\winpe.bmp
Copying WIM to the deployment share.
Creating an ISO.
Copying ISO to the deployment share.

=== Completed processing platform x86 ===

=== Making sure the deployment share has the latest x64 tools ===

=== Processing LiteTouchPE (x64) boot image ===

Building requested boot image profile.
Determining if any changes have been made in the boot image configuration.
Loading the existing boot image profile for platform x64.
The Windows PE source has changed since a boot image was last generated, so a new image will be created.
Discarding existing boot image profile because a complete rebuild is required.
Calculating hashes for requested content.
Changes have been made, boot image will be updated.
Windows PE WIM C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim will be used.
WIM file mounted.
Set Windows PE system root.
Set Windows PE scratch space.
Added component winpe-hta
Added component winpe-scripting
Added component winpe-wmi
Added component winpe-securestartup
Added component winpe-fmapi
Added component winpe-mdac
Copy: C:\DeploymentShare\Control\Bootstrap.ini to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Bootstrap.ini
Copy: C:\Program Files\Microsoft Deployment Toolkit\Templates\Unattend_PE_x64.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Unattend.xml
Copy: C:\Program Files\Microsoft Deployment Toolkit\Templates\winpeshl.ini to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Windows\system32\winpeshl.ini
Copy: C:\DeploymentShare\Scripts\LiteTouch.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\LiteTouch.wsf
Copy: C:\DeploymentShare\Scripts\ZTIUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTIBCDUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIBCDUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTIDiskUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIDiskUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTIDataAccess.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIDataAccess.vbs
Copy: C:\DeploymentShare\Scripts\ZTIConfigFile.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIConfigFile.vbs
Copy: C:\DeploymentShare\Scripts\ZTIGather.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIGather.wsf
Copy: C:\DeploymentShare\Scripts\ZTIGather.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTIGather.xml
Copy: C:\DeploymentShare\Scripts\Wizard.hta to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Wizard.hta
Copy: C:\DeploymentShare\Scripts\Credentials_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Credentials_ENU.xml
Copy: C:\DeploymentShare\Scripts\Credentials_scripts.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Credentials_scripts.vbs
Copy: C:\DeploymentShare\Scripts\WizUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WizUtility.vbs
Copy: C:\DeploymentShare\Scripts\Wizard.css to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Wizard.css
Copy: C:\DeploymentShare\Scripts\Wizard.ico to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Wizard.ico
Copy: C:\DeploymentShare\Scripts\BackButton.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\BackButton.jpg
Copy: C:\DeploymentShare\Scripts\plusicon.gif to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\plusicon.gif
Copy: C:\DeploymentShare\Scripts\minusico.gif to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\minusico.gif
Copy: C:\DeploymentShare\Scripts\Summary_Definition_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Summary_Definition_ENU.xml
Copy: C:\DeploymentShare\Scripts\Summary_scripts.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Summary_scripts.vbs
Copy: C:\DeploymentShare\Scripts\LTICleanup.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\LTICleanup.wsf
Copy: C:\DeploymentShare\Scripts\BDD_Welcome_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\BDD_Welcome_ENU.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Choice.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Choice.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Choice.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Choice.vbs
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_DeployRoot.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_DeployRoot.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_DeployRoot.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_DeployRoot.vbs
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Initialize.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Initialize.xml
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Initialize.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Initialize.vbs
Copy: C:\DeploymentShare\Scripts\SelectItem.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\SelectItem.jpg
Copy: C:\DeploymentShare\Scripts\WelcomeBanner.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeBanner.jpg
Copy: C:\DeploymentShare\Scripts\btnout.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\btnout.png
Copy: C:\DeploymentShare\Scripts\btnover.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\btnover.png
Copy: C:\DeploymentShare\Scripts\btnsel.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\btnsel.png
Copy: C:\DeploymentShare\Scripts\LTIGetFolder.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\LTIGetFolder.wsf
Copy: C:\DeploymentShare\Scripts\NICSettings_Definition_ENU.xml to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\NICSettings_Definition_ENU.xml
Copy: C:\DeploymentShare\Scripts\ZTINicUtility.vbs to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTINicUtility.vbs
Copy: C:\DeploymentShare\Scripts\ZTINicConfig.wsf to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ZTINicConfig.wsf
Copy: C:\DeploymentShare\Scripts\BackButton.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\BackButton.png
Copy: C:\DeploymentShare\Scripts\FolderIcon.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\FolderIcon.png
Copy: C:\DeploymentShare\Scripts\ItemIcon1.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\ItemIcon1.png
Copy: C:\DeploymentShare\Scripts\MinusIcon1.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\MinusIcon1.png
Copy: C:\DeploymentShare\Scripts\PlusIcon1.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\PlusIcon1.png
Copy: C:\DeploymentShare\Scripts\SelectItem.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\SelectItem.png
Copy: C:\DeploymentShare\Scripts\header-image.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\header-image.png
Copy: C:\DeploymentShare\Scripts\NavBar.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\NavBar.png
Copy: C:\DeploymentShare\Scripts\Computer.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\Computer.png
Copy: C:\DeploymentShare\Scripts\WelcomeWiz_Background.jpg to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\WelcomeWiz_Background.jpg
Copy: C:\DeploymentShare\Scripts\DeployWiz_Administrator.png to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Scripts\DeployWiz_Administrator.png
Copy: C:\DeploymentShare\Tools\x64\BDDRUN.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Windows\system32\BDDRUN.exe
Copy: C:\DeploymentShare\Tools\x64\WinRERUN.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\WinRERUN.exe
Copy: C:\DeploymentShare\Tools\x64\CcmCore.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\CcmCore.dll
Copy: C:\DeploymentShare\Tools\x64\CcmUtilLib.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\CcmUtilLib.dll
Copy: C:\DeploymentShare\Tools\x64\Smsboot.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\Smsboot.exe
Copy: C:\DeploymentShare\Tools\x64\SmsCore.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\SmsCore.dll
Copy: C:\DeploymentShare\Tools\x64\TsCore.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TsCore.dll
Copy: C:\DeploymentShare\Tools\x64\TSEnv.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TSEnv.exe
Copy: C:\DeploymentShare\Tools\x64\TsManager.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TsManager.exe
Copy: C:\DeploymentShare\Tools\x64\TsmBootstrap.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TsmBootstrap.exe
Copy: C:\DeploymentShare\Tools\x64\TsMessaging.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TsMessaging.dll
Copy: C:\DeploymentShare\Tools\x64\TsmBootstrap.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TsmBootstrap.exe
Copy: C:\DeploymentShare\Tools\x64\TsProgressUI.exe to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TsProgressUI.exe
Copy: C:\DeploymentShare\Tools\x64\TSResNlc.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\TSResNlc.dll
Copy: C:\DeploymentShare\Tools\x64\CommonUtils.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\CommonUtils.dll
Copy: C:\DeploymentShare\Tools\x64\ccmgencert.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\ccmgencert.dll
Copy: C:\DeploymentShare\Tools\x64\msvcp120.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\msvcp120.dll
Copy: C:\DeploymentShare\Tools\x64\msvcr120.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\msvcr120.dll
Copy: C:\DeploymentShare\Tools\x64\00000409\tsres.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\00000409\tsres.dll
Copy: C:\DeploymentShare\Tools\x64\Microsoft.BDD.Utility.dll to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Deploy\Tools\x64\Microsoft.BDD.Utility.dll
Copy: C:\Program Files\Microsoft Deployment Toolkit\Samples\Background.bmp to C:\Users\ADMINI~1\AppData\Local\Temp\2\MDTUpdate.3008\Mount\Windows\system32\winpe.bmp
Copying WIM to the deployment share.
Creating an ISO.
Copying ISO to the deployment share.

=== Completed processing platform x64 ===

=== Processing complete ===

</pre>

Don’t forget to grab that code by the ‘View Script’ button!

So you’re all set!

Wait – did something go wrong?  Are you seeing an error?  Something like this?

UDS-010

With text that reads:

<pre>=== Making sure the deployment share has the latest x86 tools ===

=== Processing LiteTouchPE (x86) boot image ===

Building requested boot image profile.
Determining if any changes have been made in the boot image configuration.
Loading the existing boot image profile for platform x86.
The Windows PE source has changed since a boot image was last generated, so a new image will be created.
Discarding existing boot image profile because a complete rebuild is required.
Calculating hashes for requested content.
Changes have been made, boot image will be updated.
Windows PE WIM C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\x86\en-us\winpe.wim will be used.
Unable to mount the WIM, so the update process cannot continue.

=== Completed processing platform x86 ===

=== Making sure the deployment share has the latest x64 tools ===

=== Processing LiteTouchPE (x64) boot image ===

Building requested boot image profile.
Determining if any changes have been made in the boot image configuration.
Loading the existing boot image profile for platform x64.
The Windows PE source has changed since a boot image was last generated, so a new image will be created.
Discarding existing boot image profile because a complete rebuild is required.
Calculating hashes for requested content.
Changes have been made, boot image will be updated.
Windows PE WIM C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\en-us\winpe.wim will be used.
Unable to mount the WIM, so the update process cannot continue.

=== Completed processing platform x64 ===

=== Processing complete ===

</pre>

Did you remember to apply the patch mentioned in the previous post?  If not, apply the patch and try again.  If you did apply the patch, further troubleshooting is required and I recommend posting on the TechNet Forums and Twitter.  You’re more than welcome to post here – happy to help in anyway I can – but the reality is there your issue will get far more visibility on those two platforms than here 🙂

Objective Complete!

That’s it for now but you’re essentially ready to start imaging.  If you’re feeling adventurous, try imaging one of your VMs.

Until next time, Good Providence to you!

MDT Tutorial Part 1: Installation

Living Table of Contents

Today’s agenda: Install Software

  • Install the Windows Assessment & Deployment Kit (ADK)
  • Install the Microsoft Deployment Toolkit (MDT)

ADK Installation

If you read my last post I recommended running the ADK installation and selecting the option to download the files locally in preparation for the installation.  The reason for that is due to the nature of the ADK installation: The bits are retrieved on demand and it takes a while.  It’s very much as game of Hurry Up and Wait!

Run the ADK installation & optionally change the installation path

ADK-001

Decide whether you want to share statistics

ADK-002

Read over the EULA and if you agree, click accept

ADK-003

When you get to the feature selection stage, everything will be checked.  Uncheck everything except

  1. Deployment Tools
  2. Windows Preinstallation Environment (Windows PE)

I personally also recommend checking:

  1. Imaging and Configuration Designer (ICD)
  2. Configuration Designer
  3. User State Migration Toolkit (USMT)

ADK-004

If you downloaded it locally, the installation should move at a decent clip and finish swiftly.  Stand up, stretch, take a quick walk & grab some water.

ADK-005ADK-006

Known Issue

There’s a known issue with the Windows Assessment & Deployment Kit (ADK) where the following prompt is displayed on systems due to two files being signed with an older certificate.

ADK-007

This is a well documented bug:

Fortunately this is easily fixed by applying the patch and instructions and code are included:


xcopy ".\amd64\wimmount.sys" "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM\wimmount.sys"
xcopy ".\amd64\wofadk.sys" "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\DISM\wofadk.sys"

xcopy ".\x86\wimmount.sys" "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\x86\DISM\wimmount.sys"
xcopy ".\x86\wofadk.sys" "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\x86\DISM\wofadk.sys"

xcopy ".\arm64\wimmount.sys" "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\arm64\DISM\wimmount.sys"
xcopy ".\arm64\wofadk.sys" "C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\arm64\DISM\wofadk.sys"

Or you can use the workaround suggested by Michael Niehaus.

MDT Installation

This is a straightforward installation with few options to configure since you can leave the defaults.

Run the installer & click next

MDT-001

Read through the EULA

MDT-002

You can leave the default options and optionally change the installation location.

MDT-003

Click next to start the installation and let it run for a few minutes to completion.

MDT-005 MDT-007

MDT-008

Milestone Reached!  A congratulations is in order!

In the next post we’ll crack open the Deployment Workbench and start setting ourselves up for imaging.

For now, I bid you Good Providence!

MDT Tutorial: Prologue & Requirements

I met someone recently who is in a similar IT position looking for some advice with respect to Operating System Deployments (OSD) – both bare metal and upgrades – and application packaging & deployments.  I recommended leveraging the Microsoft Deployment Toolkit (MDT) for imaging and combining it with the PowerShell App Deployment Toolkit (PSADT) to help accomplish his goals.  Although he had used MDT, he wasn’t as experienced with it as I was and so was looking for some guidance which I was happy to do.

Now, I may not be a world renowned expert like some people (hint: see the Resources page) but I can hold my own, and this was an excellent opportunity for me to go over the basics of image building with my new friend.

So over the next few weeks I’ll be going over the basics of building an MDT imaging lab.

One more thing…

I don’t think there’s anything new here.  In fact, this is mostly a consolidation of well known & documented steps in addition to popular or leading practices recommended by those who share a passion for imaging.  So aside for compiling some of these ideas I can’t possibly take all the credit.  Because lots of these steps are now ingrained in my process, I may not be able to cite references to where the original idea came from.  Not trying to steal thunder or take credit away from anyone where it’s due; I just didn’t necessarily catalog the URL or Tweet of every process, tip or trick I’ve come across for the last 5 or so years.

If you’re a seasoned MDT Guru, you’re probably going to find this a little ho-hum elementary.  So while you’re welcome to read on, please curb your expectations. 🙂

Living Table of Contents

Prerequisites

Hardware

Preferred Configuration

Ideally you want a beefy machine to spin up some VM’s, and it doesn’t have to be a Dell R730xd.  In fact, before I got a dedicated machine, I used a laptop with 8GB of RAM and a ~200GB or so SSD.  These days it’s not uncommon for a machine to have 12-16GB of RAM and 256GB SSD so I’m thinking that’s a realistic and achievable goal.  Just remember: Can’t have too much RAM but on the storage front if SSD is a premium, put your VM’s on the SSD and the OS and Deployment Share on mechanical/spindle disks.  You could get creative by using USB drives (thumb or external) or even SD cards.  Go Nuts!

Acceptable Minimum for Educational Purposes

While you can use physical assets for testing, it’s not leading practice and will require some extra work with drivers.  That said, if you don’t have access to beefy hardware for creating Virtual Machines, but have a handful of physical assets at your disposal, grab a few machines and get them setup on a gigabit switch with network access.

Software

MDT Server

Be it a physical or virtual machine, install the OS of your choice on your designated MDT server.  At this time, OS selection doesn’t matter so it could be a licensed or evaluation copy of Server 2012 R2, Server 2016 or Windows 10.  Once you install the OS on the MDT server, install .NET 3.5, rename it to something appreciable, like MDTServer, create a workgroup and patch the machine.

All Set!

Once you have everything all setup, you’re ready to move forward!

Good Providence to you as you get this all setup!

Getting Real Lenovo Model Details

Our computer naming convention includes a portion of the model number to make it easier to identify trends and those with old, or new, assets.  Coming from a Dell shop where we did something similar, I was disappointed to learn that Lenovo machines didn’t populate the Model details the same way.  So instead of seeing something like ThinkPad W541, we were seeing something very cryptic: 20EFCTO1WW

Get your Decoder Ring

Thinking something was up with the built-in scripts or logic I ran the below on a Lenovo machine which confirmed it was what it was:


wmic path win32_computersystem get model

Model
20EFCTO1WW

For a while we kept a matrix of sorts that we’d feed into our CustomSettings.ini to ensure machines were named correctly.  We expected this pain as models were phased out and new models came in, but it was also very frustrating as the details would change mid-stream for the same model.  This led us to studying the Lenovo Product Specifications Reference or PSREF.

Not being keen on this, I learned somewhere (unsure of the actual source) that Lenovo stashes the bits we were after in Win32_ComputerSystemProduct under Version


wmic path win32_computersystemproduct get version

Version
ThinkPad W541

Once confirmed across a few machines, I went right to work.

UserExit Script: GetAbbrModel.vbs

This is a modified version of the script we use in production but the result is the same: It gets the human-readable format of the model, trims the parts we don’t want and returns an abbreviated version of the model.  So a ThinkPad W541 ends up being returned to MDT/SCCM as W54.  You can modify to suit, like creating a new property/variable called RealModel and assigning the script output to that or overwrite the existing Model property via the script itself.

The script works on 99% of the machines in our environment but it does occasionally fail:

  • some unexpected data is in there: sometimes it’s really bizzare or mirrors Model in Win32_ComputerSystem or Name in Win32_ComputerSystemProduct.
  • most of the time it’s because the field is blank/null/empty and we typically see this on machines that were serviced, specifically a board replacement, and tech didn’t run the utility to set the bits in the BIOS.  Accidents happen.
  • it’s running on very hardware that should have been retired 🙂

Good Providence to you as you adjust it to suit your needs!


' //***************************************************************************
' //
' // Solution:Get Model Abbreviation for Microsoft Deployment
' // File: jgp_GetAbbrModel.vbs
' //
' // Purpose: Gets & sets the correct model abbreviation for use in computer name and other custom configurations
' //
' // ***** End Header *****
' //***************************************************************************

'//----------------------------------------------------------------------------
'//
'// Global constant and variable declarations
'//
'//----------------------------------------------------------------------------
Option Explicit

'//----------------------------------------------------------------------------
'// End declarations
'//----------------------------------------------------------------------------

'//----------------------------------------------------------------------------
'// Main routine
'//----------------------------------------------------------------------------
Function UserExit(sType, sWhen, sDetail, bSkip)
	UserExit = Success
End Function

Function GetAbbrModel()
	on error goto 0
	Dim sMake : sMake = oEnvironment.Item("Make")
	Dim sModel : sModel = oEnvironment.Item("Model")
	Dim sAbbrModel : sAbbrModel = "UNK"

	Select Case UCase(sMake)

		Case UCase("Dell")

			If InStr(1,sModel,"OptiPlex ",1) > 0 Then
				sAbbrModel = Left(Replace(sModel,"ptiPlex ","",1,-1,1),3)
			elseif InStr(1,sModel,"Latitude ",1) > 0 Then
				sAbbrModel = Left(Replace(sModel,"Latitude ","",1,-1,1),3)
			elseif InStr(1,sModel,"XPS",1) > 0 Then
				sAbbrModel = Left(Replace(sModel,"PS","",1,-1,1),3)
			end if

		Case UCase("Lenovo")
			Dim oCSP
			For Each oCSP in GetObject("winmgmts:").ExecQuery("SELECT Version,Name FROM Win32_ComputerSystemProduct")
				Dim sLenovoModel : sLenovoModel = oCSP.Version
				Dim sLenovoProductType : sLenovoProductType = oCSP.Name
				exit for
			Next

			If InStr(1,sLenovoModel,"ThinkCentre ",1) > 0 Then
				sAbbrModel = Left(Replace(sLenovoModel,"ThinkCentre ","",1,-1,1),3)
			elseif InStr(1,sLenovoModel,"ThinkStation ",1) > 0 Then
					sAbbrModel = Left(Replace(sLenovoModel,"ThinkStation ","",1,-1,1),3)
			elseif InStr(1,sLenovoModel,"ThinkPad ",1) > 0 Then
				if Instr(1,sLenovoModel,"Carbon",1) > 0 Then
					If InStr(1,sLenovoModel,"Carbon 4th",1) > 0 Then
						sAbbrModel = Left(Replace(Replace(Replace(sLenovoModel,"ThinkPad ","",1,-1,1),"arbon 4th","")," ",""),3)
					elseif InStr(1,sLenovoModel,"Carbon 3rd",1) > 0 Then
						sAbbrModel = Left(Replace(Replace(Replace(sLenovoModel,"ThinkPad ","",1,-1,1),"arbon 3rd","")," ",""),3)
					elseif InStr(1,sLenovoModel,"Carbon 2nd",1) > 0 Then
						sAbbrModel = Left(Replace(Replace(Replace(sLenovoModel,"ThinkPad ","",1,-1,1),"arbon 2nd","")," ",""),3)
					elseif InStr(1,sLenovoModel,"Carbon",1) > 0 Then
						sAbbrModel = Left(Replace(Replace(Replace(sLenovoModel,"ThinkPad ","",1,-1,1),"arbon","")," ",""),3)
					end if
				else
					sAbbrModel = Left(Replace(sLenovoModel,"ThinkPad ","",1,-1,1),3)
				end if
			else
				' Alternatively you could build & maintain (yuck) a table of product types
				Select Case UCase(Left(sLenovoProductType,4))
					Case UCase("5032")
						sAbbrModel = "M81"

					case UCase("20EF")
						sAbbrModel = "W54"
				End Select
			end if

		Case UCase("innotek GmbH")
			sAbbrModel = UCase(Left(sMake,1) & Mid(sMake,8,1) & Right(sMake,1))

		Case UCase("VMware, Inc.")
			sAbbrModel = UCase(Left(sMake,3))

		Case UCase("Microsoft Corporation")
			sAbbrModel = "HPV"

	End Select
	GetAbbrModel = sAbbrModel
End Function

Preparing for Windows 10: Move Computers into to Win 10 OUs

One thing that has annoyed me about MDT and SCCM was that there wasn’t a built-in method to move machines into the proper OU.  As such it required creating something from scratch and I opted for something that didn’t require dependencies, like the ActiveDirectory module.

This isn’t the best way and this isn’t the only way – it’s just a way; one of many in fact.

Please note that this is NOT the ideal way to handle any operations that require credentials!  Keeping credentials in a script is bad practice as anyone snooping around could happen upon them and create some problems.  Instead, you should rely on web services to do this and Maik Koster has put together an excellent little care package to help get you started.

Move-ComputerToOU Prerequisites

My script has a few prerequisites:

  • The current AD site
  • A [local] Domain Controller to use (recommended)
  • The current OU of the machine to be moved
  • The new OU to move the machine into

It’s important to know that this script does not rely on the ActiveDirectory module.
One of my [many] quirks is to try to keep everything self-contained where it makes sense to do so, and I liked the idea of not having to rely on some installed component, an EXE and so on.  But to be honest, web services is the way to go for this.

Getting the Current AD Site

Better see this post for that.

Getting a Local Domain Controller

Better see this post for that.

Getting the Current OU

Better see this post for that.

Getting / Setting the New OU

If this is being executed as part of an OSD, yank those details from the MachineObjectOU Task Sequence variable via something like:

Function Get-TaskSequenceEnvironmentVariable
    {
        Param([Parameter(Mandatory=$true,Position=0)]$VarName)
        Try { return (New-Object -COMObject Microsoft.SMS.TSEnvironment).Value($VarName) }
        Catch { throw $_ }
    }
$MachineObjectOU = Get-TaskSequenceEnvironmentVariable MachineObjectOU

Otherwise just feed it the new OU via the parameter

Process Explanation

We first have to find existing object in AD


# This is the machine we want to move
$ADComputer = $env:COMPUTERNAME

# Create Directory Entry with authentication
$de = New-Object System.DirectoryServices.DirectoryEntry($LDAPPath,"$domain\$user",$pass)

# Create Directory Searcher
$ds = New-Object System.DirectoryServices.DirectorySearcher($de)

# Fiter for the machine in question
$ds.Filter = "(&(ObjectCategory=computer)(samaccountname=$ADComputerName$))"

# Optionally, set other search parameters
#$ds.SearchRoot = $de
#$ds.PageSize = 1000
#$ds.Filter = $strFilter
#$ds.SearchScope = "Subtree"
#$colPropList = "distinguishedName", "Name", "samaccountname"
#foreach ($Property in $colPropList) { $ds.PropertiesToLoad.Add($Property) | Out-Null }

# Execute the find operation
$res = $ds.FindAll()

 

Then we bind to the existing computer object


# If there's an existing asset in AD with that sam account name, it should be the first - and only - item in the array.
# So we bind to the existing computer object in AD
$CurrentComputerObject = New-Object System.DirectoryServices.DirectoryEntry($res[0].path,"$domain\$user",$pass)

# Extract the current OU
$CurrentOU = $CurrentComputerObject.Path.Substring(8+$SiteDC.Length+3+$ADComputerName.Length+1)

 

From there setup the destination OU


# This Here we set the new OU location
$DestinationOU = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$SiteDC/$NewOU","$domain\$user",$pass)

 

And finally move the machine from the old/current OU to the new/destination OU


# And now we move the asset to that new OU
$Result = $CurrentComputerObject.PSBase.MoveTo($DestinationOU)

Move-ComputerToProperOU.ps1

So this is a shortened version of the script I’m using in production.  All you need to do is fill in the blanks and test it in your environment.


# There's a separate function to get the local domain controller
$SiteDC = Get-SiteDomainController
# Or you can hard code the local domain controller
$SiteDC = 'localdc.domain.fqdn'

# Build LDAP String
# I //think// there were maybe two cases whre this din't work
$LocalRootDomainNamingContext = ([ADSI]"LDAP://$SiteDC/RootDSE").rootDomainNamingContext
# So I added logic to trap that and pull what I needed from SiteDC
#$LocalRootDomainNamingContext = $SiteDC.Substring($SiteDC.IndexOf('.'))
#$LocalRootDomainNamingContext = ($LocalRootDomainNamingContext.Replace('.',',DC=')).Substring(1)

# Building the LDAP string
$LDAPPath = 'LDAP://' + $SiteDC + "/" + $LocalRootDomainNamingContext

# Set my domian for authentication
$domain = 'mydomain'

# Set the user for authentication
$user = 'myjoindomainaccount'

# Set the password for authentication
$pass = 'my sekret leet-o-1337 creds'

# This is the machine I want to find & move into the proper OU.
$ADComputerName = $env:COMPUTERNAME

# This is the new OU to move the above machine into.
$NewOU = 'OU=Laptops,OU=Win10,OU=Office,OU=CorpWorkstations,DC=domain,DC=fqdn'

# Create Directory Entry with authentication
$de = New-Object System.DirectoryServices.DirectoryEntry($LDAPPath,"$domain\$user",$pass)

# Create Directory Searcher
$ds = New-Object System.DirectoryServices.DirectorySearcher($de)

# Fiter for the machine in question
$ds.Filter = "(&(ObjectCategory=computer)(samaccountname=$ADComputerName$))"

# Optionally, set other search parameters
#$ds.SearchRoot = $de
#$ds.PageSize = 1000
#$ds.Filter = $strFilter
#$ds.SearchScope = "Subtree"
#$colPropList = "distinguishedName", "Name", "samaccountname"
#foreach ($Property in $colPropList) { $ds.PropertiesToLoad.Add($Property) | Out-Null }

# Execute the find operation
$res = $ds.FindAll()

# If there's an existing asset in AD with that sam account name, it should be the first - and only - item in the array.
# So we bind to the existing computer object in AD
$CurrentComputerObject = New-Object System.DirectoryServices.DirectoryEntry($res[0].path,"$domain\$user",$pass)

# Extract the current OU
$CurrentOU = $CurrentComputerObject.Path.Substring(8+$SiteDC.Length+3+$ADComputerName.Length+1)

# This Here we set the new OU location
$DestinationOU = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$SiteDC/$NewOU","$domain\$user",$pass)

# And now we move the asset to that new OU
$Result = $CurrentComputerObject.PSBase.MoveTo($DestinationOU)

 

Happy Upgrading & Good Providence!