Autounattend.xml - 当 CommandLine 很长时会出现奇怪的行为

Autounattend.xml - 当 CommandLine 很长时会出现奇怪的行为

版本:Windows 10 x64 1909(西班牙语)| 内部版本:18363.959

根据微软的说法,元素的限制CommandLine是 1024 个字符,但在我的测试中,当它超过两百多个字符时,它就会开始出现奇怪的行为。考虑到在组件Path中调用的是同一个元素Microsoft-Windows-Deployment,我猜文档是错误的,两个元素的实际限制都是 259 个字符。

资料来源:

https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-firstlogoncommands-synchronouscommand-commandline

https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-deployment-runsynchronous-runsynchronouscommand-path

如何重现:

oobeSystem传递过程中,添加这些内容FirstLogonCommands

<SynchronousCommand wcm:action="add">
  <Order>1</Order>
  <Description>Test</Description>
  <CommandLine>reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test1 /t REG_SZ /d &quot;cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot; /f</CommandLine>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
  <Order>2</Order>
  <Description>Test</Description>
  <CommandLine>reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test2 /t REG_SZ /d &quot;cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&quot; /f</CommandLine>
</SynchronousCommand>

命令 1 被正确添加到注册表并执行:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
    Test1    REG_SZ    cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

但是命令 2 被添加到HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce字面上:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
    Unattend0000000002{373CFC84-60AF-44A4-A316-9BECBAB1AD4B}    REG_EXPAND_SZ    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test2 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f

C:\Windows\Panther\UnattendedGC\setupact.log没有显示任何异常:

2020-08-17 19:09:39, Info                         [Shell Unattend] LogonCommands: Set command 'reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test1 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f' 
2020-08-17 19:09:39, Info                         [Shell Unattend] LogonCommands: Set command 'reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v Test2 /t REG_SZ /d "cmd /k echo aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" /f' 

答案1

最近我遇到了同样的问题,正如你猜测的那样,我将限制确定为 259 个字符。但是,我认为如果命令行中包含百分比变量,变量扩展可能会改变有效限制。但不幸的是,我的测试并没有在这方面得出任何明确的结论。

以下简单测试演示了 259 个字符的限制:

<SynchronousCommand wcm:action="add">
    <Order>1</Order>
    <RequiresUserInput>false</RequiresUserInput>
    <CommandLine>cmd /c ECHO This line will eventually be 259 characters long. This line will eventually be 259 characters long. This line will eventually be 259 characters long. This line will eventually be 259 characters long. This line will even > "C:\Windows\Temp\259.log"</CommandLine>
    <Description>259 characters, should produce file</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
    <Order>2</Order>
    <RequiresUserInput>false</RequiresUserInput>
    <CommandLine>cmd /c ECHO This line will eventually be 260 characters long. This line will eventually be 260 characters long. This line will eventually be 260 characters long. This line will eventually be 260 characters long. This line will event > "C:\Windows\Temp\260.log"</CommandLine>
    <Description>260 characters, should NOT produce file</Description>
</SynchronousCommand>

简而言之:<CommandLine>长度为 259 个字符并尝试写入名为 的文件的行259.log已成功写入,而<CommandLine>长度为 260 个字符并尝试写入名为 的文件的行260.log则未成功写入。

我第一次遇到这个问题时,正在对各种 Windows 安装后命令调用的命令行进行一些更改。具体来说,我的更改是完全限定文件路径.exe,并在某些情况下使用环境变量(例如,"%ComSpec%"而不是)cmd。但是通过增加字符数,我无意中破坏了一切!

令人费解的是,<CommandLine>长度少于 260 个字符的行仍然无法执行预期的操作。我知道这些命令是正确的,因为即使没有完全限定文件.exe,它们也能正常工作。以下是<CommandLine>失败的 253 个字符的示例行:

<SynchronousCommand wcm:action="add">
    <Order>3</Order>
    <RequiresUserInput>false</RequiresUserInput>
    <CommandLine>"%ComSpec%" /c FOR %I IN ("%InstallDrive%:\cfs-extras\installers\LibreOffice_*.msi") DO IF NOT DEFINED L "%WinDir%\System32\msiexec.exe" /i "%~fI" /l* "%TMP%\L.log" /qn ALLUSERS=1 CREATEDESKTOPLINK=1 QUICKSTART=1 ADDLOCAL=ALL UI_LANGS=en_GB ^&^& SET L=t</CommandLine>
    <Description>Silently install LibreOffice</Description>
</SynchronousCommand>

但是,如果我手动扩展变量,那么我的命令确实超出了 259 个字符的限制!这可能表明在运行命令之前,正在进行一些变量的预扩展。

另一个观察:我尝试跑步普罗克蒙,例如过滤进程名称 =cmd.exe我发现cmd.exe失败的命令从未出现在 Procmon 输出中。

正如您所发现的,我还发现C:\Windows\Panther\UnattendedGC\setupact.log报告该命令已成功运行,无论它是否运行。

读了你关于从 USB 棒运行的评论后,听起来你正在做的事情和我非常相似。对我有帮助的一件事是为 USB 驱动器号设置一个环境变量。希望这能让你以用户身份调用脚本,而不是长命令行yagmoth555♦评论。我在以下部分进行了设置<settings pass="specialize">

<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
    xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <RunSynchronous>
        <RunSynchronousCommand wcm:action="add">
            <Order>1</Order>
            <Description>Set InstallDrive environment variable</Description>
            <Path>"%ComSpec%" /c FOR %i IN (C D E F G H I J K L N M O P Q R S T U V W X Y Z) DO IF NOT DEFINED InstallDrive IF EXIST %i:\cfs-extras "%SystemRoot%\System32\setx.exe" InstallDrive %i /M</Path>
        </RunSynchronousCommand>
    </RunSynchronous>
</component>

这只是检查每个驱动器上是否存在已知存在于 USB 驱动器上的目录,如果存在,它会将InstallDrive环境变量设置为包含该目录的驱动器的驱动器号。然后您可以%InstallDrive%<settings pass="oobeSystem">命令/脚本中引用它。在本节结束时,我使用以下命令删除环境变量:

<SynchronousCommand wcm:action="add">
    <Order>7</Order>
    <RequiresUserInput>false</RequiresUserInput>
    <CommandLine>"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -command [Environment]::SetEnvironmentVariable('InstallDrive',$null,'Machine')</CommandLine>
    <Description>Remove InstallDrive machine environment variable. Always run this last.</Description>
</SynchronousCommand>

...只是为了保持干净整洁。

我知道您提出问题已经四年了,但我希望这个答案对您以及可能遇到同样问题的其他人来说仍然具有一定的意义。

相关内容