다음을 통해 공유


파이프라인 정보

간단한 설명

PowerShell에서 파이프라인에 명령 결합

긴 설명

파이프라인은 파이프라인 연산자(|)(ASCII 124)로 연결된 일련의 명령입니다. 각 파이프라인 연산자는 이전 명령의 결과를 다음 명령으로 보냅니다.

첫 번째 명령의 출력은 두 번째 명령에 대한 입력으로 처리하기 위해 보낼 수 있습니다. 그리고 그 출력은 또 다른 명령으로 보낼 수 있습니다. 그 결과 일련의 간단한 명령으로 구성된 복잡한 명령 체인 또는 파이프라인 이 생성됩니다.

예를 들면 다음과 같습니다.

Command-1 | Command-2 | Command-3

이 예제에서는 Command-1 내보내는 개체가 Command-2전송됩니다. Command-2 개체를 처리하고 Command-3보냅니다. Command-3 개체를 처리하고 파이프라인 아래로 보냅니다. 파이프라인에 더 이상 명령이 없으므로 결과가 콘솔에 표시됩니다.

파이프라인에서 명령은 왼쪽에서 오른쪽으로 순서대로 처리됩니다. 처리는 단일 작업으로 처리되고 출력이 생성될 때 표시됩니다.

다음은 간단한 예입니다. 다음 명령은 메모장 프로세스를 가져오고 중지합니다.

예를 들면 다음과 같습니다.

Get-Process notepad | Stop-Process

첫 번째 명령은 Get-Process cmdlet을 사용하여 메모장 프로세스를 나타내는 개체를 가져옵니다. 파이프라인 연산자(|)를 사용하여 프로세스 개체를 Stop-Process cmdlet으로 보내 메모장 프로세스를 중지합니다. 지정된 프로세스가 파이프라인을 통해 제출되므로 Stop-Process 명령에는 프로세스를 지정하기 위한 Name 또는 ID 매개 변수가 없습니다.

이 파이프라인 예제에서는 현재 디렉터리의 텍스트 파일을 가져오고, 길이가 10,000바이트를 초과하는 파일만 선택하고, 길이별로 정렬하고, 표에 있는 각 파일의 이름과 길이를 표시합니다.

Get-ChildItem -Path *.txt |
  Where-Object {$_.length -gt 10000} |
    Sort-Object -Property length |
      Format-Table -Property name, length

이 파이프라인은 지정된 순서로 네 개의 명령으로 구성됩니다. 다음 그림에서는 파이프라인의 다음 명령으로 전달되는 각 명령의 출력을 보여 줍니다.

Get-ChildItem -Path *.txt
| (FileInfo objects for *.txt)
V
Where-Object {$_.length -gt 10000}
| (FileInfo objects for *.txt)
| (      Length > 10000      )
V
Sort-Object -Property Length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
V
Format-Table -Property name, length
| (FileInfo objects for *.txt)
| (      Length > 10000      )
| (     Sorted by length     )
| (   Formatted in a table   )
V

Name                       Length
----                       ------
tmp1.txt                    82920
tmp2.txt                   114000
tmp3.txt                   114000

파이프라인 사용

대부분의 PowerShell cmdlet은 파이프라인을 지원하도록 설계되었습니다. 대부분의 경우 get cmdlet의 결과를 동일한 명사로 파이프를 수 있습니다. 예를 들어 Get-Service cmdlet의 출력을 Start-Service 또는 Stop-Service cmdlet으로 파이프할 수 있습니다.

이 예제 파이프라인은 컴퓨터에서 WMI 서비스를 시작합니다.

Get-Service wmi | Start-Service

또 다른 예로 PowerShell 레지스트리 공급자 내의 Get-Item 또는 Get-ChildItem 출력을 New-ItemProperty cmdlet으로 파이프할 수 있습니다. 다음은 8124값이 있는 NoOfEmployees새 레지스트리 항목을 MyCompany 레지스트리 키에 추가하는 예제입니다.

Get-Item -Path HKLM:\Software\MyCompany |
  New-ItemProperty -Name NoOfEmployees -Value 8124

Get-Member, Where-Object, Sort-Object, Group-ObjectMeasure-Object 같은 유틸리티 cmdlet의 대부분은 파이프라인에서 거의 독점적으로 사용됩니다. 모든 개체 형식을 이러한 cmdlet으로 파이프할 수 있습니다. 이 예제에서는 각 프로세스의 열린 핸들 수를 기준으로 컴퓨터의 모든 프로세스를 정렬하는 방법을 보여 줍니다.

Get-Process | Sort-Object -Property handles

개체를 서식 지정, 내보내기 및 출력 cmdlet(예: Format-List, Format-Table, Export-Clixml, Export-CSVOut-File)으로 파이프할 수 있습니다.

이 예제에서는 Format-List cmdlet을 사용하여 프로세스 개체의 속성 목록을 표시하는 방법을 보여줍니다.

Get-Process winlogon | Format-List -Property *

간단한 명령을 파이프라인에 결합하면 시간과 입력이 절약되고 스크립팅의 효율성이 높아집니다.

파이프라인 작동 방식

이 섹션에서는 입력 개체가 cmdlet 매개 변수에 바인딩되고 파이프라인 실행 중에 처리되는 방법을 설명합니다.

파이프라인 입력 허용

파이프라닝을 지원하려면 수신 cmdlet에 파이프라인 입력을 허용하는 매개 변수가 있어야 합니다. Get-Help 명령어에 전체 또는 매개변수 옵션을 통해 cmdlet의 어떤 매개 변수가 파이프라인 입력을 수용하는지 확인합니다.

예를 들어 Start-Service cmdlet의 매개 변수 중 파이프라인 입력을 허용하는 매개 변수를 확인하려면 다음을 입력합니다.

Get-Help Start-Service -Full

또는

Get-Help Start-Service -Parameter *

Start-Service cmdlet에 대한 도움말은 InputObjectName 매개 변수만 파이프라인 입력을 허용한다는 것을 보여줍니다.

-InputObject <ServiceController[]>
Specifies ServiceController objects representing the services to be started.
Enter a variable that contains the objects, or type a command or expression
that gets the objects.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByValue)
Accept wildcard characters?  false

-Name <String[]>
Specifies the service names for the service to be started.

The parameter name is optional. You can use Name or its alias, ServiceName,
or you can omit the parameter name.

Required?                    true
Position?                    0
Default value                None
Accept pipeline input?       True (ByPropertyName, ByValue)
Accept wildcard characters?  false

파이프라인을 통해 Start-Service개체를 보내면 PowerShell은 InputObjectName 매개 변수와 개체를 연결하려고 시도합니다.

파이프라인 입력을 수락하는 방법

Cmdlet 매개 변수는 다음 두 가지 방법 중 하나로 파이프라인 입력을 수락할 수 있습니다.

  • ByValue: 매개 변수는 예상된 .NET 형식과 일치하거나 해당 형식으로 변환할 수 있는 값을 허용합니다.

    예를 들어 Start-Service 매개 변수는 값별로 파이프라인 입력을 허용합니다. 문자열로 변환할 수 있는 문자열 개체 또는 개체를 허용할 수 있습니다.

  • ByPropertyName: 매개 변수는 입력 개체에 매개 변수와 이름이 같은 속성이 있는 경우에만 입력을 허용합니다.

    예를 들어 Start-Service Name 매개 변수는 Name 속성이 있는 개체를 허용할 수 있습니다. 개체의 속성을 나열하려면 Get-Member로 개체를 전달합니다.

일부 매개 변수는 값 또는 속성 이름 둘 다로 개체를 수락할 수 있으므로 파이프라인에서 입력을 쉽게 수행할 수 있습니다.

매개 변수 바인딩

한 명령에서 다른 명령으로 개체를 파이프하는 경우 PowerShell은 파이프된 개체를 수신 cmdlet의 매개 변수와 연결하려고 시도합니다.

PowerShell의 매개 변수 바인딩 구성 요소는 다음 조건에 따라 입력 개체를 cmdlet 매개 변수와 연결합니다.

  • 매개 변수는 파이프라인의 입력을 수락해야 합니다.
  • 매개 변수는 전송되는 개체의 형식 또는 예상 형식으로 변환할 수 있는 형식을 허용해야 합니다.
  • 매개 변수가 명령에 사용되지 않았습니다.

예를 들어 Start-Service cmdlet에는 많은 매개 변수가 있지만, 그 중 두 개의 매개 변수인 NameInputObject만 파이프라인 입력을 수락할 수 있습니다. Name 매개 변수는 문자열을 사용하고 InputObject 매개 변수는 서비스 개체를 사용합니다. 따라서 문자열, 서비스 개체 및 문자열 또는 서비스 개체로 변환할 수 있는 속성을 사용하여 개체를 파이프할 수 있습니다.

PowerShell은 가능한 한 효율적으로 매개 변수 바인딩을 관리합니다. PowerShell이 특정 매개 변수에 바인딩되도록 제안하거나 강제 적용할 수는 없습니다. PowerShell이 파이프된 개체를 바인딩할 수 없는 경우 명령이 실패합니다.

바인딩 오류 문제 해결에 대한 자세한 내용은 이 문서의 뒷부분에 있는 파이프라인 오류 조사 참조하세요.

일회성 처리

명령에 개체를 파이핑하는 것은 명령의 매개 변수를 사용하여 개체를 제출하는 것과 비슷합니다. 파이프라인 예제를 살펴보겠습니다. 이 예제에서는 파이프라인을 사용하여 서비스 개체 테이블을 표시합니다.

Get-Service | Format-Table -Property Name, DependentServices

기능적으로 Format-Table 매개 변수를 사용하여 개체 컬렉션을 제출하는 것과 같습니다.

예를 들어, InputObject 매개변수를 사용하여 전달된 변수에 서비스 컬렉션을 저장할 수 있습니다.

$services = Get-Service
Format-Table -InputObject $services -Property Name, DependentServices

또는 InputObject 매개 변수에 명령을 포함할 수 있습니다.

Format-Table -InputObject (Get-Service) -Property Name, DependentServices

그러나 중요한 차이점이 있습니다. 여러 개체를 명령에 파이프하는 경우 PowerShell은 한 번에 하나씩 명령으로 개체를 보냅니다. 명령 매개 변수를 사용하면 개체가 단일 배열 개체로 전송됩니다. 이 사소한 차이는 중대한 결과를 초래합니다.

파이프라인을 실행할 때 PowerShell은 인터페이스를 구현하는 IEnumerable 모든 형식을 자동으로 열거하고 파이프라인을 통해 멤버를 한 번에 하나씩 보냅니다. 단, 메서드를 호출 [hashtable] 해야 하는 는 예외GetEnumerator()입니다.

다음 예제에서는 배열과 해시 테이블을 Measure-Object cmdlet에 파이프하여 파이프라인에서 받은 개체 수를 계산합니다. 배열에는 여러 멤버가 있고 해시 테이블은 여러 키-값 쌍을 가합니다. 배열은 순차적으로 하나씩 처리됩니다.

@(1,2,3) | Measure-Object
Count    : 3
Average  :
Sum      :
Maximum  :
Minimum  :
Property :
@{"One"=1;"Two"=2} | Measure-Object
Count    : 1
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

마찬가지로, 여러 프로세스 개체를 Get-Process cmdlet에서 Get-Member cmdlet으로 파이프라인하면 PowerShell은 각 프로세스 개체를 하나씩 Get-Member로 전송합니다. Get-Member 프로세스 개체의 .NET 클래스(형식)와 해당 속성 및 메서드를 표시합니다.

Get-Process | Get-Member
TypeName: System.Diagnostics.Process

Name      MemberType     Definition
----      ----------     ----------
Handles   AliasProperty  Handles = Handlecount
Name      AliasProperty  Name = ProcessName
NPM       AliasProperty  NPM = NonpagedSystemMemorySize
...

비고

Get-Member 중복을 제거하므로 개체가 모두 동일한 형식이면 하나의 개체 형식만 표시됩니다.

그러나 Get-Member 매개 변수를 사용하는 경우 Get-MemberSystem.Diagnostics.Process 개체 배열을 단일 단위로 받습니다. 개체 배열의 속성을 표시합니다. ([] 형식 이름 뒤의 배열 기호()를 확인합니다.

예를 들면 다음과 같습니다.

Get-Member -InputObject (Get-Process)
TypeName: System.Object[]

Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
Address            Method        System.Object& Address(Int32 )
Clone              Method        System.Object Clone()
...

이 결과는 의도한 결과가 아닐 수 있습니다. 그러나 이해한 후에는 사용할 수 있습니다. 예를 들어 모든 배열 개체에는 Count 속성이 있습니다. 이를 사용하여 컴퓨터에서 실행 중인 프로세스 수를 계산할 수 있습니다.

예를 들면 다음과 같습니다.

(Get-Process).count

파이프라인 아래로 전송된 개체는 한 번에 하나씩 배달된다는 점을 기억해야 합니다.

파이프라인 오류 조사

PowerShell이 파이프된 개체를 수신 cmdlet의 매개 변수와 연결할 수 없으면 명령이 실패합니다.

다음 예제에서는 레지스트리 항목을 한 레지스트리 키에서 다른 레지스트리 키로 이동하려고 합니다. Get-Item cmdlet은 대상 경로를 가져온 후 그 경로를 Move-ItemProperty cmdlet에 전달합니다. Move-ItemProperty 명령은 이동할 레지스트리 항목의 현재 경로와 이름을 지정합니다.

Get-Item -Path HKLM:\Software\MyCompany\sales |
Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product

명령이 실패하고 PowerShell에서 다음 오류 메시지를 표시합니다.

Move-ItemProperty : The input object can't be bound to any parameters for
the command either because the command doesn't take pipeline input or the
input and its properties do not match any of the parameters that take
pipeline input.
At line:1 char:23
+ $a | Move-ItemProperty <<<<  -Path HKLM:\Software\MyCompany\design -Name p

조사하려면 Trace-Command cmdlet을 사용하여 PowerShell의 매개 변수 바인딩 구성 요소를 추적합니다. 다음 예제에서는 파이프라인이 실행되는 동안 매개 변수 바인딩을 추적합니다. PSHost 매개 변수는 콘솔에 추적 결과를 표시하고 FilePath 매개 변수는 나중에 참조하기 위해 추적 결과를 debug.txt 파일로 보냅니다.

Trace-Command -Name ParameterBinding -PSHost -FilePath debug.txt -Expression {
  Get-Item -Path HKLM:\Software\MyCompany\sales |
    Move-ItemProperty -Path HKLM:\Software\MyCompany\design -Name product
}

추적 결과는 길지만, Get-Item cmdlet에 값이 바인딩되는 것과 명명된 값이 Move-ItemProperty cmdlet에 바인딩되는 것을 보여줍니다.

...
BIND NAMED cmd line args [`Move-ItemProperty`]
BIND arg [HKLM:\Software\MyCompany\design] to parameter [Path]
...
BIND arg [product] to parameter [Name]
...
BIND POSITIONAL cmd line args [`Move-ItemProperty`]
...

마지막으로 Move-ItemProperty 매개 변수에 경로를 바인딩하려는 시도가 실패했음을 보여줍니다.

...
BIND PIPELINE object to parameters: [`Move-ItemProperty`]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values
Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO
COERCION
...

Get-Help cmdlet을 사용하여 Destination 매개 변수의 특성을 봅니다.

Get-Help Move-ItemProperty -Parameter Destination

-Destination <String>
    Specifies the path to the destination location.

    Required?                    true
    Position?                    1
    Default value                None
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

결과에 따르면 대상은 파이프라인 입력을 오직 '속성 이름별'로만 받습니다. 따라서 파이프된 개체에는 대상로 명명된 속성이 있어야 합니다.

Get-Member 사용하여 Get-Item들어오는 개체의 속성을 확인합니다.

Get-Item -Path HKLM:\Software\MyCompany\sales | Get-Member

출력은 항목이 Destination 속성이 없는 Microsoft.Win32.RegistryKey 개체임을 보여줍니다. 명령이 실패한 이유를 설명합니다.

Path 매개 변수는 이름 또는 값별로 파이프라인 입력을 허용합니다.

Get-Help Move-ItemProperty -Parameter Path

-Path <String[]>
    Specifies the path to the current location of the property. Wildcard
    characters are permitted.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  true

명령을 수정하려면 Move-ItemProperty cmdlet에서 대상을 지정하고 Get-Item 사용하여 이동하려는 항목의 경로 가져와야 합니다.

예를 들면 다음과 같습니다.

Get-Item -Path HKLM:\Software\MyCompany\design |
Move-ItemProperty -Destination HKLM:\Software\MyCompany\sales -Name product

내재적 줄 연속

이미 설명한 대로 파이프라인은 일반적으로 한 줄로 작성된 파이프라인 연산자(|)로 연결된 일련의 명령입니다. 그러나 가독성을 위해 PowerShell을 사용하면 파이프라인을 여러 줄로 분할할 수 있습니다. 파이프 연산자가 줄의 마지막 토큰인 경우 PowerShell 파서는 다음 줄을 현재 명령에 조인하여 파이프라인의 생성을 계속합니다.

예를 들어 다음 단일 줄 파이프라인은 다음과 같습니다.

Command-1 | Command-2 | Command-3

은 다음과 같이 작성할 수 있습니다.

Command-1 |
  Command-2 |
    Command-3

다음 줄의 선행 공백은 중요하지 않습니다. 들여쓰기를 통해 가독성이 향상됩니다.

또한 참조하십시오

about_PSReadLine

객체_정보

매개변수_정보

명령어 구문에 관하여

ForEach 개요