Winre
Winre
[Parameter(Mandatory=$false,HelpMessage="Skip confirmation")][bool]$SkipConfirmation=$false,
# ------------------------------------
# Helper functions
# ------------------------------------
# Log message
function LogMessage([string]$message)
$message = "$message"
Write-Host $message
function ExtractNumbers([string]$str)
return [long]$cleanString
# Return an array, the first value is total size and the second value is free space
function DisplayPartitionInfo([string[]]$partitionPath)
function DisplayWinREStatus()
$params = $line.Split(':')
if ($params.Count -lt 2)
continue
LogMessage($line.Trim())
$Location = $params[1].Trim()
LogMessage($line.Trim())
}
# ------------------------------------
# Main execution
# ------------------------------------
$Error.Clear()
# ------------------------------------
# partition info
# ------------------------------------
$NeedShrink = $true
$NeedCreateNew = $false
$NeedBackup = $false
$InitialWinREStatus = DisplayWinREStatus
$WinREStatus = $InitialWinREStatus[0]
$WinRELocation = $InitialWinREStatus[1]
if (!$WinREStatus)
exit 1
$system32Path = [System.Environment]::SystemDirectory
if (!(Test-Path $ReAgentXmlPath))
exit 1
# Get OS partition
LogMessage("")
$OSDrive = $system32Path.Substring(0,1)
$WinRELocationItems = $WinRELocation.Split('\\')
$OSDiskIndex = ExtractNumbers($item)
$WinREPartitionIndex = ExtractNumbers($item)
$diskType = $diskInfo.PartitionStyle
$WinREPartitionSizeInfo = DisplayPartitionInfo($WinREPartition.AccessPaths)
if ($WinREPartition.IsActive)
$WinREIsOnSystemPartition = $true
$WinREIsOnSystemPartition = $true
if ($PSBoundParameters.ContainsKey('BackupFolder'))
LogMessage("")
$Needbackup = $true
if ($WinREIsOnSystemPartition)
$Needbackup = $false
else
if (Test-path $BackupFolder)
if ($items)
exit 1
else
try
if ($item)
{
LogMessage("Backup directory created")
else
exit 1
} catch
exit 1
# ------------------------------------
# - If there is enough unallocated space to grow the WinRE partition size, skip shrinking OS
# However, if the WinRE partition is before the OS partition, there is no chance to extend it
# As a result, it's better to create a new WinRE partition after the OS partition
# ------------------------------------
# Perform a few checks
LogMessage("")
exit 1
LogMessage("WinRE and OS are on the same partition, should not perform extension")
exit 0
LogMessage("More than 500 MB of free space was detected in the WinRE partition, there is no
need to extend the partition")
exit 0
$NeedShrink = $true
# Will create a new WinRE partition with current WinRE partition size + 500 MB
# The OS partition size will be shrunk by the new WinRE partition size
LogMessage("Error: The target OS partition size after shrinking is smaller than the
supported minimum size, cannot perform the repartition")
exit 1
else
if ($WinREIsOnSystemPartition)
LogMessage("WinRE parititon is after the OS partition and it's also System partition")
exit 1
{
LogMessage("Error: WinRE partition is not right after the OS partition, cannot extend
WinRE partition")
exit 1
$shrinkSize = 500MB
$NeedShrink = $false
$targetOSPartitionSize = 0
else
$shrinkSize = 500MB
}
exit 1
# ------------------------------------
# ------------------------------------
LogMessage("")
if ($NeedCreateNew)
LogMessage("Note: WinRE partition is before OS partition, need to create a new WinRE partition
after OS partition")
if ($WinREIsOnSystemPartition)
{
LogMessage("Existing WinRE partition is also system partition, it will be preserved")
else
else
if ($NeedShrink)
if ($UnallocatedSpace -ge 0)
else
LogMessage(" WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex +
"]")
LogMessage("WinRE will be temporarily disabled before extending the WinRE partition and
enabled automatically in the end")
LogMessage("Would you like to proceed by using the unallocated space between the OS
and the WinRE partitions?")
if ($Needbackup)
LogMessage("")
LogMessage("The contents of the old WinRE partition will be backed up to [" + $BackupFolder +
"]")
LogMessage("")
LogMessage("Please reboot the device before running this script to ensure any pending partition actions
are finalized")
LogMessage("")
if ($SkipConfirmation)
{
LogMessage("User chose to skip confirmation")
else
$userInput = Read-Host -Prompt "Would you like to proceed? Y for Yes and N for No"
exit 0
else
exit 0
LogMessage("")
LogMessage("Note: To prevent unexpected results, please do not interrupt the execution or restart your
system")
# ------------------------------------
# Do the actual execution
# 1. Check whether ReAgent.xml has stage location and clear it for repartiion
# 4. Re-enable WinRE
# ------------------------------------
LogMessage("")
$node = $xml.WindowsRE.ImageLocation
else
$node.path = ""
$node.offset = "0"
$node.guid= "{00000000-0000-0000-0000-000000000000}"
$node.id="0"
# Disable WinRE
LogMessage("Disabling WinRE...")
reagentc /disable
exit $LASTEXITCODE
if (!(Test-Path $disableWinREPath))
# Re-enable WinRE
reagentc /enable
exit 1
}
# ------------------------------------
# ------------------------------------
if ($NeedShrink)
if ($Error.Count -gt 0) {
# Re-enable WinRE
reagentc /enable
}
exit 1
LogMessage("")
if ($WinREIsOnSystemPartition)
else
# If requested by user, backup rest of the content on WinRE partition to backup directory
if ($Needbackup)
$sourcePath = $WinREPartition.AccessPaths[0]
# Copy-Item may have access issue with certain system folders, enumerate the children
items and exlcude them
{
if ($item.Name -ieq "System Volume Information")
continue
try
} catch
exit 1
LogMessage("Backup completed")
LogMessage("")
if ($Error.Count -gt 0) {
LogMessage("Error: Remove-Partition encountered errors: " +
$Error[0].Exception.Message)
exit 1
Sleep 5
LogMessage("")
$newPartitionIndex = $partition.PartitionNumber
Sleep 2
if ($Error.Count -gt 0) {
exit 1
}
else
$targetWinREPartitionSizeInMb = [int]($targetWinREPartitionSize/1MB)
$diskpartScript =
@"
set id=27
"@
$TempPath = $env:Temp
try
else
exit 1
Remove-Item $diskpartSciptFile
catch
exit 1
if ($Error.Count -gt 0)
exit 1
}
LogMessage("New Partition index: " + $newPartitionIndex)
# Re-enable WinRE
LogMessage("Re-enabling WinRE...")
reagentc /enable
exit $LASTEXITCODE
LogMessage("")
LogMessage("WinRE Information:")
$FinalWinREStatus = DisplayWinREStatus
$WinREStatus = $FinalWinREStatus[0]
$WinRELocation = $FinalWinREStatus[1]
if (!$WinREStatus)
$WinRELocationItems = $WinRELocation.Split('\\')
$WinREPartitionIndex = ExtractNumbers($item)
}
$WinREPartitionSizeInfoAfter = DisplayPartitionInfo($WinREPartition.AccessPaths)
LogMessage("")
LogMessage("OS Information:")
if ($NeedBackup)
LogMessage("")
LogMessage("The contents of the old WinRE partition has been backed up to [" + $BackupFolder
+ "]")
LogMessage("")