Windows PowerShell을 통해 일대다 원격 작업 사용

완료됨

일대다 원격 작업을 사용하면 단일 명령을 여러 컴퓨터에 병렬로 보낼 수 있습니다. 각 컴퓨터는 전송되는 명령을 실행하고 결과를 XML로 직렬화한 다음, 해당 결과를 컴퓨터로 다시 전송합니다. 그러면 컴퓨터에서 XML을 개체로 역직렬화하여 Windows PowerShell 파이프라인에 넣습니다. 이 작업을 수행할 때 각 개체에 여러 속성이 추가되며 여기에는 각 결과가 제공된 컴퓨터를 나타내는 PSComputerName 속성이 포함됩니다. 이 속성을 사용하면 컴퓨터 이름에 따라 정렬, 그룹화 및 필터링할 수 있습니다.

다음과 같은 두 가지 기술을 사용하여 일대다 원격 작업을 사용할 수 있습니다.

  • Invoke-Command –ComputerName name1,name2 –ScriptBlock { command }. 이 기술은 스크립트 블록에 포함된 명령을 나열된 컴퓨터로 보냅니다. 이 기술은 하나 또는 두 개의 명령을 보내는 데 유용합니다. 여러 명령은 세미콜론으로 구분됩니다.
  • Invoke-Command –ComputerName name1,name2 –FilePath 파일 경로. 이 기술은 .ps1 파일 이름 확장명을 갖는 스크립트 파일의 내용을 나열된 컴퓨터로 보냅니다. 로컬 컴퓨터에서 파일을 열고 해당 내용을 읽습니다. 그러나 원격 컴퓨터는 파일에 직접 액세스할 필요가 없습니다. 이 기술은 전체 스크립트와 같은 큰 명령 파일을 보내는 데 유용합니다.

참고

모든 스크립트 블록(–ScriptBlock 매개 변수에 제공된 스크립트 블록 포함) 내에서 세미콜론을 사용하여 여러 명령을 구분할 수 있습니다. 예를 들어 { Get-Service ; Get-Process }Get-Service를 실행한 다음, Get-Process를 실행합니다.

제한

로컬 컴퓨터에서 리소스를 관리하는 데 도움이 되도록 PowerShell에는 각 명령에 대해 설정된 동시 원격 연결 수를 제한할 수 있는 명령별 제한 기능이 포함되어 있습니다. 기본적으로 Windows PowerShell은 한 번에 32대의 컴퓨터에만 연결됩니다. 32대를 넘는 컴퓨터가 나열된 경우 다른 컴퓨터에 대한 연결은 큐에 대기됩니다. 첫 번째 일괄 처리에서 일부 컴퓨터에 대한 세션이 완료되고 결과를 반환하면 다음 일괄 처리에서 컴퓨터에 대한 연결이 시작됩니다.

Invoke-Command–ThrottleLimit 매개 변수를 사용하여 이 동작을 변경할 수 있습니다. 숫자를 증가시키면 원격 컴퓨터에서 추가적인 부하가 발생하지 않습니다. 그러나 Invoke-Command가 호출된 컴퓨터에는 추가적인 부하가 발생합니다. 또한 더 많은 대역폭을 활용합니다. 각 동시 연결은 기본적으로 Windows PowerShell 스레드입니다. 따라서 컴퓨터 수를 증가시키면 로컬 컴퓨터에서 메모리를 많이 소비하고 프로세서 속도가 저하됩니다.

값 전달

스크립트 블록 또는 파일 내용은 실행되는 원격 컴퓨터에 리터럴 텍스트로 그대로 전송됩니다. 컴퓨터는 Invoke-Command가 실행된 스크립트 블록 또는 파일을 구문 분석하지 않습니다. 다음 명령 예제를 생각해 보겠습니다.

$var = 'BITS'
Invoke-Command –ScriptBlock { Get-Service –Name $var } –Computer LON-DC1

이 시나리오에서는 변수 $varLON-DC1에서 실행될 스크립트 블록에 포함되지 않고 로컬 컴퓨터에서 설정됩니다. 즉, $var은 PowerShell 원격 세션에서 LON-DC1로 정의되거나 설정되어 있지 않습니다. 이는 Windows PowerShell을 처음 사용하는 관리자가 종종 하는 일반적인 실수입니다.

로컬 및 원격으로 명령 실행

원격 컴퓨터에 전달할 스크립트 블록 내에 포함된 명령에 주의하세요. 로컬 컴퓨터는 스크립트 블록 콘텐츠를 처리하지 않고 원격 컴퓨터에 전달합니다. 예를 들어 다음과 같은 명령을 생각해 보겠습니다.

Invoke-Command –ScriptBlock { Do-Something –Credential (Get-Credential) } -ComputerName LON-DC1

이 명령은 원격 컴퓨터에서 Get-Credential cmdlet을 실행합니다. 로컬 컴퓨터에서 Get-Credential을 실행하려고 하면 그래픽 대화 상자를 사용하여 자격 증명을 묻는 메시지가 표시됩니다.

질문: 원격 컴퓨터에서 실행할 때 해당 명령이 작동합니까? 예를 들어 100대의 원격 컴퓨터에서 이전 명령을 실행한 경우 100개의 자격 증명을 묻는 메시지가 표시되나요?

이제 이 수정된 버전의 명령을 보겠습니다.

Invoke-Command –ScriptBlock { Param($c) Do-Something –Credential $c }
               -ComputerName LON-DC1
               -ArgumentList (Get-Credential)

이 명령은 로컬 컴퓨터에서 Get-Credential을 실행하며 한 번만 실행합니다. 결과 개체가 스크립트 블록의 $c 매개 변수에 전달되므로 각 컴퓨터에서 동일한 자격 증명을 사용할 수 있습니다.

이러한 예제에서는 원격 명령을 신중하게 작성해야 하는 중요성을 보여 줍니다. 원격 및 로컬로 명령을 조합하여 실행하면 다양한 유용한 목표를 달성할 수 있습니다.

지속성

여기에 설명된 기술을 사용하면 Invoke-Command를 사용할 때마다 원격 컴퓨터가 새 wsmprovhost 프로세스를 만들고 명령을 실행합니다. 그런 다음, 결과를 반환하고 해당 Windows PowerShell 인스턴스를 닫습니다. 연속된 각 Invoke-Command는 동일한 컴퓨터에서 수행된 경우에도 새 Windows PowerShell 창을 여는 것과 비슷합니다. 이전 세션에서 수행한 모든 작업은 디스크 또는 다른 영구 스토리지에 저장하지 않는 한 존재하지 않게 됩니다. 예를 들어 다음과 같은 명령을 생각해 보겠습니다.

Invoke-Command –ComputerName LON-DC1 –ScriptBlock { $x = 'BITS' }
Invoke-Command –ComputerName LON-DC1 –ScriptBlock { Get-Service –Name $x }

이 예제에서는 Get-Service가 실패하는데, 이전 wsmprovhost 프로세스의 일부로 만든 변수의 값에 의존하기 때문입니다. Invoke-Command에서 호출한 첫 번째 스크립트가 완료되면 해당 변수가 메모리에서 지워집니다. 이 문제를 해결하려면 원격 컴퓨터에 wsmprovhost 프로세스를 만들어 연속 명령을 성공적으로 보낼 수 있도록 합니다.

여러 컴퓨터 이름

Invoke-Command–ComputerName 매개 변수는 모든 문자열 개체 컬렉션을 컴퓨터 이름으로 사용할 수 있습니다. 다음 목록에서는 이러한 컬렉션을 만드는 데 사용할 수 있는 다양한 기술에 대해 설명합니다.

  • -ComputerName ONE,TWO,THREE. 쉼표로 구분된 컴퓨터 이름의 정적 목록입니다.
  • -ComputerName (Get-Content Names.txt). Names.txt라는 텍스트 파일에서 이름을 읽으며, 파일에는 줄마다 컴퓨터 이름이 하나씩 있다고 가정합니다.
  • -ComputerName (Import-Csv Computers.csv | Select –ExpandProperty Computer). 이름이 Computers.csv이고 Computer 열에 컴퓨터 이름이 포함되어 있는 CSV(쉼표로 구분된 값) 파일을 읽습니다.
  • -ComputerName (Get-ADComputer –Filter * | Select –ExpandProperty Name). AD DS의 모든 컴퓨터 개체를 쿼리합니다. 이 기술을 사용하면 큰 도메인에서 상당한 시간이 걸릴 수 있습니다.

컴퓨터 이름을 사용할 때 발생하는 일반적인 실수

컴퓨터 이름을 지정하는 위치에 주의하세요. 예를 들어 다음 명령을 검토해 보겠습니다.

Invoke-Command –ScriptBlock { Get-Service –ComputerName ONE,TWO }

이 명령은 Invoke-Command–ComputerName 매개 변수를 제공하지 않습니다. 따라서 명령은 로컬 컴퓨터에서 실행됩니다. 로컬 컴퓨터는 ONETWO라는 이름의 컴퓨터를 대상으로 하는 Get-Service를 실행합니다. Get-Service에서 사용하는 프로토콜은 Windows PowerShell 원격 작업 대신 사용됩니다. 이 명령을 다음 명령과 비교해 보겠습니다.

Invoke-Command –ScriptBlock { Get-Service } –ComputerName ONE,TWO

이 명령은 원격 Windows PowerShell 원격 작업을 사용하여 ONETWO라는 컴퓨터에 연결합니다. 이들 컴퓨터는 각각 원격 작업을 사용하여 결과를 반환하는 Get-Service를 로컬로 실행합니다.

대화형 Windows PowerShell 원격 상황에서는 개별 세션을 별도의 엔터티로 관리할 수 있습니다. 이렇게 하려면 먼저 New-PSSession 명령을 사용하여 세션을 만듭니다. New-PSSession 명령을 사용하는 경우의 이점은 세션이 여러 Invoke-Command 인스턴스에 걸쳐 유지되므로 스크립트의 다른 명령에 변수 및 개체를 전달할 수 있다는 점입니다. New-PSSession 명령을 사용하여 영구 세션을 만들고 변수에 할당할 수 있습니다. 그런 다음, Invoke-Command 명령을 사용하여 나중에 변수를 참조할 수 있습니다. 완료되면 Remove-PSSession 명령을 사용하여 영구 세션을 닫을 수 있습니다.