Partitions: Recommendations and ZTIRecoveryDisk.wsf


Hopefully you have read my two posts on default MDT 2013 Update 1 (Build 8298) BIOS and UEFI Partitions, and here is what I have decided for my layout.  Before you decide to do the same, I recommend reading Microsoft Hardware’s posts on Partitions

Microsoft Hardware Dev: Hard Drives and Partitions

Microsoft Hardware Dev: UEFI/GPT-based hard drive partitions

Microsoft Hardware Dev: BIOS/MBR-based hard drive partitions

I have decided that this is how I want my Partitions for BIOS and UEFI

Partitions


For my Format and Partition Disk (BIOS) step, I will make a few changes

2015-10-27_11-41-50

  • Rename System Reserved Partition Name to System (in line with Microsoft Hardware Dev)
  • Resize the System Partition from 499MB to 984MB
  • Assign a Variable of RecoveryDisk to the System Partition (this will come in handy later)
  • Configure the Windows Partition to use 100% Remaining Space
  • Remove the Recovery Partition

For the Format and Partition Disk (UEFI) step, I will make similar changes

2015-10-27_11-56-13

  • Rename EFI Boot Partition Name to System (in line with Microsoft Hardware Dev)
  • Resize the EFI System Partition from 499MB to 200MB
  • No changes to MSR, although Microsoft Hardware Dev uses 16MB for Windows 10
  • Configure the Windows Partition to use 100% Remaining Space
  • Remove the Recovery Partition

ZTIRecoveryDisk

I’m sure you were wondering how I was going to get the Recovery Partition back.  I have added a step right after the Format and Partition Disk to run a custom script.

2015-10-27_12-00-21


On a BIOS system, it is not necessary to create a Recovery Partition if the System Partition is sized properly (the script does not validate this so you will have to edit if your System Partition is not large enough).

From Microsoft Hardware Dev:

Recovery tools partition
The Windows Recovery Environment (Windows RE) tools image (winre.wim) should be in a separate partition than the Windows partition to support automatic failover and to support booting Windows BitLocker Drive Encryption-encrypted partitions.
While this image can be included on the same partition as the system partition, we recommend that you place this partition in a separate partition, immediately after the Windows partition. This allows Windows to modify and recreate the partition later if future updates require a larger recovery image.
This partition must have enough space for the Windows Recovery Environment tools image (winre.wim, typically between 250-300MB, depending on base language and customizations added), plus enough free space so that the partition can be captured by backup utilities:
If the partition is less than 500 MB, it must have at least 50 MB of free space.
If the partition is 500 MB or larger, it must have at least 320 MB of free space.
If the partition is larger than 1 GB, we recommend that it should have at least 1 GB free.
It must have at least 320 MB of free space.
We recommend that it should have at least 1 GB free.

So while Microsoft is recommending moving it to the end, the 984MB is of sufficient size for a larger WinRE.wim.  Assuming 20MB for System Files, a 300MB WinRE.wim, and 320MB free for VSS, I should have 344MB remaining.  If this is still not enough, then Windows will create a Recovery Partition for me at the end of the drive if necessary.

2015-10-27_12-18-44

2015-10-27_12-32-40


On a UEFI system, we can see that ZTIDiskRecovery does quite a few more steps

  • Selects a free drive letter
  • Assigns a drive letter in WinPE (this will disappear after reboot)
  • Assigns the Variable RecoveryDisk to the Drive Letter in WinPE
  • Shrinks OSDisk 984MB
  • Creates a new Recovery Partition at the end of the drive

2015-10-27_12-19-31

2015-10-27_12-31-45


I will be posting the final ZTIRecoveryDisk.wsf on GitHub in the next few days after further testing.  While it has been tested in an MDT Task Sequence, I will have it validated in SCCM OSD as well.

Below is the script in its proper form sans OSD testing if you feel brave enough.

<job id="ZTIRecoveryDisk">
	<script language="VBScript" src="ZTIDiskUtility.vbs"/>
	<script language="VBScript" src="ZTIUtility.vbs"/>
	<script language="VBScript">

' // ***************************************************************************
' // 
' // File:      ZTIRecoveryDisk.wsf
' // 
' // Author:    David Segura
' // 
' // Version:   20151024
' // 
' // Purpose:   Creates a Recovery Partition for UEFI Systems
' // 
' // Usage:     cscript %ScriptRoot%\ZTIRecoveryDisk.wsf
' // 
' // ***************************************************************************

Option Explicit
RunNewInstance

'//----------------------------------------------------------------------------
'//  Global Constants
'//----------------------------------------------------------------------------
'Set the size of the Recovery Partition
	Const RECOVERY_SIZE = 984

'//----------------------------------------------------------------------------
'//  Main Class
'//----------------------------------------------------------------------------

Class ZTIRecoveryDisk

	Dim sFreeDrive
	Dim sRecoveryDisk
	Dim i
	Dim oExec
	
	'//----------------------------------------------------------------------------
	'//  Main routine
	'//----------------------------------------------------------------------------
	Function Main
	
		Dim drsAuthor		: 	drsAuthor		=	"Segura"
		Dim drsScript		: 	drsScript		=	"ZTIRecoveryDisk.wsf"
		oLogging.CreateEntry "(" & drsAuthor & ") Processing " & drsScript, LogTypeInfo
		
		'//----------------------------------------------------------------------------
		'//  Environment Check
		'//----------------------------------------------------------------------------
		If oEnvironment.Item("IsUEFI") <> "True" Then
			oLogging.CreateEntry "(" & drsAuthor & ") UEFI Requirement Not Met . . . Exiting", LogTypeInfo
			Main = SUCCESS
			EXIT Function
		End If
		
		GenerateListOfAvailableDriveLetters
		oLogging.CreateEntry "Free Drive Letter(s): " & sFreeDrive , LogTypeInfo

		oUtility.GetMajorMinorVersion(oEnvironment.Item("ImageBuild"))
		
		'//----------------------------------------------------------------------------
		'//  Assign Recovery Partition a Drive Letter in WinPE
		'//----------------------------------------------------------------------------
		sRecoveryDisk = left(GetLastAvailableDriveLetter, 1)
		oEnvironment.Item("RecoveryDisk") = sRecoveryDisk
		oLogging.CreateEntry "(" & drsAuthor & ") Recovery Partition will be assigned letter " & oEnvironment.Item("RecoveryDisk") & " in WinPE", LogTypeInfo
		
		oLogging.CreateEntry "(" & drsAuthor & ") Creating Recovery Partition", LogTypeInfo
		'//----------------------------------------------------------------------------
		'//  Open an instance for diskpart.exe, and dynamically pipe the commands to the program.
		'//----------------------------------------------------------------------------
		set oExec = oUtility.RunCommandStart("Diskpart.exe", empty)
		oUtility.RunCommandWrite oExec, "RESCAN"  ' Just to be sure.
		oUtility.RunCommandWrite oExec, "LIST DISK"
		oUtility.RunCommandWrite oExec, "LIST VOLUME"
		oUtility.RunCommandWrite oExec, "SEL VOL " & oEnvironment.Item("OSDisk")
		oUtility.RunCommandWrite oExec, "SHRINK MINIMUM=" & RECOVERY_SIZE
		oUtility.RunCommandWrite oExec, "CREATE PARTITION PRIMARY"
		oUtility.RunCommandWrite oExec, "FORMAT QUICK FS=NTFS LABEL=""Recovery"""
		oUtility.RunCommandWrite oExec, "ASSIGN LETTER=" & sRecoveryDisk
		oUtility.RunCommandWrite oExec, "SET ID=""de94bba4-06d1-4d40-a16a-bfd50179d6ac"""
		oUtility.RunCommandWrite oExec, "GPT ATTRIBUTES=0x8000000000000001"
		oUtility.RunCommandWrite oExec, "DETAIL PARTITION"
		oUtility.RunCommandWrite oExec, "DETAIL VOLUME"
		
	End Function
	'// END MAIN

	'//---------------------------------------------------------------------------
	'//  Support Routines 
	'//---------------------------------------------------------------------------
	
	Function GenerateListOfAvailableDriveLetters

		Dim i
		For i = asc("C") to asc("W")
			If not ofso.DriveExists(chr(i)+":") and i <> asc("S") and i <> asc("M") then
				sFreeDrive = trim(sFreeDrive & " " & chr(i)+":")
			End If
		Next

	End Function

	Function GetNextAvailableDriveLetter

		TestAndFail len(Trim(sFreeDrive)) > 0, 7817, "Verify There are Free drives available."
		GetNextAvailableDriveLetter = left(trim(sFreeDrive),2)
		oLogging.CreateEntry "Pop next Drive Letter: [" & GetNextAvailableDriveLetter & "]", LogTypeVerbose
		sFreeDrive = mid(trim(sFreeDrive),4)

	End Function

	Function GetLastAvailableDriveLetter

		TestAndFail len(Trim(sFreeDrive)) > 0, 7817, "Verify There are Free drives available."
		GetLastAvailableDriveLetter = right(trim(sFreeDrive),2)
		oLogging.CreateEntry "Pop next Drive Letter: [" & GetLastAvailableDriveLetter & "]", LogTypeVerbose
		sFreeDrive = replace(sFreeDrive,GetLastAvailableDriveLetter,"")

	End Function
	
End Class
	
	</script>
</job>

Advertisements