我正在尝试创建一个配置文件来定义图像捕获的排除项,如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-WindowsCustomImage
和New-WindowsImage
cmdlet 通过以下方式实现排除行为:注册回调方法与底层 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
也同样有效。