Category Archives: MCM

ConfigMgr OSD | Windows 10 Disk Partitioning to Correctly Include Recovery Tools Partition

Edit 28/02/24: Updated to reflect increase of Recovery partition to 2048Mb.

How should disks be partitioned for Windows 10 so that the Recovery Partition is configured properly? Turns out the answer isn’t straightforward and that the standard tools provided provided in ConfigMgr by Microsoft don’t quite allow you to do it properly by default…

WinRE is important as it is used by many of the reset features used in Windows 10, especially in Modern Management scenarios. This includes manual recovery, Factory Reset and newer options such as Windows Autopilot Reset.

This partition is used to help recover an OS when not bootable which is why it needs to be located on a separate partition. This partition should be placed immediately after the Windows partition to allow Windows to modify and recreate the partition in the future if future updates (i.e. newer versions of Windows) require a larger Recovery Image. It also allows the device to be rebuilt (i.e., have the OS reinstalled) without affecting the Recovery Partition.

If this resizing/recreation of the Recovery Partition can’t be done during OS upgrades then the ability to use the WinRE environment can be removed and is tricky to remediate afterwards.

To produce this post I have read through a lot of other well-respected blogs and also analysed what a lot of experts have suggested on Twitter etc. This article is the summary of that analysis as well as providing a script written by me which can be used during ConfigMgr Task Sequences to create the required disk partitions correctly. The main resources I used were:

miketerrill.net

garytown.com

Lets start with the recommendations from Microsoft.

UEFI | GPT

For UEFI, Microsoft recommend the following partition layout for Windows 10 (Docs link can be found here):

diagram of default partition layout: system, msr, windows, and recovery
Microsoft Recommended Partition Layout

From this diagram we can see that Microsoft recommend a ‘System‘ partition’ (also known as a EFI System Partition (ESP)) which provides a device with a partition to boot from. It shouldn’t contain any files other than what is intended for booting the device.

‘System’ Partition

Following that is a ‘Microsoft Reserved‘ partition (MSR) which is used for partition management. No user data can be stored on this partition.

‘Microsoft Reserved’ Partition

The next partition is the ‘Windows‘ partition which is obviously used for the Windows Operating System.

‘Windows’ Partition

And the last partition (and the one which causes the most questions) is the ‘Recovery Tools‘ partition which will host a copy of the ‘Windows Recovery Environment’ (WinRE). WinRE is a recovery environment that can repair common causes of unbootable operating systems.

The Recovery Tools partition presents a problem as there is no built-in way in a Task Sequence of ensuring that the Recovery Tools partition is located at the end of the disk (i.e., after the Windows partition) and is configured correctly – this is the main reason for writing this blog post.

The table below summarises the best recommended sizes for each partition based on the Microsoft recommendations and also various experts around the web:

NameSize (Mb)Format
System (EFI)360 fixed sizeFAT32
MSR128 fixed size
Windows (Primary)100% of remaining space on diskNTFS
Recovery 2048 fixed sizeNTFS
UEFI Disk Partitions
UEFI | GPT Format and Partition Disk Step

BIOS | MBR

For traditional BIOS, Microsoft recommend the following partition layout for Windows 10 (Docs link can be found here). Note that ‘BIOS | MBR’ is now considered legacy and has limited use case scenarios with Modern Device Management. Many modern security controls are based on the newer UEFI firmware and so ‘BIOS | MBR’ and is therefore rarely used:

diagram of default partition layout: system, windows, and recovery

From this diagram we can see that Microsoft again recommends a ‘System‘ partition which is used to boot the device.

‘System’ Partition

Following that is the ‘Windows‘ partition to be used for the Windows 10 operating system.

‘Windows’ Partition

And the final partition is once again the ‘Recovery Tools‘ partition which was mentioned previously in the UEFI section above.

The table below summarises the best recommended sizes for each partition based on the Microsoft recommendations and also various experts around the web:

NameSize (Mb)Format
System360 fixed sizeNTFS
Windows (Primary)100% of remaining space on diskNTFS
Recovery 2048 fixed sizeNTFS
Traditional BIOS Disk Partitions
BIOS | MBR Format and Partition Disk Step

Recovery Tools Partition Solution

To create the Recovery Tools partition in the location and size required we need to use ‘Diskpart’ to create the Recovery Partition once the built-in ‘Format and Partition Disk‘ step has been completed.

The way this is done is to shrink the ‘Windows’ partition by the size needed (in this case 984Mb) and create a new partition with that newly-available space called ‘Recovery’.

For UEFI deployments, the ‘Recovery Tools’ partition needs to have it’s ‘ID‘ set to ‘de94bba4-06d1-4d40-a16a-bfd50179d6ac‘, be given the GPT attribute of ‘0x8000000000000001‘ and needs to be set to have a Partition Type of ‘27‘ so that it is hidden.

To accomplish this I wrote a PowerShell script to run Diskpart with the required settings. The script should be added to the Task Sequence just after the built-in ‘Format and Partition Disk’ step as per the images below:

Location of ‘Create Recovery Partition’ Step

The script works best when entered as a PowerShell script as part of a ‘Run PowerShell Script‘ task in a Task Sequence:

‘Create Recovery Partition’ Script Task

The script for automating the creation of the Recovery Partition is embedded below. It will detect if the device is configured for BIOS or UEFI and create the partition accordingly:

<#
.DESCRIPTION
    Script to create Recovery Partition during OSD and hide System Partition (if needed) on MBR

    This script requires the following optional Boot Image components: 'WinPE-DismCmdlets', 'WinPE-PowerShell', 'WinPE-StorageWMI'
.EXAMPLE
    PowerShell.exe -ExecutionPolicy ByPass -File <ScriptName>.ps1
.NOTES

    VERSION     AUTHOR              CHANGE
    1.5         Jonathan Conway     Initial script creation
#>

# Loads the Task Sequence environment
$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment

# Configures script log path to match tsenv logs folder
$LogPath = $tsenv.Value("_SMSTSLogPath")

# Determines if firmware configured as UEFI
$UEFI = $tsenv.Value("_SMSTSBootUEFI")

# Get OS Disk information
[string]$OSDrivePartitionNumber = (Get-Disk | Where-Object {$PSItem.BusType -ne 'USB'} | Get-Partition | Where-Object {$PSItem.Size -gt '5GB' -and $PSItem.Type -eq 'Basic'}).PartitionNumber

# Recovery partition size in Mb
$RecoveryPartitionSize = '2048'

If ($UEFI -eq $true) {

    'select disk 0',
    'list partition',
    "select partition $OSDrivePartitionNumber",
    "shrink desired=$RecoveryPartitionSize minimum=$RecoveryPartitionSize",
    'create partition primary',
    'format quick fs=ntfs label=Recovery',
    'set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"',
    'gpt attributes=0x8000000000000001',
    'list partition' | diskpart | Tee-Object -FilePath "$LogPath\Pwsh-OsdDiskpart.log"
}

else {
    'select disk 0',
    'list partition',
    "select partition $OSDrivePartitionNumber",
    "shrink desired=$RecoveryPartitionSize minimum=$RecoveryPartitionSize",
    'create partition primary',
    'format quick fs=ntfs label=Recovery',
    'set id=27',
    'list partition',
    'select partition 1', 'set id=17', 'list partition' | diskpart | Tee-Object -FilePath "$LogPath\Pwsh-OsdDiskpart.log"
}

The script uses variables for the OS Drive Partition and Recovery Partition Size so both of these can be modified according to specific requirements in the event that this is needed.

So this solution should allow you to correctly configure the disk partitions needed to install Windows 10 and also ensure that a functional Recovery Tools partition is always present.

/ JC

Testing ConfigMgr packages & applications before adding them into ConfigMgr using PsExec.exe

To test that an application is 99.9% sure to work when deployed via ConfigMgr it is important to initially test installers by running them in the SYSTEM context on a test machine.

Applications and Packages run under the SYSTEM context when deployed via ConfigMgr and can behave differently when compared to running them as a Local Administrator account or a standard user.

Testing them with PsExec (from the Microsoft PSTools suite – part of Microsoft Sysinternals) means that you can be pretty sure that they will work once you’ve added them into ConfigMgr but saves you time before you create the package/application, distribute the content and test in a deployment etc. only to find it fails and have to start over again.

Running the command below from an ‘Administrator’ command prompt will mimic the ConfigMgr deployment by running any commands issued in the resulting Command Prompt as the LOCAL SYSTEM account:

psexec -s -i cmd.exe

You’ll know that the command prompt is running as SYSTEM by running ‘whoami’ as per the screenshot below:

Once tested in this way, you can go ahead and add your package or application into ConfigMgr and be confident that any deployments to clients via Software Distribution or Task Sequence will be successful.

/ JC

WMI/WQL “LIKE” Query Wildcards With Examples

Quick post today.

Standard Windows/DOS wildcards don’t work in WMI “LIKE” queries as they use WQL language instead:

Multiple Characters = "%" (Percentage)
Single Character    = "_" (Underscore)

For reference, the corresponding Windows wildcards are:

Multiple Characters = "*" (Asterisk) 
Single Character    = "?" (Question Mark)

Note: when using wildcards in ConfigMgr Task Sequences pay attention to what is being done. If you’re querying a value from WMI then you should use “%” and “_” as wildcards:

SELECT * FROM Win32_ComputerSystem WHERE Name LIKE 'PC%'
SELECT * FROM Win32_ComputerSystem WHERE Name LIKE 'PC_____'

If you’re querying a Task Sequence variable then the Windows wildcards (“*” and “?” should be used:

OSDComputerName LIKE "PC*"
OSDComputerName LIKE "PC?????"

/ JC