Loading

Windows自动部署镜像

WinPE + Windows 10 全自动化部署实践指南

本指南教程采用 WinPE + Unattend.xml 方案实现 Windows 10 家庭版的全自动化部署,包括分区解析、应答文件配置、登录自动化。


一、环境准备

必备软件及下载地址

  1. Windows ADK(Assessment and Deployment Kit)

  2. Windows PE Add-on for ADK

  3. 7-Zip

配置 7-Zip 为全局变量

为便于后续命令行操作,建议将 7-Zip 安装目录添加至系统 PATH:

setx /M PATH "%PATH%;C:\Program Files\7-Zip"

注意:请确认 7-Zip 安装在默认路径 C:\Program Files\7-Zip,如果不同,请修改路径后再执行。


二、构建 WinPE 环境

步骤 1:以管理员资格打开命令行

开始 > Windows Kits > Deployment and Imaging Tools Environment(部署和映像工具环境) > 以管理员身份运行

该命令行环境自动设置好 DISM 工具和所需环境变量,是构建 PE 镜像的推荐入口。

步骤 2:清理旧目录(如有)

dism /Unmount-Image /MountDir:C:\WinPE_amd64\mount /Discard
rd /s /q C:\WinPE_amd64

步骤 3:创建 WinPE 工作目录

copype amd64 C:\WinPE_amd64

该命令将创建如下目录结构:

C:\WinPE_amd64\
├── Media\             # 最终生成 ISO 的目录结构
│   └── sources\       # 包含 boot.wim
└── Mount\             # boot.wim 挂载点,用于修改启动环境

生成后可在 Mount 中注入脚本、驱动,或替换启动文件,在 Media 中组织最终 ISO 镜像结构。

步骤 4:挂载 boot.wim

dism /Mount-Image /ImageFile:C:\WinPE_amd64\media\sources\boot.wim /Index:1 /MountDir:C:\WinPE_amd64\mount

此操作将 boot.wim 中的 WinPE 镜像挂载到 mount 目录,便于添加 startnet.cmd、分区脚本、驱动等文件。

完成编辑后可使用 dism /Unmount-Image /MountDir:C:\WinPE_amd64\mount /Commit 保存修改。

步骤 5:添加powershell组件

Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-WMI.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-WMI_en-us.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-NetFX.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-NetFX_en-us.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-Scripting.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-Scripting_en-us.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-PowerShell.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-PowerShell_en-us.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-StorageWMI.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-StorageWMI_en-us.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\WinPE-DismCmdlets.cab"
Dism /Add-Package /Image:"C:\WinPE_amd64\mount" /PackagePath:"C:\Program Files (x86)\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\amd64\WinPE_OCs\en-us\WinPE-DismCmdlets_en-us.cab"

三、添加启动脚本和配置文件

1. 分区脚本(generate-dp.ps1)说明

  • 分区脚本使用 diskpart 命令进行磁盘自动分区;
  • 配合 PowerShell 脚本提前识别出最佳系统盘(优先级:NVMe SSD > SATA SSD > HDD),并动态写入目标磁盘编号;

使用 PowerShell 脚本自动生成 dp.txt

# 获取 WinPE 启动盘所在物理磁盘编号
$bootDiskNumber = (Get-Volume -DriveLetter X -ErrorAction SilentlyContinue | Get-Partition | Get-Disk).Number

# 过滤非系统盘候选:排除 U 盘、启动盘、可移动磁盘
$disks = Get-Disk | Where-Object {
    $_.Number -ne $bootDiskNumber -and
    $_.BusType -notin @('USB', '1394') -and
    $_.IsBoot -ne $true -and
    $_.IsRemovable -ne $true
}

# 打分函数:优先级 NVMe > SATA SSD > HDD
function Get-DiskScore($disk) {
    switch ($disk.BusType) {
        'NVMe' { return 3 }
        'SATA' {
            if ($disk.MediaType -eq 'SSD') { return 2 }
            else { return 1 }
        }
        default { return 0 }
    }
}

# 按评分和容量排序
$targetDisk = $disks | Sort-Object @{
    Expression = { Get-DiskScore $_ }; Descending = $true
}, @{
    Expression = { $_.Size }; Ascending = $true
} | Select-Object -First 1

if (-not $targetDisk) {
    Write-Host "No suitable disk found. Aborting." -ForegroundColor Red
    exit 1
}

$diskIndex = $targetDisk.Number
$diskSizeGB = [math]::Round($targetDisk.Size / 1GB)
$osSize = if ($diskSizeGB -le 256) { $diskSizeGB - 2 } else { 200 }

# 输出磁盘信息并暂停确认
Write-Host "Target Disk #: $diskIndex" -ForegroundColor Yellow
Write-Host "Model        : $($targetDisk.Model)" -ForegroundColor Yellow
Write-Host "Capacity     : $diskSizeGB GB" -ForegroundColor Yellow
Read-Host "Press Enter to continue formatting this disk (or close to cancel)"

# 生成 dp.txt 分区脚本
@"
select disk $diskIndex
clean
convert gpt
create partition efi size=100
format quick fs=fat32 label="System"
assign letter=S
create partition msr size=128
create partition primary size=$($osSize * 1024)
format quick fs=ntfs label="Windows"
assign letter=C
exit
"@ | Out-File -Encoding ASCII -FilePath "X:\dp.txt"

# 成功提示
Write-Host "Partition script generated. C: drive will use $osSize GB." -ForegroundColor Green

2. 启动脚本(startnet.cmd)说明

以下为 WinPE 启动后自动运行的批处理脚本,负责调用 PowerShell 生成分区脚本、执行磁盘分区、应用系统镜像、复制应答文件并重建引导。
/Index:4 用于选择镜像版本,对于consumer版本的镜像来说,索引: 4 对应的为专业版。至于为什么不使用business版本的镜像,主要是因为business版本的镜像中不包含家庭版系统,而大多数品牌机都带有OEM家庭版的数字许可证,可以自动激活家庭版系统。

@echo off
wpeinit

:: run PowerShell script to generate dp.txt
echo Launching PowerShell to generate partition script...
powershell -ExecutionPolicy Bypass -Command "X:\generate-dp.ps1"

:: run diskpart
echo Running diskpart with dp.txt...
diskpart /s X:\dp.txt

:: locate install.wim automatically
setlocal enabledelayedexpansion
set WIMPATH=
for %%i in (D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    if exist %%i:\sources\install.wim (
        set WIMPATH=%%i:\sources\install.wim
        echo Found: !WIMPATH!
        goto :found
    )
)
echo ERROR: install.wim not found.
pause
exit /b

:found
echo Applying system image...
dism /Apply-Image /ImageFile:!WIMPATH! /Index:4 /ApplyDir:C:\

:: copy unattended answer file
echo Copying autounattend.xml to target system...
mkdir C:\Windows\Panther
copy X:\autounattend.xml C:\Windows\Panther\Unattend.xml

:: repair boot
bcdboot C:\Windows /s S: /f UEFI

:: reboot
wpeutil reboot

索引列表如下:

索引: 1
名称: Windows 10 家庭版

索引: 2
名称: Windows 10 家庭单语言版

索引: 3
名称: Windows 10 教育版

索引: 4
名称: Windows 10 专业版

索引: 5
名称: Windows 10 专业教育版

索引: 6
名称: Windows 10 专业工作站版

3. 应答文件(Unattend.xml)说明

下方为一个适用于 Windows 10 的完整自动应答文件(Unattend.xml)示例涵盖了从安装镜像选择到用户自动登录的全过程配置。

详见下方完整文件及注释:

<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">

  <!-- 第一阶段:windowsPE,用于磁盘分区、镜像选择、EULA 许可等 -->
  <settings pass="windowsPE">
    <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">

      <!-- 安装镜像来源:指定使用“Windows 10 Home”名称的版本 -->
      <ImageInstall>
        <OSImage>
          <InstallFrom>
            <MetaData>
              <Key>/IMAGE/NAME</Key>
              <Value>Windows 10 Home</Value>
            </MetaData>
          </InstallFrom>
          <!-- 安装目标分区:如使用外部分区脚本,则此处无实际影响 -->
          <InstallTo>
            <DiskID>0</DiskID>
            <PartitionID>3</PartitionID>
          </InstallTo>
        </OSImage>
      </ImageInstall>

      <!-- 用户信息及接受许可协议(ProductKey 可为空) -->
      <UserData>
        <AcceptEula>true</AcceptEula>
        <FullName>Ecordia</FullName>
        <Organization>Ecordia</Organization>
        <ProductKey></ProductKey>
      </UserData>

    </component>
  </settings>

  <!-- 第二阶段:specialize,主要用于主机名、时区等初始化设置 -->
  <settings pass="specialize">
    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <ComputerName>EC-PC</ComputerName> <!-- 设置计算机名称 -->
      <TimeZone>China Standard Time</TimeZone> <!-- 设置默认时区 -->
    </component>
  </settings>

  <!-- 第三阶段:oobeSystem,用于用户创建、OOBE跳过、语言设置等 -->
  <settings pass="oobeSystem">

    <!-- 设置系统语言、输入法等区域信息 -->
    <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
      <InputLocale>zh-CN</InputLocale>
      <SystemLocale>zh-CN</SystemLocale>
      <UILanguage>zh-CN</UILanguage>
      <UserLocale>zh-CN</UserLocale>
    </component>

    <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">

      <!-- 设置 OOBE 跳过选项 -->
      <OOBE>
        <HideEULAPage>true</HideEULAPage>
        <SkipMachineOOBE>true</SkipMachineOOBE>
        <SkipUserOOBE>true</SkipUserOOBE>
        <NetworkLocation>Home</NetworkLocation>
        <ProtectYourPC>1</ProtectYourPC>
      </OOBE>

      <!-- 创建本地管理员账户 -->
      <UserAccounts>
        <LocalAccounts>
          <LocalAccount wcm:action="add">
            <Name>Windows</Name> <!-- 用户名 -->
            <Group>Administrators</Group> <!-- 属于管理员组 -->
            <Password>
              <Value>Password@123</Value> <!-- 用户密码 -->
              <PlainText>true</PlainText>
            </Password>
          </LocalAccount>
        </LocalAccounts>
      </UserAccounts>

      <!-- 启用自动登录 -->
      <AutoLogon>
        <Username>Windows</Username>
        <Enabled>true</Enabled>
        <LogonCount>1</LogonCount>
        <Password>
          <Value>Password@123</Value>
          <PlainText>true</PlainText>
        </Password>
      </AutoLogon>

    </component>
  </settings>

</unattend>

拷贝位置:需在系统部署完成后将文件复制至 C:\Windows\Panther\Unattend.xml


四、集成 Windows 安装文件

提取以下文件自原版 ISO:

  • sources\install.wim

拷贝到以下目录:

C:\WinPE_amd64\media\sources\install.wim

可使用 7-Zip 打开 ISO 文件进行提取

加载机制说明:

在 WinPE 启动时,media 目录中的所有内容将会被映射为启动盘 X:\ 的根目录。因此:

  • C:\WinPE_amd64\media\sources\install.wim → 加载后为 X:\sources\install.wim

五、保存修改并生成 ISO

卸载 boot.wim 镜像并保存:

dism /Unmount-Image /MountDir:C:\WinPE_amd64\mount /Commit

生成 ISO 文件:

MakeWinPEMedia /ISO C:\WinPE_amd64 C:\WinPE_AutoInstall.iso

生成的 WinPE_AutoInstall.iso 可用 Ventoy、Rufus 或其他工具写入 U 盘,完成自动部署。


六、推荐目录结构总览

C:\WinPE_amd64\
├─ mount\                       装载修改 boot.wim
│  ├─ Windows\System32\startnet.cmd
│  ├─ autounattend.xml
│  ├─ generate-dp.ps1
├─ media\
│  └─ sources\install.wim     抽取自 ISO
└─ WinPE_AutoInstall.iso      生成后的启动镜像

七、后期维护与扩展(修改已有镜像)

若已制作好 ISO 但需调整脚本,可重新挂载 boot.wim 修改:

dism /Mount-Image /ImageFile:C:\WinPE_amd64\media\sources\boot.wim /Index:1 /MountDir:C:\WinPE_amd64\mount
  • 修改后重新执行:
dism /Unmount-Image /MountDir:C:\WinPE_amd64\mount /Commit
  • 如有必要,重新打包 ISO
MakeWinPEMedia /ISO C:\WinPE_amd64 C:\WinPE_AutoInstall.iso

八、常见错误和处理办法

错误信息 原因 解决方案
Destination directory exists 目录已存在 卸载挂载后删除:dism ... /Discard + rd /s /q
Failed to mount 未以管理员运行或 mount 存在 确保管理员权限并删除旧 mount 目录
copype 无效命令 未在 Deployment Tools CMD 中执行 重新打开正确命令环境
install.wim 缺失 文件未提取或路径错误 使用 7-Zip 从 ISO 提取

如需进一步帮助,如绑定默认系统盘、集成驱动程序、自动创建用户脚本等,可继续扩展本 PE 环境。

posted @ 2025-08-01 15:57  Yogochann  阅读(166)  评论(0)    收藏  举报