Autounattend.xml - CommandLine이 길 때 이상한 동작

Autounattend.xml - CommandLine이 길 때 이상한 동작

버전: Windows 10 x64 1909(스페인어) | 빌드: 18363.959

Microsoft에 따르면 요소의 제한은 CommandLine1024자이지만 테스트에서 200자를 초과하면 이상하게 동작하기 시작합니다. 구성 요소 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

그러나 Command 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자 제한을 초과합니다! 이는 명령이 실행되기 전에 변수의 사전 확장이 진행되고 있음을 시사할 수 있습니다.

또 다른 관찰: 나는 달리기를 시도했다프로크몬, 예를 들어 프로세스 이름 =으로 필터링한 결과 실패한 명령이 Procmon 출력에 나타나지 않는 cmd.exe것으로 나타났습니다 .cmd.exe

찾은 대로 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>

...그냥 깨끗하고 깔끔하게 유지하기 위해서죠.

귀하가 질문한 지 4년이 지났다는 것을 알고 있지만, 이 답변이 귀하 및 잠재적으로 동일한 문제에 직면했을 수 있는 다른 사람들에게 여전히 관련성이 있기를 바랍니다.

관련 정보