Hey, Scripting Guy!컵 홀더는 어디 있을까요?

Microsoft Scripting Guys

이 칼럼은 Windows PowerShell의 시험판 버전을 기준으로 작성되었습니다. 이 문서에 수록된 모든 정보는 변경될 수 있습니다.

새로운 기술이 소개된 후 사람들이 구기술과의 차이를 실제로 인식하기 위해서는 어느 정도의 시간이 필요합니다. 최초의 자동차를 생각해 보세요. 이 기묘한 기계는 말이 끄는 마차와 같은 일을 했기 때문에 말 없는 마차라고 불렸습니다. 생각해 보면 최초의 자동차와 마차의 차이점은 마차에는 말이 필요하고 자동차에는 말이 필요 없다는 것뿐입니다. 그것을 제외하면 그 둘을 구별하기란 매우 어렵지요.

물론 오늘날에 자동차와 말이 끄는 마차를 혼동하는 사람은 없습니다. 그것은 바로 오랜 세월 동안 자동차를 만든 사람들의 노력의 결과로 자동차와 마차가 명확하게 구분되었기 때문입니다. 오늘날 자동차는 CD 플레이어, 에어컨, 위성 네비게이션 시스템 등이 완비된 상태로 공장에서 직접 출하되지만 말이 끄는 마차는 그렇지 않습니다. 1880년대에 말이 끄는 마차를 몰고 있을 때 잠깐 동안 프라푸치노를 놓아 두어야 하는 상황이 발생했다고 생각해 보세요. 무척 난감했을 테지요? 그렇지만 요새 SUV에는 기본적으로 컵 홀더가 17개까지 마련되어 있고 운전자만을 위한 컵 홀더를 3개나 마련해 둔 자동차도 있습니다. 일부 신모델의 경우에는 필요에 따라 음료를 데우거나 차게 할 수 있는 컵 홀더도 있습니다.

참고 과거에 운전할 때는 세 가지 음료수를 마실 수 없었다는 것은 참으로 믿기 힘든 이야기네요. 한두 가지 음료수만을 마시면서 운전해야 했으니 정말로 힘들었겠지요?

신기술이 실질적인 성공을 거두려면 기존의 안정적인 기술보다 미지의 새로운 기술이 좋은 이유를 사람들이 알 수 있어야 합니다. DVD가 처음에 출시되었을 때 DVD는 비디오 레코더와 마찬가지로 집에서 영화를 보는 데 사용되었습니다. 그렇지만 DVD는 비디오 카세트에 비해 비쌌으며 DVD 플레이어에는 녹화 기능이 없었습니다. DVD가 선풍적인 인기를 끌지 못한 것은 당연한 결과일 테지요. 그렇지만 DVD 제조업체에서 삭제된 장면, 영화에서는 볼 수 없었던 배우들의 해설, 카세트 테이프에서는 얻을 수 없는 여러 가지 것들을 디스크에 포함하기 시작하면서 이전까지는 별로였던 DVD의 인기가 경쟁 기술인 VHS를 압도하기 시작했습니다. 집에서 영화를 볼 수 있다는 것만으로는 부족했기 때문에 DVD 제조업체에서는 사람들이 이미 가지고 있는 것을 넘어서는 무언가를 제공해야 했던 것입니다.

참고 사람들이 이러한 보너스 항목을 실제로 보았는지는 사실 중요하지 않습니다. 인간이란 존재는 무엇인가가 있으면 그것을 가져야 하기 때문이죠. 마침 Scripting Guy도 TechNet Magazine 칼럼에서 편집된 내용과 시스템 관리 스크립트에 대한 다른 결론으로 구성된 DVD 제작을 고려하고 있답니다.

Windows PowerShell 사용

이런 이야기는 Microsoft에서 출시한 새로운 명령 셸/스크립트 기술인 Windows PowerShell™에도 적용됩니다. Windows PowerShell을 처음 접할 때 사람들은 대개 이런 이야기를 듣게 됩니다.

  • "Windows PowerShell을 사용하면 프로세스와 서비스를 관리할 수 있습니다."
  • "Windows PowerShell을 사용하면 이벤트 로그에서 이벤트를 검색할 수 있습니다."
  • "Windows PowerShell에서는 WMI를 사용하여 컴퓨터를 관리할 수 있습니다."

이 이야기에는 잘못된 내용이 하나도 없을 뿐만 아니라 이러한 작업은 모두 유용하고 중요합니다. 이 이야기의 단 한 가지 문제는 이미 VBScript 및 Windows Script Host를 사용해서 그러한 작업을 모두 수행할 수 있다는 점입니다. 이전 버전과의 호환성이 중요한데 VBScript에서 수행할 수 있는 작업을 Windows PowerShell에서 수행할 수 없다면 Windows PowerShell은 대단한 혁신이 아닐 것입니다. 영화를 재생할 수 없는 DVD 플레이어를 상상해 보십시오. 사실 상상할 필요도 없습니다. Scripting Guy 중 한 명이 그런 DVD 플레이어를 갖고 있으니까요.

또한 Windows PowerShell이 VBScript에서 수행할 수 있는 작업만을 수행할 수 있다면 이 신기술 때문에 처음부터 고생할 필요가 없을 것입니다. 그러나 분명한 점은 VBScript에는 컵 홀더가 없다는 것입니다. 또한 Windows PowerShell도 마찬가지입니다. 그렇다면 이 새로운 스크립트 기술에는 어떤 차별성이 있을까요?

솔직히 말해서 Windows PowerShell에는 특별한 차이점이 없습니다. 컵 홀더가 없기는 하지만 Windows PowerShell에는 VBScript에 없는 몇 가지 기능이 있습니다. "고장나지 않은 것은 고치려고 하지 말라."는 말처럼 프로세스와 서비스를 관리하는 작업만 필요한 경우에는 Windows PowerShell을 고려할 만한 특별한 이유가 없을 것입니다. Scripting Guy는 이 말을 "고치려고 하면 고장나므로 고치지 말라."라고 이해합니다. Windows PowerShell을 사용해서 VBScript에서 할 수 없는 작업을 할 수 있을 때 Windows PowerShell의 진정한 가치가 드러날 것입니다. 그 예로 파일에 마지막으로 쓴 시간 변경과 같은 작업이 있습니다.

마지막 쓴 시간 변경

방금 전 파일에 마지막으로 쓴 시간 변경에 대해 이야기했습니다. 빠르고 간편한 버전 제어 양식과 같은 다양한 이유로 스크립트 작성자들은 항상 파일에 마지막으로 쓴 시간(또는 만든 시간)을 변경할 수 있는 날이 오기를 고대하고 있습니다. 불행하게도 WMI(Windows Management Instrumentation)나 FileSystemObject에서는 이 기능을 제공하지 않으며, 이 같은 기술에서는 파일 날짜와 시간이 읽기 전용으로 설정되어 있습니다.

그러나 Windows PowerShell에서는 다음 명령을 실행하면 간단하게 파일의 마지막 쓴 시간을 현재 날짜 및 시간으로 변경할 수 있습니다.

$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = Date

이 명령의 작동 방법을 설명하기 전에 먼저 모든 분이 궁금해하실 "WMI로는 할 수 없는데 어떻게 Windows PowerShell로는 파일에 마지막으로 쓴 시간의 변경이 가능할까"라는 질문에 대한 답을 드리겠습니다. 이것은 Windows PowerShell과 관련된 일반적인 오해를 단적으로 드러내는 질문이기 때문에 먼저 이 질문에 대답한 후 시작하는 것이 좋을 것 같습니다. 많은 사람들은 Windows PowerShell을 단지 WMI를 사용하는 새로운 방법 정도로 생각합니다. 그렇습니다. Windows PowerShell을 사용해서 WMI 데이터에 액세스할 수 있다는 것도 분명한 사실이며, 우리가 cmdlet(네이티브 Windows PowerShell 명령)이 추가로 만들어지기를 기다리는 동안 대부분의 시스템 관리 스크립트는 계속해서 WMI에 의지하게 될 것입니다. 그러나 Windows PowerShell은 .NET Framework를 기반으로 하며 Windows PowerShell cmdlet은 WMI 개체보다는 .NET 개체를 주로 다룹니다. 이 점은 .NET Framework를 통해 사용할 수 있는 속성이 WMI를 통해 사용할 수 있는 속성과 반드시 일치하지는 않기 때문에 잘 기억해 두어야 합니다.

예를 들어 Get-Item cmdlet을 사용하여 파일에 바인딩하면 WMI CIM_Datafile 클래스 인스턴스를 가져오지 않고 .NET 개체를 가져옵니다. 이 점이 크게 문제가 될까요? 그렇습니다. .NET 개체의 파일 관리 관련 속성 및 메서드 집합은 WMI의 것과 아주 작은 부분이 다릅니다. 앞에서 본 것처럼 속성이 읽기 전용일 때와 읽기/쓰기일 때 차이가 있듯이 이러한 약간의 차이가 매우 중요한 의미를 가질 수 있습니다.

질문으로 돌아가서 Get-Item cmdlet이 .NET 개체를 반환한다는 것을 어떻게 알 수 있겠습니까? 이 경우, 그리고 대부분의 경우 지금 다루고 있는 개체의 유형을 가장 쉽게 확인할 수 있는 방법(또한 사용할 수 있는 속성과 메서드를 식별할 수 있는 가장 쉬운 방법)은 파일에 바인딩한 다음 해당 개체를 Get-Member cmdlet에 전달하는 것입니다.

Get-Item c:\scripts\test.txt | Get-Member

그림 1에서는 이 명령의 결과를 보여 줍니다. 이 결과를 보면 .NET 개체라는 것을 확실히 알 수 있습니다(Scripting Guy가 무엇인가 잘못한 것처럼!).

Figure 1 Get-Item이 반환하는 개체의 구성원

   
TypeName: System.IO.FileInfo

Name                      MemberType     Definition
----                      ----------     ----------
AppendText                Method         System.IO.StreamWriter AppendText()
CopyTo                    Method         System.IO.FileInfo CopyTo(String destFileName),
                                         System.IO.FileInfo CopyTo(S...
Create                    Method         System.IO.FileStream Create()
CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(
                                         Type requestedType)
CreateText                Method         System.IO.StreamWriter CreateText()

우연히도 이 간단한 명령은 Windows PowerShell의 기능 중 파이프라인과 메타 정보라는 두 가지 흥미롭고 유용한 기능을 보여 줍니다. 오늘은 기술적인 내용을 자세하게 다루지는 않겠지만 파이프라인의 기본 개념은 cmdlet을 사용하여 개체를 가져와서 다른 cmdlet에 전달할 수 있다는 것입니다. 이 명령에서는 Get-Item cmdlet을 사용해서 C:\Scripts\Test.txt 파일을 나타내는 개체를 가져온 다음 해당 개체를 파이프라인을 통해 개체로 Get-Member cmdlet에 전달합니다. | 기호는 Windows PowerShell 명령에서 파이프라인을 나타냅니다.

그런 다음 Get-Member는 검색된 개체의 속성과 메서드를 검색하는 작업을 수행합니다. 이 기능은 Windows PowerShell의 여러 유용한 기능 중 하나입니다. 이 기능을 이용하면 정보에 대한 정보인 메타 정보에 쉽게 액세스할 수 있습니다. WMI 스크립트를 작성하여 사용 가능한 WMI 클래스, 속성 및 메서드에 대한 정보를 검색할 때와 마찬가지 방법으로 Get-Member 및 Get-Command와 같은 cmdlet을 사용하여 Windows PowerShell의 정보를 검색할 수 있습니다.

Get-Member는 WMI로 수행할 수 있는 작업보다 한 단계 발전된 기능을 제공합니다. WMI를 사용하여 WMI 개체 정보를 가져올 수 있지만 WMI로 다른 COM 개체(예: FileSystemObject)에 대한 정보를 가져올 수는 없습니다. 그러나 Windows PowerShell에서는 다릅니다. Get-Member는 사용자가 바인딩하거나 만들 수 있는 모든 개체에 대해 작동합니다. FileSystemObject를 사용할 때 사용할 수 있는 메서드가 기억나지 않나요? 그렇다면 다음 명령을 실행하십시오.

New-Object -comobject "Scripting.     FileSystemObject" | Get-Member

이 기능은 그리 많이 이용되지는 않지만 대단히 유용한 기능입니다.

훌륭하지 않습니까? C:\Scripts\Test.txt 파일에 대한 작업을 수행할 때 사용할 수 있는 속성 및 메서드 목록을 스크롤하면 다음 줄을 보게 될 것입니다.

LastWriteTime             Property       System.DateTime LastWriteTime {get;set;}

흥미로우시지요? 분명 LastWriteTime은 get(읽기)과 set(쓰기)을 모두 지원하는 속성입니다. 그렇다고 해서 Windows PowerShell을 이용해서 파일에 마지막으로 쓴 시간의 값을 변경할 수 있는 것일까요? 글쎄요.

Windows PowerShell 용어

별칭 기존 cmdlet을 나타내는 사용자 지정 가능한 이름입니다. Windows PowerShell에는 일반적인 셸 명령을 해당 cmdlet에 매핑하는 기본 별칭이 많이 있습니다.

Cmdlet Windows PowerShell의 최소 기능 단위이며, 다른 셸의 기본 제공 명령과 비슷합니다.

명령 Windows PowerShell의 실행 단위입니다. 명령에는 파이프로 연결된 여러 작업이 포함될 수 있으며 ; 문자를 사용하여 여러 줄로 분리할 수 있습니다.

프라푸치노 스타벅스에서 판매하는 아이스 커피입니다.

Monad/MSH/Microsoft Command Shell Windows PowerShell의 이전 코드명입니다.

개체 시스템이나 명령에서 검색되는 구조화된 데이터입니다. Windows PowerShell은 데이터를 .NET 개체로 조작하므로 텍스트 기반 명령 출력을 구문 분석할 필요가 없으며 이름을 사용하여 개체 속성을 조작할 수 있습니다.

매개 변수 명령줄에 사용되는 cmdlet의 옵션 집합입니다. Windows PowerShell에서는 처음에 하이픈(-) 문자를 사용하여 매개 변수를 지정합니다.

파이프라인 한 명령의 출력을 다른 명령의 입력으로 보내는 데 사용됩니다. 파이프라고도 하며 명령에서 | 문자로 표시됩니다.

프로필 Windows PowerShell이 시작될 때 로드되는 설정으로 셸의 작동 방법을 구성하는 데 사용됩니다.

스크립트 파일로 저장되어 실행되는 하나 이상의 명령입니다. Windows PowerShell에서는 .ps1 확장명을 스크립트 파일에 사용합니다.

셸 명령과 cmdlet을 모두 실행할 수 있는 명령줄 환경입니다.

변수 명령 실행 중에 값을 설정, 변경 또는 검색할 수 있는 개체 또는 매개 변수입니다.

이제 다시 Test.txt 파일에 마지막으로 쓴 시간을 현재 날짜 및 시간으로 설정하는 명령에 대한 이야기로 돌아가겠습니다. 예를 들면 다음과 같습니다.

$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = Date

실제로 이 명령은 매우 간단합니다. 먼저 $a라는 변수를 선언합니다. 그런 다음 Get-Item cmdlet을 사용하여 C:\Scripts\Test.txt 파일에 연결하고 해당 개체를 변수 $a에 저장합니다. 한 줄에서 여러 명령을 실행할 때 사용하는 세미콜론을 입력한 후 LastWriteTime 속성의 값을 현재 날짜 및 시간으로 설정합니다. 컵 홀더가 없는 아쉬움을 충분히 메워 주는 좋은 기능이지 않습니까?

응용하기

물론 마지막으로 쓴 시간을 현재 날짜 및 시간으로 설정하는 것 외에도 여러 작업을 수행할 수 있습니다. 다음 명령을 살펴보십시오.

$b = Get-Date "5/22/2006 8:15 PM";
$a = Get-Item c:\scripts\test.txt; $a.LastWriteTime = $b

이번에는 세 개의 명령을 연결했습니다. 먼저 Get-Date cmdlet을 사용하여 5/22/2006, 8:15 PM이라는 값을 가진 날짜 시간 개체를 만듭니다. 마지막으로 쓴 시간을 현재 날짜 및 시간으로 설정하는 첫 번째 스크립트에서 날짜 시간 개체를 만들 때 왜 Get-Date를 사용하지 않았을까요? 이유는 간단합니다. Date 명령은 자동으로 날짜 시간 개체를 반환하기 때문입니다. 직접 확인해 보려면 Windows PowerShell 콘솔에 Date | Get-Member 명령을 입력해 보십시오.

원하는 날짜 및 시간으로 설정된 날짜 시간 개체를 만든 다음에는 익숙한 Get-Item 명령을 사용하여 Test.txt 파일을 나타내는 개체(변수 $a에 저장한 개체)를 가져옵니다. 마지막으로 LastWriteTime 속성을 변수 $b가 나타내는 값으로 설정합니다.

$a.LastWriteTime = $b

믿어지지 않을 수도 있겠지만 지금까지 살펴본 기능은 일부에 불과합니다. 평범해 보이는 명령을 하나 살펴보겠습니다.

$b = Get-Date "5/22/2006 8:15 PM";
Get-ChildItem c:\scripts | ForEach-Object {$_.LastWriteTime = $b}

이 명령에 흥미로운 점이 있습니까? 이 명령이 어떤 기능을 수행하는지 살펴보시죠. 첫 번째 부분은 쉽습니다. 첫 번째 부분에서는 다시 한번 5/22/2006 8:15 PM이라는 값을 가진 날짜 시간 개체를 만듭니다. 그러나 두 번째 부분에서는 Get-Item cmdlet을 사용하지 않고 다음 명령을 사용합니다.

Get-ChildItem c:\scripts

이 명령의 핵심은 무엇일까요? Get-ChildItem cmdlet을 폴더에 적용하면 해당 폴더에 있는 모든 파일의 컬렉션이 반환됩니다. 컬렉션을 받아서 컬렉션의 모든 항목을 파이프라인(| 기호)을 통해 ForEach-Object cmdlet에 전달합니다.

이제 ForEach-Object는 이 모든 파일을 가지고 어떤 작업을 수행할까요? 그렇습니다. 다음과 같이 각 파일 및 모든 파일의 LastWriteTime 속성 값을 변경할 것입니다.

ForEach-Object {$_.LastWriteTime = $b}

참고 이 달의 칼럼은 Windows PowerShell 초보자를 위한 것이 아니기는 하지만 초보자를 위해 간단하게 설명하자면 $_는 For Each 루프의 현재 항목을 나타내는 특수한 변수로서 다음 VBScript 루프에 사용되는 objItem과 같습니다.

For Each objItem in colItems
    Wscript.Echo objItem.Name
Next

이 Windows PowerShell 명령의 실행이 종료되면 C:\Scripts 폴더에 있는 모든 파일의 마지막 쓴 시간이 동일한 시간으로 설정됩니다. 우리는 이 새로운 말 없는 마차가 움직이는 모습을 보고 싶습니다.

밤새도록 이 명령을 변형하여 실행할 수 있습니다. 예를 들어 C:\Scripts 폴더에서 .txt 파일의 마지막 쓴 시간만 바꾸고 싶으신가요? 물론 가능합니다. 말씀만 하십시오.

$b = Get-Date "5/22/2006 8:15 PM"; Get-ChildItem c:\scripts\*.txt | ForEach-Object {$_.LastWriteTime = $b}

올바른 선택

정말 멋지지 않습니까? 그러나 이 칼럼의 목적은 Windows PowerShell의 "판매를 권유"하거나 VBScript 스크립트를 던져 버리고 Windows PowerShell로 바꾸라고 권하는 것이 아닙니다. VBScript 스크립트를 계속 사용하고 싶고 필요하다면 그대로 사용하면 됩니다. 컴퓨터 관리에 사용되는 배치 파일, 명령줄 도구, 마법의 주문 및 다른 도구의 경우에도 마찬가지입니다. "고장나지 않은 것은 고치려고 하지 말라."는 말을 기억하십시오.

중요한 것은 기존에 이미 할 수 있는 작업을 Windows PowerShell이 할 수 있다는 것이 아닙니다. .NET Framework에 액세스할 수 있기 때문에 Windows PowerShell은 기존에 할 수 없었던 작업을 할 수 있다는 것이 중요한 것입니다. 파일에 마지막으로 액세스한 시간을 수정하는 것은 이러한 특징을 보여 주는 한 가지 예입니다. 필요한 작업이 무엇인가에 따라 다른 예제들도 얼마든지 만들 수 있습니다. 바로 이런 장점 때문에 Windows PowerShell을 살펴볼 가치가 있는 것입니다.

아마도 저희가 Windows PowerShell을 소개하는 방식이 낯설게 느껴지셨을 것입니다. 간단한 "Hello, world"와 같은 예제부터 시작하지 않고 여러 부분으로 구성된 Windows PowerShell 명령으로 바로 들어가 파이프라인이나 cmdlet과 같은 용어를 모두 알고 있는 것으로 간주하고 설명을 생략하다 보니 익숙하지 않게 느껴지는 분들이 많았을 것입니다. 이 같은 방식은 모두 의도적인 것이었습니다. 물론 Windows PowerShell을 사용해 보지 않은 사람이 많다는 것을 알고 있었지만 또 다시 컴퓨터에서 서비스 목록을 검색하는 방법을 보여 주게 되면 여러분이 새롭다는 느낌을 받지 못하고 저희의 설명을 귀담아듣지 않게 될 것이라고 생각했기 때문입니다.

여러분이 부디 운전하지 않고 있었기를 바랍니다. 대부분의 사람들에게는, "TechNet Magazine을 읽지" 않더라도 운전하면서 세 가지 음료수를 마시고, DVD를 보고, 휴대 전화를 받는 것 자체로 굉장히 어려운 일이지요.

모두가 그렇다는 것은 아니고 대부분이 그렇다는 것이지요.

Microsoft Scripting Guys는 Microsoft에서 근무하는 직원들입니다. 이들은 야구 경기를 하거나, 감독하거나, 관람하는 등의 일상적인 다른 활동을 하지 않을 때 TechNet 스크립트 센터를 운영합니다. 자세한 내용은 https://www.microsoft.com/korea/technet/scriptcenter/default.mspx에서 확인하십시오.

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