해결 방법

해결 방법

Invoke-Command정확히 동일한 명령이 동일한 시스템에서 로컬로 실행될 때와 원격으로 명령이 실행될 때 다른 결과가 나타나는 이유는 무엇입니까 ?

원격으로 호출되는 이러한 명령은 4개의 빈 줄을 표시합니다.

PS > Invoke-Command cluster02 { cmd /c dir c:\ | select-string 'bytes free' }

이러한 로컬 명령은 예상대로 출력됩니다.

PS > Invoke-Command cluster02 { cmd /c dir c:\ | select-string 'bytes free' }

11 Dir(s) 828,179,570,688 bytes free

처음 시작한 Enter-PSSession cluster02다음 실행하면 두 명령 모두 예상된 출력을 반환합니다.

이전 PowerShell(Windows 2012)의 버그입니까, 아니면 일부 PS 특성을 놓친 것입니까? 버그나 특이점이라면 언제 나타나나요? 즉, 이 이상한 행동에서 배울 점이 있는 걸까요?

답변1

겪고 있는 문제는 cmd /ccmd dir명령을 사용하여 원격으로 실행한 다음 원격으로 PowerShell 명령으로 파이프하려고 한다는 것입니다.

원격으로 실행할 때 로컬에서 작동하는 방식과 정확히 동일하게 작동할 것으로 예상하지만, 이는 차이점이 있고 혼란을 일으키는 것으로 알려져 있습니다.

에 명시된 바와 같이사용자 프로필이 필요한 명령은 원격으로 실행 시 실패할 수 있음우편

문제는 원격 컴퓨터에 연결할 때 완전한 사용자 환경이 가동되지 않는다는 것입니다. 기술적으로 일반적인 의미에서 컴퓨터에 "로그온"하는 것은 아닙니다. 예, 인증하고 있지만 공유 폴더에 인증하는 것과 거의 같은 방식입니다. 원격 연결에는 완전한 사용자 프로필이 없으므로 예상하는 모든 항목에 오류가 발생하고 실패할 수 있습니다(오류가 표시되지 않더라도).

불행히도 이 문제를 쉽게 해결할 수 있는 방법은 없습니다.

원격 컴퓨터에 대해 실행할 때 Invoke-Command -ScriptBlock {}명령을 가능한 한 PowerShell로 유지하려고 합니다. cmd와 PowerShell을 혼합하는 경우 시스템에 대화형으로 로그온한 동안 실행할 때와 동일한 방식으로 작동하지 않을 수 있으므로 광범위하게 테스트해야 합니다.

원격 PowerShell, 바이트 단위로 드라이브 여유 공간 가져오기(아니요 cmd)

Invoke-Command -ComputerName Cluster02 -ScriptBlock {(Get-PSDrive C).Free}

산출

599257099776

해결 방법

출력을 Invoke-Command변수로 설정한 다음 문자열과 line 속성을 선택하면 원하는 출력을 원하는 대로 얻을 수 있는 것 같습니다.

PowerShell(변형 1)

$var = Invoke-Command cluster02 -ScriptBlock { cmd /c "dir c:\" }; 
($var| select-string 'bytes free').Line.Trim();

산출

11 Dir(s)  36,011,925,504 bytes free

문제가 발생할 가능성이 높습니다.cmd /c호출 한 다음 원격 호출 세션에서 일치하는 문자열을 선택하는 PowerShell 파이프 로 인해 발생합니다 . 나는 의 전체 출력을 invoke-command외부 변수로 올바르게 반환한 invoke-command다음 그에 따라 외부에서도 해당 변수를 구문 분석하여 이 문제를 해결합니다 invoke-command.

PowerShell(변형 2)

위와 동일한 거래가 있지만 변수를 혼합에 던지는 대신 쿼리 Invoke-Command에 바로 파이프를 연결하면 Select-String됩니다.

Invoke-Command cluster02 -ScriptBlock { cmd /c "dir c:\"; } | select-string 'bytes free';

아니면 이런 것이라도...

(Invoke-Command cluster02 -ScriptBlock { cmd /c "dir c:\"; } | select-string 'bytes free').Line.Trim()

답변2

(이 TLDR 버전이 마음에 드셨다면 허용된 답변에 찬성 투표해 주세요)

TLDR 지침

원격으로 스크립트 블록을 실행하는 경우:

  • 가능하다면 기본 PowerShell이 ​​아닌 것은 실행하지 마세요. 예를 cmd /c dir c:\|sls 'bytes free'들어 (Get-PSDrive C).Free.
  • 그렇지 않은 경우 원격 셸에서 최소한의 처리를 수행합니다. 예를 들어 다음과 같이 선택 문자열을 원격 셸 외부로 이동합니다 Invoke-Command cluster02 { cmd /c "dir c:\" } | sls 'bytes free'.

관련 정보