摘要

本文說明如何使用Microsoft提供的範例腳本來增加修復磁碟分區大小,以啟用 WinRE) (Windows 修復環境的維護。 WinRE 是一項可協助您疑難解答及復原各種系統問題的工具,例如啟動失敗、惡意代碼感染或系統檔案損毀。

WinRE 需要足夠的修復磁碟分區空間,才能成功安裝 WinRE 更新。 不過,有些裝置的修復磁碟分區空間可能很小。 範例腳本可協助您調整裝置修復磁碟分區大小,以避免潛在的 WinRE 維護失敗。

如何使用此腳本將 WinRE 磁碟分區大小增加 250 MB

################################################################################################

#

# Copyright (c) Microsoft Corporation.

# Licensed under the MIT License.

#

# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

# SOFTWARE.

#

################################################################################################

Param (
[Parameter(Mandatory=$false,HelpMessage="Skip confirmation")][bool]$SkipConfirmation=$false,
[Parameter(Mandatory=$true,HelpMessage="Path to backup old WinRE partition content to")][string]$BackupFolder
)

# ------------------------------------
# Helper functions
# ------------------------------------

# Log message
function LogMessage([string]$message)
{
    $message = "$message"
    Write-Host $message
}

# Extract numbers from string
function ExtractNumbers([string]$str)
{
    $cleanString = $str -replace "[^0-9]"
    return [long]$cleanString
}

# Display partition info using fsutil
# Return an array, the first value is total size and the second value is free space
function DisplayPartitionInfo([string[]]$partitionPath)
{
    $volume = Get-WmiObject -Class Win32_Volume | Where-Object { $partitionPath -contains $_.DeviceID }
    LogMessage("  Partition capacity: " +  $volume.Capacity)
    LogMessage("  Partition free space: " + $volume.FreeSpace)
    return $volume.Capacity, $volume.FreeSpace
} 

# Display WinRE status
function DisplayWinREStatus()
{
    # Get WinRE partition info
    $WinREInfo = Reagentc /info
    foreach ($line in $WinREInfo)
    {
        $params = $line.Split(':')
        if ($params.Count -lt 2)
        {
            continue
        }
        if (($params[1].Trim() -ieq "Enabled") -Or (($params[1].Trim() -ieq "Disabled")))
        {
            $Status = $params[1].Trim() -ieq "Enabled"
            LogMessage($line.Trim())
        }
        if ($params[1].Trim() -like "\\?\GLOBALROOT*")
        {
            $Location = $params[1].Trim()
            LogMessage($line.Trim())
        }
    }
    
    return $Status, $Location
}

# ------------------------------------
# Main execution
# ------------------------------------

# Clear the error
$Error.Clear()

# ------------------------------------
# Examining the system to collect required info 
# for the execution
# Need to check WinRE status, collect OS and WinRE
# partition info
# ------------------------------------
LogMessage("Start time: $([DateTime]::Now)")

LogMessage("Examining the system...")
$NeedShrink = $true
$NeedCreateNew = $false
$NeedBackup = $false

# Get WinRE partition info
$InitialWinREStatus = DisplayWinREStatus
$WinREStatus = $InitialWinREStatus[0]
$WinRELocation = $InitialWinREStatus[1]

if (!$WinREStatus)
{
    LogMessage("Error: WinRE Disabled")
    exit 1
}

# Get System directory and ReAgent xml file
$system32Path = [System.Environment]::SystemDirectory
LogMessage("System directory: " + $system32Path)
$ReAgentXmlPath = Join-Path -Path $system32Path -ChildPath "\Recovery\ReAgent.xml"
LogMessage("ReAgent xml: " + $ReAgentXmlPath)
if (!(Test-Path  $ReAgentXmlPath))
{
    LogMessage("Error: ReAgent.xml cannot be found")
    exit 1
}

# Get OS partition
LogMessage("")
LogMessage("Collecting OS and WinRE partition info...")
$OSDrive = $system32Path.Substring(0,1)
$OSPartition = Get-Partition -DriveLetter $OSDrive

# Get WinRE partition
$WinRELocationItems = $WinRELocation.Split('\\')
foreach ($item in $WinRELocationItems)
{
    if ($item -like "harddisk*")
    {
        $OSDiskIndex = ExtractNumbers($item)
    }
    if ($item -like "partition*")
    {
        $WinREPartitionIndex = ExtractNumbers($item)
    }
}

LogMessage("OS Disk: " + $OSDiskIndex)
LogMessage("OS Partition: " + $OSPartition.PartitionNumber)
LogMessage("WinRE Partition: " + $WinREPartitionIndex)

$WinREPartition = Get-Partition -DiskNumber $OSDiskIndex -PartitionNumber $WinREPartitionIndex

$diskInfo = Get-Disk -number $OSDiskIndex
$diskType = $diskInfo.PartitionStyle
LogMessage("Disk PartitionStyle: " + $diskType)

# Display WinRE partition size info
LogMessage("WinRE partition size info")
$WinREPartitionSizeInfo = DisplayPartitionInfo($WinREPartition.AccessPaths)
LogMessage("WinRE Partition Offset: " + $WinREPartition.Offset)
LogMessage("WinRE Partition Type: " + $WinREPartition.Type)
LogMessage("OS partition size: " + $OSPartition.Size)
LogMessage("OS partition Offset: " + $OSPartition.Offset)
$OSPartitionEnds = $OSPartition.Offset + $OSPartition.Size

LogMessage("OS partition ends at: " + $OSPartitionEnds)
LogMessage("WinRE partition starts at: " + $WinREPartition.Offset)

$WinREIsOnSystemPartition = $false
if ($diskType -ieq "MBR")
{
    if ($WinREPartition.IsActive)
    {
        LogMessage("WinRE is on System partition")
        $WinREIsOnSystemPartition = $true
    }
}

if ($diskType -ieq "GPT")
{
    if ($WinREPartition.Type -ieq "System")
    {
        LogMessage("WinRE is on System partition")
        $WinREIsOnSystemPartition = $true
    }
}

# Checking the BackupFolder parameter
if ($PSBoundParameters.ContainsKey('BackupFolder'))
{
    LogMessage("")
    LogMessage("Backup Directory: [" + $BackupFolder + "]")
    
    $Needbackup = $true
    
    if ($WinREIsOnSystemPartition)
    {
        $Needbackup = $false
        LogMessage("WinRE is on System partition which will be preserved. No need to backup content")
    }
    else
    {
        if (Test-path $BackupFolder)
        {
            $items = Get-ChildItem -Path $BackupFolder

            if ($items)
            {
                LogMessage("Error: Existing backup directory is not empty")
                exit 1
            }
        }
        else
        {
            LogMessage("Creating backup directory...")
            try 
            {
                $item = New-Item -Path $BackupFolder -ItemType Directory -ErrorAction Stop

                if ($item)
                {
                    LogMessage("Backup directory created")
                }
                else
                {
                    LogMessage("Error: Failed to create backup directory [" + $BackupFolder + "]")
                    exit 1
                }
            } catch 
            {
                LogMessage("Error: An error occurred: $_")
                exit 1
            }
        }
    }
}

# ------------------------------------
# Verify whether we meet requirements of execution
# - WinRE cannot be on OS partition for the extension
# - WinRE partition must be the next partition after OS partition
# - If WinRE partition already have >=250MB free space, no need to do repartition
# - 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("")
LogMessage("Verifying if the WinRE partition needs to be extended or not...")

if (!(($diskType -ieq "MBR") -Or ($diskType -ieq "GPT")))
{
    LogMessage("Error: Got an unexpected disk partition style: " +$diskType)
    exit 1
}

# WinRE partition must be after OS partition for the repartition
if ($WinREPartitionIndex -eq $OSPartition.PartitionNumber)
{
    LogMessage("WinRE and OS are on the same partition, should not perform extension")
    exit 0
}

$supportedSize = Get-PartitionSupportedSize -DriveLetter $OSDrive

# if there is enough free space, skip extension
if ($WinREPartitionSizeInfo[1] -ge 250MB)
{
    LogMessage("More than 250 MB of free space was detected in the WinRE partition, there is no need to extend the partition")
    exit 0
}

if ($WinREPartition.Offset -lt $OSPartitionEnds)
{
    LogMessage("WinRE partition is not after OS partition, cannot perform extension")
    LogMessage("Need to create a new WinRE partition after OS partition")
    $NeedCreateNew = $true
    $NeedShrink = $true
    
    # Calculate the size of repartition
    # Will create a new WinRE partition with current WinRE partition size + 250 MB
    # The OS partition size will be shrunk by the new WinRE partition size
    $targetWinREPartitionSize = $WinREPartitionSizeInfo[0] + 250MB
    $shrinkSize = [Math]::Ceiling($targetWinREPartitionSize / 1MB) * 1MB
    $targetOSPartitionSize = $OSPartition.Size - $shrinkSize
    if ($targetOSPartitionSize -lt $supportedSize.SizeMin)
    {
        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")
        LogMessage("Error: Got unexpected disk layout, cannot proceed")
        exit 1
    }
    if (!($WinREPartitionIndex -eq ($OSPartition.PartitionNumber + 1)))
    {
        LogMessage("Error: WinRE partition is not right after the OS partition, cannot extend WinRE partition")
        exit 1
    }

    # Calculate the size of repartition
    # Will shrink OS partitition by 250 MB
    $shrinkSize = 250MB
    $targetOSPartitionSize = $OSPartition.Size - $shrinkSize
    $targetWinREPartitionSize = $WinREPartitionSizeInfo[0] + 250MB

    $UnallocatedSpace = $WinREPartition.Offset - $OSPartitionEnds;

    # If there is unallocated space, consider using it
    if ($UnallocatedSpace -ge 250MB)
    {
        $UnallocatedSpace = $WinREPartition.Offset - $OSPartitionEnds;
        LogMessage("Found unallocated space between OS and WinRE partition: " + $UnallocatedSpace)
        LogMessage("There is already enough space to extend WinRE partition without shrinking the OS partition")
        $NeedShrink = $false
        $targetOSPartitionSize = 0
    }
    else
    {
        $shrinkSize = [Math]::Ceiling((250MB - $UnallocatedSpace)/ 1MB) * 1MB
        if ($shrinkSize > 250MB)
        {
            $shrinkSize = 250MB
        }
        $targetOSPartitionSize = $OSPartition.Size - $shrinkSize
        if ($targetOSPartitionSize -lt $supportedSize.SizeMin)
        {
            LogMessage("Error: The target OS partition size after shrinking is smaller than the supported minimum size, cannot perform the repartition")
            exit 1
        }
    }
}

# ------------------------------------
# Report execution plan and ask for user confirmation to continue
# ------------------------------------

# Report the changes planned to be executed, waiting for user confirmation
LogMessage("")
LogMessage("Summary of proposed changes")
if ($NeedCreateNew)
{
    LogMessage("Note: WinRE partition is before OS partition, need to create a new WinRE partition after OS partition")
    LogMessage("Will shrink OS partition by " + $shrinkSize)
    LogMessage("  Current OS partition size: " + $OSPartition.Size)
    LogMessage("  Target OS partition size after shrinking: " + $targetOSPartitionSize)
    LogMessage("New WinRE partition will be created with size: ", $targetWinREPartitionSize)
    if ($WinREIsOnSystemPartition)
    {
        LogMessage("Existing WinRE partition is also system partition, it will be preserved")
    }
    else
    {
        LogMessage("Existing WinRE partition will be deleted")
        LogMessage("  WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex + "]")
        LogMessage("  Current WinRE partition size: " + $WinREPartitionSizeInfo[0])
    }
}
else
{
    if ($NeedShrink)
    {
        LogMessage("Will shrink OS partition by " + $shrinkSize)
        LogMessage("  Current OS partition size: " + $OSPartition.Size)
        LogMessage("  Target OS partition size after shrinking: " + $targetOSPartitionSize)
        if ($UnallocatedSpace -ge 0)
        {
            LogMessage("Unallocated space between OS and WinRE partition that will be used towards the new WinRE partition: " + $UnallocatedSpace)
        }
    }
    else
    {
        LogMessage("Will use 250MB from unallocated space between OS and WinRE partition")
    }

    LogMessage("Will extend WinRE partition size by 250MB")
    LogMessage("  WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex + "]")
    LogMessage("  Current WinRE partition size: " + $WinREPartitionSizeInfo[0])
    LogMessage("  New WinRE partition size:     " + $targetWinREPartitionSize)
    LogMessage("WinRE will be temporarily disabled before extending the WinRE partition and enabled automatically in the end")

    if ($UnallocatedSpace -ge 100MB)
    {
        LogMessage("Warning: More than 100MB of unallocated space was detected between the OS and WinRE partitions")
        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")
    LogMessage("Proceeding with changes...")
}
else
{
    $userInput = Read-Host -Prompt "Would you like to proceed? Y for Yes and N for No"
        
    if ($userInput -ieq "Y")
    {
        LogMessage("Proceeding with changes...")
    }
    elseif ($userInput -ieq "N")
    {
        LogMessage("Canceling based on user request, no changes were made to the system")
        exit 0
    }
    else
    {
        LogMessage("Error: Unexpected user input: [" + $userInput + "]") 
        exit 0
    }
}

LogMessage("")
LogMessage("Note: To prevent unexpected results, please do not interrupt the execution or restart your system")

# ------------------------------------
# Do the actual execution
# The main flow is:
# 1. Check whether ReAgent.xml has stage location and clear it for repartiion
# 2. Disable WinRE as WinRE partition will be deleted
# 3. Perform the repartition to create a larger WinRE partition
# 4. Re-enable WinRE
# ------------------------------------

LogMessage("")

# Load ReAgent.xml to clear Stage location
LogMessage("Loading [" + $ReAgentXmlPath + "] ...")
$xml = [xml](Get-Content -Path $ReAgentXmlPath)
$node = $xml.WindowsRE.ImageLocation
if (($node.path -eq "") -And ($node.guid -eq "{00000000-0000-0000-0000-000000000000}") -And ($node.offset -eq "0") -And ($node.id -eq "0"))
{
    LogMessage("Stage location info is empty")
}
else
{
    LogMessage("Clearing stage location info...")
    $node.path = ""
    $node.offset = "0"
    $node.guid= "{00000000-0000-0000-0000-000000000000}"
    $node.id="0"

    # Save the change
    LogMessage("Saving changes to [" + $ReAgentXmlPath + "]...")
    $xml.Save($ReAgentXmlPath)
}

# Disable WinRE
LogMessage("Disabling WinRE...")
reagentc /disable
if (!($LASTEXITCODE -eq 0))
{
    LogMessage("Warning: encountered an error when disabling WinRE: " + $LASTEXITCODE)
    exit $LASTEXITCODE
}

# Verify WinRE is under C:\Windows\System32\Recovery\WinRE.wim
$disableWinREPath = Join-Path -Path $system32Path -ChildPath "\Recovery\WinRE.wim"
LogMessage("Verifying that WinRE wim exists in downlevel at default location")
if (!(Test-Path $disableWinREPath))
{
    LogMessage("Error: Cannot find " + $disableWinREPath)
    
    # Re-enable WinRE
    LogMessage("Re-enabling WinRE on error...")
    reagentc /enable
    if (!($LASTEXITCODE -eq 0))
    {
        LogMessage("Warning: encountered an error when enabling WinRE: " + $LASTEXITCODE)
    }
    exit 1
}

# ------------------------------------
# Perform the repartition
# 1. Resize the OS partition
# 2. Delete the WinRE partition
# 3. Create a new WinRE partition
# ------------------------------------
LogMessage("Performing repartition to extend the WinRE partition ...")

# 1. Resize the OS partition
if ($NeedShrink)
{
    LogMessage("Shrinking the OS partition to create a larger WinRE partition")
    LogMessage("Resizing the OS partition to: [" + $targetOSPartitionSize + "]...")
    Resize-Partition -DriveLetter $OSDrive -Size $targetOSPartitionSize
    if ($Error.Count -gt 0) {
        LogMessage("Error: Resize-Partition encountered errors: " + $Error[0].Exception.Message)
        
        # Re-enable WinRE
        LogMessage("Re-enabling WinRE on error...")
        reagentc /enable
        if (!($LASTEXITCODE -eq 0))
        {
            LogMessage("Warning: encountered an error when enabling WinRE: " + $LASTEXITCODE)
        }
        exit 1
    }
    $OSPartitionAfterShrink = Get-Partition -DriveLetter $OSDrive
    LogMessage("Target partition size: " + $targetOSPartitionSize)
    LogMessage("Size of OS partition after shrinking: " + $OSPartitionAfterShrink.Size)
}

# 2. Delete the WinRE partition
LogMessage("")

if ($WinREIsOnSystemPartition)
{
    LogMessage("Existing WinRE partition is System partition, skipping deletion")
}
else
{    
    # If requested by user, backup rest of the content on WinRE partition to backup directory
    if ($Needbackup)
    {
        $sourcePath = $WinREPartition.AccessPaths[0] 
        LogMessage("Copying content on WinRE partition from [" + $sourcePath + "] to [" + $BackupFolder + "]...")
        
        # Copy-Item may have access issue with certain system folders, enumerate the children items and exlcude them
        $items = Get-ChildItem -LiteralPath $sourcePath -Force
        foreach ($item in $items)
        {
            if ($item.Name -ieq "System Volume Information")
            {
                continue
            }
            $sourceItemPath = Join-Path -Path $sourcePath -ChildPath $item.Name
            $destItemPath = Join-Path -Path $BackupFolder -ChildPath $item.Name
            try 
            {
                LogMessage("Copying [" + $sourceItemPath + "] to [" + $destItemPath + "]...")
                Copy-Item -LiteralPath $sourceItemPath -Destination $destItemPath -Recurse -Force
            } catch 
            {
                LogMessage("Error: An error occurred during copy: $_")
                exit 1
            }
        }
        
        LogMessage("Backup completed")
        LogMessage("")
    }

    LogMessage("Deleting WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex + "]...")
    Remove-Partition -DiskNumber $OSDiskIndex -PartitionNumber $WinREPartitionIndex -Confirm:$false
    if ($Error.Count -gt 0) {
        LogMessage("Error: Remove-Partition encountered errors: " + $Error[0].Exception.Message)
        exit 1
    }
}

# A short sleep for the partition change
Sleep 5

# 3. Create a new WinRE partition
LogMessage("")
LogMessage("Creating new WinRE partition...")
LogMessage("Target size: " + $targetWinREPartitionSize)
if ($diskType -ieq "GPT")
{
    $partition = New-Partition -DiskNumber $OSDiskIndex -Size $targetWinREPartitionSize -GptType "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}"
    
    $newPartitionIndex = $partition.PartitionNumber
    # A short sleep to make sure the partition is ready for formatting
    Sleep 2

    LogMessage("Formating the partition...")
    $result = Format-Volume -Partition $partition -FileSystem NTFS -Confirm:$false
    if ($Error.Count -gt 0) {
        LogMessage("Error: Format-Volume encountered errors: " + $Error[0].Exception.Message)
        exit 1
    }
}
else
{
    #$partition = New-Partition -DiskNumber $OSDiskIndex -Size $targetWinREPartitionSize -MbrType 0x27
    $targetWinREPartitionSizeInMb = [int]($targetWinREPartitionSize/1MB)
    $diskpartScript = 
@"
select disk $OSDiskIndex
create partition primary size=$targetWinREPartitionSizeInMb id=27
format quick fs=ntfs label="Recovery"
set id=27
"@

    $TempPath = $env:Temp
    $diskpartSciptFile = Join-Path -Path $TempPath -ChildPath "\ExtendWinRE_MBR_PowershellScript.txt"
    
    LogMessage("Creating temporary diskpart script to create Recovery partition on MBR disk...")
    LogMessage("Temporary diskpart script file: " + $diskpartSciptFile)
    $diskpartScript | Out-File -FilePath $diskpartSciptFile -Encoding ascii
    
    LogMessage("Executing diskpart script...")
    try 
    {
        $diskpartOutput = diskpart /s $diskpartSciptFile
        
        if ($diskpartOutput -match "DiskPart successfully") 
        {
            LogMessage("Diskpart script executed successfully")
        }
        else
        {
            LogMessage("Error executing diskpart script:" + $diskpartOutput)
            exit 1
        }
        LogMessage("Deleting temporary diskpart script file...")
        Remove-Item $diskpartSciptFile
    }
    catch 
    {
        LogMessage("Error executing diskpart script: $_")
        exit 1
    }
    
    $vol = Get-Volume -FileSystemLabel "Recovery"
    $newPartitionIndex = (Get-Partition | Where-Object { $_.AccessPaths -contains $vol.Path } ).PartitionNumber
}

if ($Error.Count -gt 0) 
{
    LogMessage("Error: New-Partition encountered errors: " + $Error[0].Exception.Message)
    exit 1
}

LogMessage("New Partition index: " + $newPartitionIndex)

# Re-enable WinRE
LogMessage("Re-enabling WinRE...")
reagentc /enable
if (!($LASTEXITCODE -eq 0))
{
    LogMessage("Warning: encountered an error when enabling WinRE: " + $LASTEXITCODE)
    exit $LASTEXITCODE
}

# In the end, Display WinRE status to verify WinRE is enabled correctly
LogMessage("")
LogMessage("WinRE Information:")
$FinalWinREStatus = DisplayWinREStatus
$WinREStatus = $FinalWinREStatus[0]
$WinRELocation = $FinalWinREStatus[1]

if (!$WinREStatus)
{
    LogMessage("Warning: WinRE Disabled")
}

$WinRELocationItems = $WinRELocation.Split('\\')
foreach ($item in $WinRELocationItems)
{
    if ($item -like "partition*")
    {
        $WinREPartitionIndex = ExtractNumbers($item)
    }
}
LogMessage("WinRE Partition Index: " + $WinREPartitionIndex)

$WinREPartition = Get-Partition -DiskNumber $OSDiskIndex -PartitionNumber $WinREPartitionIndex
$WinREPartitionSizeInfoAfter = DisplayPartitionInfo($WinREPartition.AccessPaths)

LogMessage("")
LogMessage("OS Information:")
$OSPartition = Get-Partition -DriveLetter $OSDrive
LogMessage("OS partition size: " + $OSPartition.Size)
LogMessage("OS partition Offset: " + $OSPartition.Offset)

if (!($WinREPartitionIndex -eq $newPartitionIndex))
{
    LogMessage("Warning: WinRE is installed to partition [" + $WinREPartitionIndex +"], but the newly created Recovery partition is [" + $newPartitionIndex + "]")
}

LogMessage("End time: $([DateTime]::Now)")

if ($NeedBackup)
{
    LogMessage("")
    LogMessage("The contents of the old WinRE partition has been backed up to [" + $BackupFolder + "]")
}

LogMessage("")
LogMessage("Successfully completed the operation")

執行範例腳本的步驟

若要執行此範例文稿,請依照下列步驟執行:

  1. 開啟文字編輯器。 例如,若要開啟 Windows 記事本,請以滑鼠右鍵按兩下 [ 開始],按兩下 [ 執行],輸入 notepad.exe,然後按兩下 [ 確定]

  2. 將範例文稿複製並貼到開啟的文字編輯器。

  3. 將腳本檔案 儲存為Powershell_ExtendWinRE_or_CreateNew.ps1 至您選擇的位置。 例如,將腳本檔案儲存至 C://Documents/WinRE_Script請注意此位置路徑,就像您在步驟 7 中使用此位置一樣。

  4. 重新啟動您的裝置。 這很重要,因為您的裝置上可能有擱置中的磁碟分區作業,必須先完成,腳本才能安全地增加 WinRE 磁碟分區大小。

  5. 裝置重新啟動之後,以系統管理員身分開啟PowerShell。 其中一個方法是以滑鼠右鍵按兩下 [開始],然後按下 [終端機 (管理員) ] 。

  6. 輸入 mkdir <新備份目錄> 路徑,然後按 Enter。 例如,輸入 mkdir C:/WinRE_backup,然後按 Enter這會建立名為「WinRE_backup」的備份目錄,腳本可能會在還原原始磁碟分區失敗時使用。 請注意此備份目錄的位置。

  7. 輸入 Powershell.exe -ExecutionPolicy Bypass -File <您儲存 winre 腳本>位置的路徑 。 例如,輸入 Powershell.exe -ExecutionPolicy Bypass -File C:/Downloads/WinRE_Script

注意事項

  • 假設腳本成功完成,您的裝置現在將至少有 250 MB 的可用空間,並且可以安裝 WinRE 維護更新。

  • 刪除您在步驟 3 中建立的備份目錄,因為它已不再需要。 例如,刪除 C:/WinRE_backup 目錄。

您可能會遇到的問題,以及如何修正問題

如果您從腳本收到下列錯誤訊息,表示裝置上的可用空間不足,無法完成重新分區。 在此情況下,請遵循Microsoft釋放 Windows 磁碟驅動器空間的指導方針。 完成之後,請重新啟動裝置,然後再次執行腳本。

注意 有些裝置的操作系統磁碟分區可能有足夠的可用空間,但是磁碟驅動器太分散,而且會無法執行磁碟分區。 在此情況下,請使用本指南來 重組您的磁碟

此文稿假設您已啟用 WinRE。 如果您收到此錯誤訊息,表示您的裝置沒有啟用 WinRE 磁碟分區。 對於某些工作負載,裝置建立者可能會選擇不包含 WinRE 磁碟分區。 如果您的裝置沒有 WinRE 磁碟分區,則不需要維護。  如果您的 WinRE 磁碟分區發生問題,請依照 WinRE 疑難解答功能中的步驟進行。

當您嘗試在具有自定義磁碟分區版面配置的裝置上執行此腳本時,可能會遇到問題,其中裝置在操作系統 (操作系統) 磁碟分區與修復磁碟分區之間有另一個磁碟分區。 若要解決此問題,您需要移動或刪除操作系統磁碟分區與修復磁碟分區之間的磁碟分區,讓修復磁碟分區具有與操作系統磁碟分區 + 1 相同的索引。 

例如,如果操作系統磁碟分區為索引 2,則修復磁碟分區應為索引 3。  請小心不要刪除或修改任何重要的磁碟分區區,例如系統或開機磁碟分區。 移動或刪除磁碟分區區之後,您需要重新啟動裝置以套用變更並更新磁碟分區索引。 然後,您可以再次執行腳本,它應該可以如預期般運作。

Need more help?

Want more options?

探索訂閱權益、瀏覽訓練課程、瞭解如何保護您的裝置等等。