Windows 7 x64 and TPM 2.0

If you are using Bitlocker, Configuration Manager 1610 or higher and get a piece of hardware that has TPM 2.0 there are a few more hurdles to get the device encrypted. Coretech has written notes from the field which states the two options going forward. Following their recommendation – lets go down the path of running a device with CSM (UEFI) enabled and installing Windows 7.

Make sure that the device is running in UEFI and is setup as expected. I will leave the actual configuration of BIOS / UEFI out of this – as any device with TPM 2.0 will most likely have a preconfigured settings that are optimal. If not, time to configure for UEFI (without Secure Boot).


Once that is completed – create a new group that has the intention to identify if we (if possible) booted with a legacy option (legacy PXE-boot, legacy USB stick etc etc). Validate that its not UEFI-booted and that we have a TPM 2.0 chip (and add a check that we are also intending to install Windows 7 x64).


Only two steps are required in the group – format the drive as GPT and then a restart to the boot-image. Suggested format:



Once we have ensured that the device is running in UEFI, and not legacy…, and since we all are running a newer ADK then 1511 – we should add three registry keys per Microsoft

Above configuration of the algorithms for Windows 10 (build 1511) is kept as REG_DWORDs under:


Operating System drives: EncryptionMethodWithXtsOs

Fixed Data drives: EncryptionMethodWithXtsFdv

Removable Data drives: EncryptionMethodWithXtsRdv


You can integrate the TPM 2.0 hotfix into the Windows 7, or simply install it after the WIM has been copied onto the machine. It should be installed before MBAM (or just bitlocker) is installed and starts handling the encryption

Task Sequence and shutdown (not reboot) a computer and continue

For some reason there is a requirement to do a computer shutdown (not restart) while running a task sequence, and once the computer starts again there is a need to continue running the task sequence where we left it.

How do you go about that? Let’st start…


We need two scripts, a task sequence with the ability to run one script and then to start a task sequence controlled restart.

For testing purposes a networkshare was used instead of leveraging a package, but in real-life and in production – all of the files can be placed in a package and executed from there.
This concept is tested within WinPE (using Winpeutil etc…), but you can most likely adapt it to a Windows installation.

Run Monitor

The ‘Run Monitor’ step will kick off a VB-Script that will start a powershell script – and then exit. Simple enough to start a script, and then allow the task sequence to continue with the next steps


Runapp "powershell.exe","-noprofile -executionpolicy bypass -file " & GetScriptPatH() & "shutdown.ps1"

Private Function RunApp(AppPath,Switches)
Dim WShell
Dim RunString
Dim RetVal
Dim Success

On Error Resume Next

Set WShell=CreateObject("WScript.Shell")

RunString=Chr(34) &AppPath & Chr(34) & " " & Switches


Set WShell=Nothing
End Function

Private Function GetScriptPath
End Function

The powershell-script (shutdown.ps1) looks as follows;

  1. Create a TS Environment (so we can read variables)
  2. Verify if the variable _SMSTSBootStagePath is set
  3. If the drive-part is longer than a single-letter – we know that the boot-image is prepared and that the reboot countdown has started.
$end =$true
write-output "start"

start-sleep 2
#Remove-Variable -name tsenv -Force -ErrorAction SilentlyContinue
if (!$tsenv) {
try  {
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment
catch {
write-output "No TS started yet"
try  {
$bootpath = $tsenv.Value("_SMSTSBootStagePath") -split ":"
if ($bootpath[0].length -gt 1) {
write-output "SMSTSBootStagePath prepped for reboot"
$end = $false
catch {
write-output "variable not set"

} While ($end -eq $true)

start-sleep 5

wpeutil shutdown


The restart step is fairly generic and you can configure it as you need. A thing to note is that the time-out needs to be higher than the start-sleep within the Powershell-script. As the purpose is to continue within WinPE – the step is configured to start to the boot-image.


PXE and notes to self

The joy of supporting PXE-boot in a number of different environments have created a mental note-to-selflist when operating PXE with Configuration Manager. These are my notes, and if they can be of use to anyone else – thats great.


PXE-boot and its dependencies on operational and a managable network is key and therefore a basic understanding is vital. Coretech has published a great overview explaining PXE and its relationship with DHCP.

Basic setup

Some minor tweaks to get started are of course required even for the not-so-complex environment and 4SysOps has a great guide that details the generic troubleshooting steps on basic configuration.

In essence:

  • An operational Configuration Manager environment is key
      • A Distribution Point for the Configuration Manager site that is setup to handle PXE
      • A possibility to handle the broadcast requests when pressing F12 on the client

The last part (handle broadcast requests) is normally something that is managed by a network operations-team. There are of course (why should there be one?) many different ways to configure this and normally the discussion stands between DHCP Options (not supported by Microsoft) or IP-helpers. TechThoughts has an overview with detailed pros and cons, however clearly states that IP-helpers is the way to go forward.


Once you get everything setup – here comes a list in order of likely hood to cause you issues.

What does a client see when pressing F12?

Well, you see on the screen that you pressed F12 and potentially some sort of diagnostic information is presented to you. Is this information useful? Complete? Of debugging-quality?

Most likely not! There are two tools available – one from Citrix (PXEChecker) and one from 2pint (powershell) – which provides great insight into what shows up at your client.

Test TFTP download

Wondering if you have a responsive PXE-server? Follow the previous guide howto test the download of a file


As PXE and its reliance on just ip-addresses is heavy – the first question that comes to mind is why DNS is a thing? Well, legacy servers (still supported for the role of Distribution Point) that run Windows Server 2008 R2 may exhaust the available ports if DNS and PXE-role is hosted on the same system.

Resolve the issue by configuring Windows Deployment Services to  dynamically request and allocate ports that are available.

DWORD: UDPPortPolicy
Value: 0


If the Distribution Point (with PXE enabled) and the DHCP-server is configured on the same server a few technical configurations are required. Normally these are set up properly, however it can always be a good thing to double-check.

Configure WDS to not use the same ports as DHCP
Value: 0

Configure the DHCP-server to set option 60. Option 60 is intended for the client to know that in addition to the server providing an answer to the request for IP-address, a PXE-server also operates on the same server.

WDSUTIL /Set-Server /UseDHCPPorts:No /DHCPOption60:Yes

It’s slow

ConfigMgr has gradually provided improved ways to make PXE-boot go faster. CCMExec wrote article on howto tweak the configuration for boot-times (RamDiskTFTPBlocksize and RamDiskTFTPWindowSize). The sweetspot seems to be at 16384 / 8

DWORD: RamDiskTFTPWindowSize
Value: 8
DWORD: RamDiskTFTPBlockSize
Value: 16384 (1456 allows for higher compatibility)

It starts to download but freezes (0xC0000001)

If the error is prevalent and not related to a specific device or model – most likely this relates to issues with something between the server and the client not beeing able to handle the default size of 1456 in block size. Windows Server 2003 was set to use a block size of 512, and since Windows Server 2008 this was bumped to 1456. If this fails – set it to 512 and verify compatibility. Previously the possibility was tested with 1432 and some success has been confirmed.

DWORD: MaximumBlockSize:
Value: 512 (or 1432)

Quick test of WDS

Just a quick-test of a TFTP server – just to validate if it is responsive…

These commands be run from any client (screenshots are from Win7)

Step 1

Install the TFTP Client


Step 2

Run the command in a folder where you have permissions to write in

tftp -1 <servername> GET \boot\x86\

If the TFTP-client is not installed the below error message will be received


If it is successfull, you will have downloaded a small file


Apply hotfixes during task sequence

If you want to apply hotfixes as part of a task sequence there are of course numerous ways to achieve this. Using PowerShell, MDT 2012 U1 (soon to be 2013??) with SCCM 2012 can make this look a lot prettier with just a few lines of code.

So, lets set this up.

1. First of all we need a script, named hotfixes.ps1. The code looks like this;

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$folder = $scriptPath
$total = gci $folder *.msu | measure | Select-Object -expand Count
$i = 0
gci $folder *.msu | foreach {
WUSA ""$_.FullName /quiet /norestart""
Write-Progress -activity "Applying Hotfixes" -status "Installing $_ .. $i of $total" -percentComplete (($i / $total) * 100)
Wait-Process -name wusa

2. Collect the hotfixes necessary into a folder. Place the script in the root, and the hotfixes in a sub-folder named “hotfix”. All hotfixes must be of the .MSU-kind.


3. Create a package of this to make the files available within the SCCM 2012 infrastructure


4. Create a new MDT 2012 Update 1 task sequence. Add the following steps;


As you can see below we set our script to be executed and reference the package which contains the updates


5. Deploy the task sequence to a computer and verify the results;


Looks nice? Well, the script is partly built on the ideas of Niklas Åkerlund, a fellow Swede, on howto install multiple Windows hotfixes. Using a forum-post response by Michael Niehaus I gathered that it would be rather simple to output it more nicely and provide insight into progress using the task sequence progress bar.

Automatically generate name using ConfigMgr / MDT

Using ConfigMgr with the MDT integration to deploy computers is quite common these days. It provides a certain level of automation that is quite easy to follow, however a topic that quite often comes up is how to automatically name computers during the deployment of a new client.

There are several ways – prompt the user for a name;

Use the serial number of the client to automatically generate a name;

Use a database to have a sequence number and prefix generate a name;

This was quite heavily developed using several other metrics (type, location etc etc)