Windows PowerShell출력 서식 지정하기

Don Jones

스크립트로 보다 멋진 출력을 얻고 싶은 욕심은 특별한 것이 아니며, 저도 종종 테이블 같은 형태를 출력하기 위한 최상의 방법에 대한 질문을 받곤 합니다. 실제로 이러한 작업을 수행하는 데는 몇 가지 방법이 있습니다. 첫 번째 단계는 데이터, 즉 서식이 있는 형태로 표시할 모든 데이터를

$data1, $data2 및 $data3이라는 이름이 지정된 변수에 넣는 스크립트를 작성하는 것입니다. 그러면 데이터 서식 지정 단계로 들어갈 수 있습니다.

텍스트 방식

웹에서

이 달의 Windows PowerShell 컬럼에서 설명한 기법을 간략하게 살펴보시겠습니까? Don Jones가 이러한 cmdlet를 어떻게 사용하는지 보려면 technetmagazine.com/video로 이동하십시오.

이 작업을 수행하기 위한 가장 일반적인 방법은 VBScript, Perl, KiXtart 또는 기타 텍스트 지향 언어에서 작업할 때와 동일한 방식을 사용하는 것입니다. 다음과 같은 열 머리글을 화면에 입력하는 것부터 시작할 수 있습니다.

Write-Host "ColumnA'tColumnB'tColumnC"

`t는 탭 문자를 삽입하는 Windows PowerShellTM의 특수 이스케이프 시퀀스입니다. 데이터가 $data1, $data2 및 $data3일 때 테이블의 각 행을 표시하는 방법에는 몇 가지가 있습니다. 한 가지 방법은 다음과 같이 큰 따옴표 안의 내용으로 변수를 대체할 수 있는 셸 기능을 사용하여 간단히 변수를 작성하는 것입니다.

Write-Host "$data1't$data2't$data3"

약간 더 매력적인 또 한 가지 방법은 -f 연산자를 사용하는 것입니다. 이 기법은 데이터와 서식을 분리하며, 코드를 보다 읽기 쉽고 관리하기 쉽게 하는 방법입니다.

Write-Host "{0}'t{1}'t{3}" –f $data1,$data2,$data3

그러나 이 전체적인 접근 방법에는 심각한 문제가 있습니다. 먼저 콘솔 창의 고정 탭 정지 위치에 의존함으로써 뜻밖의 서식이 생길 수 있습니다. 예를 들면, 특정 테이블 행의 첫 번째 열에 20자의 값이 있는 경우 이 행의 전체 서식이 맞지 않게 될 수 있습니다. 또한 Write-Host를 사용하여 이 텍스트를 출력하므로 콘솔 디스플레이로만 제한됩니다.

이 출력을 파일로 보내거나 다른 서식으로 전환할 수 있는 간단한 방법은 없습니다. 가장 중요한 점은 이 텍스트 기반 접근 방식에서는 본질적으로 작업 중인 개체 기반 셸을 완전히 무시하므로 Windows PowerShell에서 제공하는 모든 훌륭한 기법과 기능을 활용할 수 없다는 사실입니다.

Windows PowerShell 방식

Windows PowerShell은 개체 지향 셸입니다. 따라서 가급적이면 작업하는 모든 요소가 개체여야 합니다. 그래야만 셸에서 필요할 때 텍스트 디스플레이로 전환할 수 있습니다. 하지만 임의의 데이터에 대해 개체를 어떻게 생성할까요?

이 예에서는 빈 사용자 지정 개체를 만들어서 그 개체를 변수에 저장하는 것부터 시작합니다.

 $obj = New-Object PSObject

이렇게 하면 사용할 수 있는 새로운 빈 개체가 만들어집니다. 그런 다음 데이터를 속성 형태로 개체에 추가합니다. 이렇게 하기 위해 개체를 Add-Member cmdlet로 간단히 파이프합니다. NoteProperty라는 것을 추가하고 속성 이름을 지정한 다음 속성 값으로 데이터를 삽입합니다. 속성의 이름을 지정할 때는 열 머리글을 사용하는 것이 좋습니다.

 $obj | Add-Member NotePropertyColumnA $data1
$obj | Add-Member NotePropertyColumnB $data2
$obj | Add-Member NotePropertyColumnC $data3

이제 간단히 이 개체를 콘솔이 아닌 파이프라인으로 출력합니다.

Write-Output $obj

그런 다음 출력해야 할 각 테이블 행에 대해 위의 단계를 반복하면 됩니다. 다음은 문자열을 받아 원래 문자열과 함께 대/소문자 버전을 출력하는 간단한 함수입니다.

functionStringVersions {
param([string]$inputString)
  $obj = New-Object PSObject
  $obj | Add-Member NoteProperty Original($inputString)
  $obj | Add-Member NoteProperty Uppercase($inputString.ToUpper())
  $obj | Add-Member NoteProperty Lowercase($inputString.ToLower())
  Write-Output $obj
}  
$strings = @("one","two","three")
foreach ($item in $strings) {
StringVersions $item
}

문자열 변수 배열로 시작하여 한 번에 각각 하나씩 진행하며 각 변수를 함수로 보냅니다. 그리고 함수의 출력이 파이프라인에 기록됩니다.

이 코드를 작성하는 보다 간단한 방법도 있지만, 여기서는 설명하려는 점을 명확히 보여 주기 위해 이 기법을 선택했습니다. 이 코드 실행에 따른 결과는 그림 1에 표시된 것처럼 완벽하게 서식이 지정된 테이블입니다. 이러한 결과는 셸이 테이블에서 개체에 대한 서식을 어떻게 지정할지 이미 알고 있기 때문입니다.

그림 1 테이블에 표시된 Windows PowerShell 출력

그림 1** 테이블에 표시된 Windows PowerShell 출력 **(더 크게 보려면 이미지를 클릭하십시오.)

개체의 속성이 네 개 이하인 경우 Windows PowerShell에서는 테이블을 자동으로 선택합니다. 따라서 아무 작업을 수행하지 않고도 멋진 모양의 테이블이 생성됩니다.

추가 기능

이달의 Cmdlet: Get-Command

사용 가능한 Windows PowerShell cmdlet 목록을 검토하기 위해 한두 번은 Get-Command 또는 간편한 앨리어스 gcm을 사용해 보았을 것입니다. 하지만 gcm이 실제로 얼마나 유연한지는 모를 수 있습니다. 예를 들어, 서비스를 사용하여 Windows PowerShell에서 수행할 수 있는 모든 것을 보려면 gcm -noun service를 실행합니다. 또는 Windows PowerShell 내보내기 옵션을 모두 보려면 gcm -verb export를 실행해 봅니다. PowerShell Community Extensions와 같은 특정 스냅인을 통해 추가된 cmdlet만 확인하려는 경우에는 gcm -pssnapin pscx를 실행합니다. "pscx"를 다른 스냅인 이름으로 바꾸면 해당 스냅인의 cmdlet를 볼 수 있습니다.

보시는 것처럼 이 Get-Command는 Windows PowerShell의 검색 기능에서 중요 역할을 담당합니다. Get-Command를 사용하면 설명서를 보지 않고도 사용할 수 있는 기능을 알아볼 수 있습니다. 또한 gcm은 Help*와 같은 명령을 사용할 때보다 훨씬 더 정확한 검색 기능을 제공합니다. Help 함수는 사용 가능한 도움말 항목만 나열합니다. 필요로 하는 cmdlet가 있다고 해도 help와 함께 제공되지 않은 cmdlet는 도움말 목록에 표시되지 않습니다.

이 기법의 이점은 테이블보다 훨씬 더 뛰어난 기능을 제공한다는 점입니다. 개체 작업 시 Windows PowerShell은 다양한 작업을 수행하는 방법을 알고 있습니다. CSV 파일 형태의 데이터를 원하십니까? Export-CSV를 사용하십시오. HTML 테이블을 선호하십니까? 개체를 ConvertTo-HTML로 파이프하십시오. 목록 서식이 필요하십니까? 개체를 Format-List로 파이프하십시오. 개체를 사용하면 셸에서 이미 수행 방법을 알고 있는 모든 기능을 사용할 수 있습니다. 다음은 위의 코드를 수정한 예입니다.

functionStringVersions {
  PROCESS {
   $obj = New-Object PSObject
   $obj | Add-Member NoteProperty Original($_)
   $obj | Add-Member NoteProperty Uppercase($_.ToUpper())
   $obj | Add-Member NoteProperty Lowercase($_.ToLower())
   Write-Output $obj
}
}

여기서는 파이프라인 입력을 허용하고 파이프라인으로 출력하도록 함수를 수정했습니다. 개체를 사용하려는 경우에는 언제나 이 방법이 더 좋습니다.

이제 이 함수의 PROCESS 스크립트 블록 내부에 코드가 들어 있습니다. 따라서 이 함수가 파이프라인 입력을 허용하고 파이프된 각 개체에 대해 한 번씩 PROCESS 스크립트 블록을 실행합니다.

PROCESS 스크립트 블록 내에서 특수 $_ 변수는 처리 중인 현재 파이프라인 개체를 나타냅니다. 이 예를 통해 문자열 배열로 간단히 파이프할 수 있다는 점을 알 수 있습니다.

@("one","two","three") | StringVersions

이 함수가 출력을 파이프라인에 추가하기 때문에 결과적으로 테이블이 만들어집니다. 파이프라인 끝에서 셸은 서식 지정 하위 시스템을 호출해야 한다는 사실을 알고 있습니다. 따라서 파이프라인의 개체 속성이 5개 미만이므로 테이블을 사용하기로 결정합니다. 속성이 더 많을 경우 셸은 기본적으로 목록을 사용합니다.

하지만 기본 동작에 의존할 필요는 없습니다. 이러한 개체를 간단히 다른 cmdlet에 파이프하여 개체로 다른 작업을 수행할 수도 있습니다.

@("one","two","three") | StringVersions | Format-List
@("one","two","three") | StringVersions | ConvertTo-HTML | Out-File "strings.html"
@("one","two","three") | StringVersions | Export-CSV "strings.csv"
@("one","two","three") | StringVersions | Select Uppercase,Lowercase -unique

그림 2는 두 번째 예의 결과 HTML을 웹 브라우저에 표시한 것입니다. 단지 출력 데이터를 단순 텍스트가 아닌 개체로 표현함으로써 이제 셸에 기본으로 제공되는 다양한 서식 지정 레이아웃, HTML 변환, 내보내기 옵션, 정렬, 필터링 및 그룹화 기능 등 풍부한 기능을 최대로 활용할 수 있습니다.

그림 2 HTML 형식으로 출력된 Windows PowerShell 데이터

그림 2** HTML 형식으로 출력된 Windows PowerShell 데이터 **(더 크게 보려면 이미지를 클릭하십시오.)

이것은 매우 유용한 기능입니다. 가급적이면 작성하는 모든 스크립트에서 개체를 출력으로 생성하는 것이 좋습니다. 그러면 추가 코드를 한 줄도 작성하지 않고도 가능한 한 다양한 방법으로 출력을 사용할 수 있습니다.

Don Jones는 Windows 관리 자동화 전문가이며 Windows PowerShell: TFMVBScript, WMI, and ADSI Unleashed 등의 서적을 집필했습니다. ScriptingAnswers.com의 포럼을 통해 Don Jones와 만날 수 있습니다.

© 2008 Microsoft Corporation 및 CMP Media, LLC. All rights reserved. 이 문서의 전부 또는 일부를 무단으로 복제하는 행위는 금지됩니다..