为什么这些配置文件排除适用于 DISM /Capture-Image,但不适用于 New-WindowsImage cmdlet?

为什么这些配置文件排除适用于 DISM /Capture-Image,但不适用于 New-WindowsImage cmdlet?

我正在尝试创建一个配置文件来定义图像捕获的排除项,如DISM 配置列表和 WimScript.ini 文件-ConfigFilePath。当我使用New-WindowsImage命令,但我注意到,当我将相同的配置文件传递给等效的DISM /Capture-Image命令。这是怎么回事?

例如,如果我创建这个目录结构...

  • Source\
    • Exclude all files\
      • 1.dat
      • 2.dat
      • 3.dat
      • 4.dat
      • 5.dat
    • Exclude even files\
      • 1.dat
      • 2.dat
      • 3.dat
      • 4.dat
      • 5.dat
    • Exclude no files\
      • 1.dat
      • 2.dat
      • 3.dat
      • 4.dat
      • 5.dat

...并创建此wimscript.ini文件...

[ExclusionList]
\Exclude all files\*
\Exclude even files\2.dat
\Exclude even files\4.dat

...然后运行此命令后...

PS> New-WindowsImage -ImagePath 'CapturedByDismModule.wim' -CapturePath 'Source' -Name 'CapturedByDismModule' -ConfigFilePath 'wimscript.ini'

...CapturedByDismModule.wim包含Source目录下的所有内容。没有排除任何内容。

但是,如果我运行这个命令......

PS> Dism.exe /Capture-Image /ImageFile:CapturedByDismExe.wim /CaptureDir:Source /Name:CapturedByDismExe /ConfigFile:wimscript.ini

...然后CapturedByDismExe.wim包含这张图片...

  • [CapturedByDismExe]
    • Exclude all files\
    • Exclude even files\
      • 1.dat
      • 3.dat
      • 5.dat
    • Exclude no files\
      • 1.dat
      • 2.dat
      • 3.dat
      • 4.dat
      • 5.dat

排除按预期进行。因此为什么传递相同的参数不会New-WindowsImage产生相同的图像?

以下是我的系统的相关版本号:

成分 版本 命令
Windows 10 1809 版本 17763.379 winver.exe
Dism.exe 10.0.17763.1 [System.Diagnostics.FileVersionInfo]::GetVersionInfo((Get-Command -Name 'Dism.exe').Path).ProductVersion
电源外壳 5.1.17763.316 $PSVersionTable.PSVersion.ToString()
DISM 模块 3.0 (Get-Command -Name 'New-WindowsImage').Module.Version.ToString()
DISM 模块 10.0.17763.1 [System.Diagnostics.FileVersionInfo]::GetVersionInfo((Get-Command -Name 'New-WindowsImage').DLL).ProductVersion

答案1

这似乎是DISM PowerShell 模块

通过...我发现Add-WindowsImage,、New-WindowsCustomImageNew-WindowsImagecmdlet 通过以下方式实现排除行为:注册回调方法底层 API然后对要捕获的每个目录或文件调用一次。通过回调,cmdlet已通过捕获目录中每个候选目录或文件的完整路径,并返回一个值,指示是否应包含或排除该目录或文件。cmdlet 通过将路径与从配置文件中解析出的排除规则进行匹配来确定这一点。

为了将每个候选对象的绝对路径转换为可以与排除规则中的路径匹配的路径,cmdlet 会从该绝对路径的开头删除等于传递给 cmdlet 的捕获路径长度的字符数。(明白了吗?)如果捕获路径是绝对路径,则此方法可以正常工作,但不幸的是,如果不是绝对路径,则很可能会最终无法排除任何内容。

举例来说,如果问题中的所有内容都发生在C:\Test目录中并C:\Test\Source传递给-CapturePath参数,那么对于第一个候选文件,它会按如下方式评估......

   Candidate absolute path: C:\Test\Source\Exclude all files\1.dat
              Capture path: C:\Test\Source
Candidate transformed path:               \Exclude all files\1.dat
 Applicable exclusion rule:               \Exclude all files\*
    Exclusion rule matched: Yes

像我一样传递Source参数-CapturePath,它看起来像这样......

   Candidate absolute path: C:\Test\Source\Exclude all files\1.dat
              Capture path: Source
Candidate transformed path:       t\Source\Exclude all files\1.dat
 Applicable exclusion rule:               \Exclude all files\*
    Exclusion rule matched: No! (transformed path prefixed with "t\Source")

请注意,如果您指定-CapturePath带有尾随反斜杠的绝对路径,则 cmdlet 从绝对路径获取捕获相对路径的基本方法也会导致问题......

   Candidate absolute path: C:\Test\Source\Exclude all files\1.dat
              Capture path: C:\Test\Source\
Candidate transformed path:                Exclude all files\1.dat
 Applicable exclusion rule:               \Exclude all files\*
    Exclusion rule matched: No! (transformed path prefixed with "\")

传递捕获路径会C:\Test\Source\导致New-WindowsImage另一个 WIM 文件没有任何排除,而Dism.exe正确处理它。

总结由于 cmdlet 不会将-CapturePath参数解析为规范化的绝对​​路径,因此解决方法当然是自己执行。因此,如果我改用此命令进行捕获...

PS> New-WindowsImage -ImagePath 'CapturedByDismModule.wim' -CapturePath (Get-Item -Path 'Source').FullName -Name 'CapturedByDismModule' -ConfigFilePath 'wimscript.ini'

...排除按预期工作。当然,传递绝对路径文字-CapturePath也同样有效。

相关内容