Hey, Scripting Guy!짜릿한 흥분

Microsoft Scripting Guys

저희는 매달 TechNet Magazine에 기고하는 것만큼 흥분되는 일은 없다고 생각합니다. 그리고 마침내 게시되었을 때는 큰 보상을 얻은 느낌이죠.(물론 실제로 금전적인 보상을 받는다면 금상첨화겠지만, 뭐 어쩔 수 없죠.)얼마나 멋진 직업입니까?이렇게 말하고 싶군요.아마 지금 전 세계 어린이들은 잠자리에 들면서 엄마에게 "엄마, 난 이 다음에 크면 매달 TechNet Magazine에 스크립팅 칼럼을 연재할래요."라고 할 겁니다.

참고 물론 세계 곳곳에는 지금도 이 칼럼을 어린이가 연재하고 있는 게 아닌지 의심하는 분들이 있습니다.하지만 뭐, 그것도 어쩔 수 없죠.

Scripting Guy가 TechNet Magazine의 칼럼에 대한 대한 독자들의 칭찬에 얼마나 약한지는 이미 잘 알려져 있습니다. 사인을 부탁하며 몰려드는 팬들과 파파라찌에게도 항상 웃음을 잃지 않을 정도니까요.하지만 사실은 이런 명예나 명성보다는 시스템 관리 스크립트를 작성할 때 느껴지는 짜릿한 흥분 때문에 이 일을 그만 두지 못하는 것입니다.

물론 똑같은 상황이라도 짜릿한 흥분이라든가 시스템 관리 스크립팅이라는 표현을 사용하는 사람은 거의 없겠죠.(무슨 의미인지도 모르고 사용한다면 모를까요.)

일반인들은 대개 시스템 관리 스크립팅이 매우 유용하긴 하지만 그다지 재미있지는 않으며 오히려 따분한 일로 치부합니다.그건 그 사람들이Windows Vista®나 Windows Server® 2008에서 부팅 구성 데이터 스크립트를 작성해본 적이 없기 때문입니다.

이런 이야기를 들으니 슬슬 흥분되지 않나요?이 기사를 읽는 독자라면 아마 대부분 이미 알고 있겠지만 부팅 프로세스 관리와 관련하여 향상된 유연성과 기능을 제공하는 새로운 부팅 구성 데이터 저장소가 도입되면서 Windows Vista와 Windows Server 2008에서 기존 boot.ini 파일은 더 이상 사용되지 않습니다.

이러한 변화도 괜찮은 일이긴 하지만정말 멋진 것은새로운 WMI(Windows® Management Instrumentation) 공급자 덕분에 스크립트를 사용하여 BCD(부팅 구성 데이터) 저장소를 손쉽게 액세스하고 완벽하게 관리할 수 있게 되었다는 점입니다.

지금쯤 등골이 짜릿한 이상한 기분이 들지 않습니까? 그런 느낌이 바로 저희가 말하는 짜릿한 흥분입니다.BCD 스크립트를 사용하여 작업하다 보면 그런 기분을 자주 느끼게 될 겁니다.

본론으로 들어가기 전에 BCD 공급자의 모든 용도를 이 칼럼에서 모두 다룰 수는 없다는 점을 알아두시기 바랍니다.(Magazine 편집자들에게 부팅 구성 데이터 스크립트 작성에 대해서 심도 있게 다루는 특집 기사를 실을 수 있는지 묻는 전자 메일을 보냈지만 아무런 반응이 없습니다.)

따라서 자세한 내용을 알아보려면 BCD WMI 공급자 설명서(go.microsoft.com/fwlink/?LinkId=116953)를 참조하시기 바랍니다.이 칼럼에서는 운영 체제가 두 개 이상 설치된 멀티부팅 컴퓨터용 샘플 코드를 몇 가지 소개하겠습니다.

참, 여기서 소개하는 스크립트는 Windows Vista와 Windows Server 2008에만 적용됩니다.앞에서도 설명했듯이 현재 BCD를 지원하는 운영 체제가 이 두 가지밖에 없기 때문입니다.

그러면 먼저 현재 컴퓨터에서 사용 중인 OS를 확인하는 스크립트부터 살펴보겠습니다.물론 Win32_OperatingSystem이라는 WMI 클래스를 사용하면 현재 컴퓨터에서 사용 중인 OS를 확인할 수 있으므로 이것이 BCD 공급자만의 특별한 기능이라고 할 수는 없습니다.그러나 적어도 BCD 스크립트만 놓고 이야기한다면 이 스크립트는 꽤 간단하면서도 BCD 작업에 필요한 기본적인 기술을 잘 보여 줍니다.(어떻게 보면 좀 특이한 방법이긴 하네요.)

여담이지만, 칼럼을 보다 흥미진진하게 쓸 수 없어서 아쉽습니다.TechNet Magazine 측에서는 지나치게 열성적인 Hey, Scripting Guy! 팬들이 너무 흥분하여 발생하는 사고에 대한 책임은 전적으로 저희에게 있다고 경고하기도 했습니다.정규식에 대한 칼럼이 게재된 후에 전 세계에 걸쳐 나타났던 격렬한 반응과 같은 일이 다시 일어나서는 안 되니까요.

참고 비틀즈가 팬들에게 에워싸이는 비디오나 존, 폴, 조지, 링고가 나타나자 울면서 까무러치는 소녀들의 사진을 본 적이 있습니까?저희가 새 칼럼을 게시할 때마다 그와 비슷한 일이 발생하곤 합니다.

예, 예, 조금 과장된 비유라는 점은 인정하죠.하지만 남자든, 여자든, 많은 사람들이 저희 칼럼을 읽으면서 감동의 눈물을 흘리는 건 분명합니다.

아무튼 BCD 공급자를 사용하여 컴퓨터에서 현재 사용 중인 OS를 확인하는 그림 1의 스크립트를 눈여겨보십시오.이 스크립트는 관리자 권한으로 실행하지 않으면 실패한다는 사실을 명심하십시오.

그림 1 현재 운영 체제 가져오기

Const BcdLibraryString_Description = &h12000004
Const Current = "{fa926493-6f1c-4193-a414-58f0b2456d1e}"

strComputer = "."

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
 strComputer & "\root\wmi:BcdStore")

objStoreClass.OpenStore "", objStore
objStore.OpenObject Current, objDefault

objDefault.GetElement BcdLibraryString_Description, objElement
Wscript.Echo "Current operating system: " & objElement.String

그렇다고 관리자 권한이 있는 계정으로 로그온해야 한다는 뜻은 아닙니다.시작 메뉴에서 명령 프롬프트를 마우스 오른쪽 단추로 클릭하여 명령 프롬프트 창을 열고 관리자 권한으로 실행을 선택해야 합니다.그러면 명령 프롬프트에서 이 스크립트를 실행할 수 있습니다.

이제 이 스크립트가 어떻게 작동하는지 살펴보겠습니다.사실 스크립트 작동 방식을 쉽게 설명할 수 있을지 걱정이 되지만최대한 노력해보겠습니다. (잠시 흥분을 가라앉히고 좀 따분한 이야기를 해야 할 것 같군요.)

먼저BcdLibraryString_Description과 Current라는 상수를 정의합니다.BcdLibraryString_Description은 검색할 개체를 나타냅니다. 이 예에서는 현재 운영 체제의 Description(이름)이 들어 있는 개체입니다.

여기서 BCD 공급자를 사용하는 것의 진가가 발휘됩니다.일반적으로 속성의 값은 단순히 검색하면 되는 것이 아니라, 이러한 상수 값 중 하나와 GetElement 메서드를 사용하여 다른 개체를 검색한 다음 해당 개체에 속한 속성의 값을 출력해야 합니다.물론 다소 복잡한 면이 있지만,여행의 즐거움 중 절반은 목적지까지 가는 과정에 있다는 말도 있지 않습니까?

참고 흠, 이 속담을 들을 때마다 "대체 어디를 가길래?"라는 생각이 들지 않습니까?

Current 상수는 현재 사용 중인 운영 체제를 나타내는 GUID에 불과합니다.아래의 값은

 {fa926493-6f1c-4193-a414-58f0b-2456d1e} 

"잘 알려진" GUID로 간주됩니다. (이런 걸 보면 Microsoft에서 일하는 사람들도 유머 감각이 꽤 있는 것 같습니다.)

이 값이 잘 알려진 GUID이기는 하지만 일단 이 값을 포함하도록 하겠습니다. 다음과 같이 비슷한 두 값이 나타나면 어떤 것이 맞는지 혼동하는 독자도 있을 것이기 때문이지요.

{fa926493-6f1c-4193-a414-58f0b2456d1e} 
{fa926493-6f1c-4193-a414-58f0b2456d1f}

참고 혹시 궁금해하는 독자를 위해 덧붙이자면, GUID는 "gwid(그위드)" 또는 "goo-id(구-아이디)"로 읽을 수 있습니다.또한 세 번째 숫자 그룹이 4로 시작하므로 위의 GUID는 V1 GUID입니다.이외에도 설명할 내용이 많지만 기사를 최대한 자중해서 쓰기로 약속했기 때문에이 정도로 하겠습니다.

이미 파악한 독자도 있겠지만 BCD 공급자를 사용하여 작업을 수행할 때는 상수, 16진수 값 및 GUID를 꽤 자주 사용하게 됩니다.이번 달 칼럼에서 이러한 항목을 모두 다룰 수는 없지만 앞서 언급한 MSDN®의 BCD 페이지(go.microsoft.com/fwlink/?LinkId=116953)에서 자세한 내용을 확인할 수 있습니다.그 흥미진진한 내용이 주는 흥분을 이겨낼 수 있다면 말입니다.

2개의 상수를 정의한 후에는 로컬 컴퓨터에서 WMI 서비스에 연결합니다.이 스크립트를 사용하여 원격 컴퓨터의 부팅 구성 데이터를 검색할 수 있을까요?물론이죠.

사실, 원격 컴퓨터의 부팅 구성 데이터를 검색할 수 없다면 이 BCD 스크립트는 효용성이 낮다고 할 수 있겠지요.원격 컴퓨터(Windows Vista 또는 Windows Server 2008을 실행하는 원격 컴퓨터의 경우)에서 부팅 구성 데이터를 검색하기 위해서는 strComputer라는 변수에 해당 컴퓨터의 이름을 할당하기만 하면 됩니다.

strComputer = "atl-fs-001"

WMI 연결 문자열에서도 몇 가지 중요한 사항을 살펴볼 필요가 있습니다.첫째로, 연결 문자열에 백업 및 복원 권한이 포함되어 있는 것을 알 수 있습니다. {(Backup,Restore)}가 바로 이러한 역할을 합니다.이것이 중요하냐고요?스크립트가 제대로 작동하기를 바란다면 매우 중요하죠.이 두 권한을 명시적으로 포함하지 않으면 스크립트가 실패합니다.

둘째로, 시스템 관리 스크립트에 가장 많이 사용되는 네임스페이스인 root\cimv2 네임스페이스에 연결하지 않은 것을 알 수 있습니다.그 대신 root\WMI 네임스페이스에 연결하고 BCDStore 클래스에 직접 바인딩합니다.다음 코드에서 이 작업을 합니다.

"\root\wmi:BcdStore" 

정말로 흥미로운 부분은지금부터입니다.

한두 가지 예외는 있겠지만 여러분이 작성하는 BCD 스크립트는 대부분상수를 정의하고 WMI 서비스에 연결한 다음 BCD 저장소를 여는 세 단계로 시작됩니다.위에서 이미 1단계와 2단계는 완료했고, 3단계를 처리하는 코드는 다음과 같습니다.

objStoreClass.OpenStore "", objStore

여기서는 모든 부팅 구성 정보가 저장되는 운영 체제 엔터티인 BCD 저장소를 엽니다.저장소를 열려면 OpenStore 메서드를 호출하여 이 메서드에 다음 두 가지 매개 변수만 전달하면 됩니다.

  • 빈 문자열("").스크립트에 기본 저장소를 열 것임을 알리는 역할을 합니다.
  • objStore.스크립트에 제공하는 "출력" 매개 변수입니다.메서드에 변수 이름을 제공하면 메서드는 이에 대한 응답으로 해당 변수 이름을 개체 참조로 사용하는 개체(이 예의 경우 BCD 저장소를 나타내는 개체)를 반환합니다.

저장소가 열리면 OpenObject 메서드를 사용하여 다른 개체(objDefault 출력 매개 변수에 저장되어 있음)를 검색할 수 있습니다.

objStore.OpenObject Current, objDefault

이 새 개체의 정체는 무엇일까요?그렇습니다.바로 현재 사용 중인 운영 체제입니다.OpenObject에 현재 운영 체제를 나타내는 잘 알려진 GUID인 Current 상수를 전달했으므로 이것을 알 수 있는 것입니다.

자, 이제 컴퓨터에서 현재 사용 중인 운영 체제는 알게 되었습니다.정확히 말하면 거의 알게 된 거죠.해당 정보를 가져오기 위해서는 GetElement를 사용하여 해당 운영 체제의 Description을 나타내는 개체를 검색해야 합니다.

objDefault.GetElement _
  BcdLibraryString_Description, objElement

자, 이제부터 너무 흥분해서 격렬하게 반응하는 일은 없을 거라고 약속할 수 있습니까?그렇다면이제 String 속성의 값을 출력하여 컴퓨터에서 현재 사용 중인 운영 체제를 확인할 수 있다는 사실을 알려드려도 되겠군요.

Wscript.Echo "Current operating system: " _
  & objElement.String

진정하시고조금 전 했던 약속을 생각하여너무 흥분하지는 마십시오.흥분을 가라앉히기 힘들다는 것은 잘 알고 있습니다.다만 최대한 마음을 가라앉히도록 해보십시오.숨을 한번 깊이 들이쉬십시오. 저희도 BCD 스크립트를 작성하다가 너무 흥분되면 그렇게 한답니다.

앞서 설명했듯이 단지 컴퓨터에서 사용 중인 운영 체제를 확인하기 위한 것치고는 작업이 너무 복잡합니다. 같은 작업을 보다 쉽게 수행할 수 있는 방법도 많습니다.그러나 BCD 스크립트의 작동 방식을 이해하는 데는 도움이 되었으리라 생각합니다. BCD 스크립트의 작동 방식만 이해하면 이전에는 스크립트 작성자가 생각도 못했던 여러 가지 기능을 구현할 수 있습니다.(부디 진정하시길...)예를 들어 멀티부팅 컴퓨터에서 특정 운영 체제에 항상 "기본"으로 태그를 지정할 수 있습니다. 이 경우 컴퓨터가 다시 부팅될 때 누군가가 다르게 지정하지 않는다면 컴퓨터가 자동으로 해당 기본 운영 체제를 로드합니다.Windows Vista와 BCD 공급자가 개발되기 이전에는 스크립터가 컴퓨터에서 기본 운영 체제를 확인할 방법이 없었습니다.그러나 이제는 그림 2와 같은 스크립트만 실행하면 간단히 확인할 수 있습니다.

그림 2 기본 운영 체제 확인

Const BcdLibraryString_Description = &h12000004
Const BootMgrId = "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
Const DefaultType = &h23000003

strComputer = "." 

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
    strComputer & "\root\wmi:BcdStore")
objStoreClass.OpenStore "", objStore

objStore.OpenObject BootMgrId, objBootMgr 

objBootMgr.GetElement DefaultType, objDefaultOSIdentifier
objStore.OpenObject objDefaultOSIdentifier.Id, objDefault

objDefault.GetElement BcdLibraryString_Description, objElement 
WScript.Echo "Default operating system: " & objElement.String

어떻습니까?또 흥분되지 않습니까?하지만 흥분을 조금 자제해 주시기 바랍니다.이 스크립트를 자세히 설명하지는 않겠습니다. 위의 10~12개 단락을 제대로 읽었다면 개념은 충분히 이해할 수 있을 것입니다.단, 기본 운영 체제까지 도달하려면OpenObject 메서드를 사용하여 부팅 관리자 개체의 인스턴스를 여는 중간 단계가 필요합니다.부팅 관리자를 연 후에는 DefaultType 상수를 사용하여 기본 운영 체제를 나타내는 개체를 검색할 수 있습니다.

지금부터가 더 흥미롭습니다.이제 현재 운영 체제와 기본 운영 체제를 확인할 수 있습니다.하지만 정말 멋진 것은컴퓨터에 설치된 모든 운영 체제의 목록을 검색할 수 있다는 사실입니다.이제는 정말 흥분되는 수준이죠.자, 마음을 가다듬고 그림 3을 눈여겨보십시오.

이 스크립트는 어떤 역할을 하는 것일까요?먼저 2개의 새 상수를 정의합니다.그 중 WindowsImages는 BCD를 지원하는 모든 OS(Windows Vista 및 Windows Server 2008)의 인스턴스를 검색할 수 있도록 하고 LegacyImages는 컴퓨터의 "레거시" 운영 체제 인스턴스를 검색할 수 있도록 합니다.BCD 저장소에 연결한 후에는 EnumerateObjects 메서드를 사용하여 컴퓨터에 설치된 BCD 지원 운영 체제의 모든 인스턴스를 검색할 수 있습니다.

objStore.EnumerateObjects _
  WindowsImages, colObjects 

그림 3 컴퓨터의 모든 운영 체제 찾기

Const BcdLibraryString_Description = &h12000004
Const WindowsImages = &h10200003
Const LegacyImages = &h10300006

strComputer = "."

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
 strComputer & "\root\wmi:BcdStore")

objStoreClass.OpenStore "", objStore 

objStore.EnumerateObjects WindowsImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement BcdLibraryString_Description, objElement 
 Wscript.Echo objElement.String
Next
Wscript.Echo

objStore.EnumerateObjects LegacyImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement BcdLibraryString_Description, objElement 
 Wscript.Echo objElement.String
Next

EnumerateObjects 메서드의 작업이 끝나면 해당 컬렉션의 모든 운영 체제에 대해 반복하는 For Each 루프를 설정합니다.이 루프 내에서는 두 줄의 코드를 사용하여 운영 체제 Description을 검색하여 표시합니다.

objObject.GetElement _
  BcdLibraryString_Description, objElement 
Wscript.Echo objElement.String

그런 다음 컴퓨터에 설치된 모든 레거시 운영 체제에 대해 프로세스를 반복합니다.

objStore.EnumerateObjects _
  LegacyImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement _
  BcdLibraryString_Description, objElement 
 Wscript.Echo objElement.String
Next

참고 흥분되는 마음은 이해가 되지만 너무 심하게 흥분하면 인체에 해가 되므로 BCD 스크립트를 실행할 때는 주의를 기울여야 합니다.임산부나 임신할 가능성이 있는 여성, 전혀 임신 계획이 없는 여성, 예전에 임신했던 여성 또는 남성이라도 반드시 의사와 상담한 후에 BCD 스크립트를 실행하시기 바랍니다.

의사와 먼저 상담해야 한다는 말은 좀 과장된 부분이 있지만,의사에게 BCD 스크립트 실행에 대해서 문의하면 뭐라고 말할지 궁금하지 않습니까?

자, 이제 정말 말도 안 될 정도로 놀라운 작업을 시도해 보겠습니다. 기본 운영 체제를 변경할 수 있을지 한번 해보는 겁니다.예를 들어 Windows Vista와 Windows Server 2008을 모두 실행하는 이중 부팅 컴퓨터가 있다고 가정합니다.그리고 Windows Vista를 기본 운영 체제로 설정하려고 합니다.어떻게 해야 할까요?그림 4를 한번 보십시오.이 스크립트는 이 작업을 수행하는 한 가지 방법을 보여 줍니다.

그림 4 기본 운영 체제 변경

Const BootMgrId = "{9dea862c-5cdd-4e70-accl-f32b344d4795}"
Const BcdLibraryString_Description = &h12000004
Const DefaultType = &h23000003
Const WindowsImages = &h10200003

strComputer = "."

Set objStoreClass = GetObject("winmgmts:{(Backup,Restore)}\\" & _
 strComputer & "\root\wmi:BcdStore")

objStoreClass.OpenStore "", objStore 
objStore.EnumerateObjects WindowsImages, colObjects 

For Each objObject in colObjects
 objObject.GetElement BcdLibraryString_Description, objElement 
 If Instr(objElement.String, "Vista") Then
  objStore.OpenObject BootMgrId, objBootMgr 
  objBootMgr.SetObjectElement DefaultType, objObject.ID 
 End If
Next

이 스크립트에서는 다시 한 번 BCD 저장소를 연 다음 EnumerateObjects 개체를 사용하여 컴퓨터에 설치된 모든 BCD 인식 운영 체제의 컬렉션을 검색합니다.그리고 각 운영 체제의 Description을 검색하기 위해 이제 친숙하게 느껴지는 다음 코드 줄을 사용하여 컬렉션의 모든 항목에 대해 반복하는 For Each 루프를 설정합니다.

objObject.GetElement _
  BcdLibraryString_Description, objElement

지정된 운영 체제의 Description이 검색되면 InStr 함수를 사용하여 해당 값에 Vista라는 단어가 있는지 확인합니다.

If Instr(objElement.String, "Vista") Then

맞습니다. 다소 번거로운 감이 있죠.이보다는 컴퓨터의 모든 운영 체제를 열거하고 루프를 실행할 필요 없이 Windows Vista의 GUID를 사용하여 해당 운영 체제를 바로 여는 것이 낫습니다.

아쉽게도 이 방법을 사용하려면 Windows Vista의 GUID를 알아야 합니다.그 대신 이 방법을 사용하면 다른 정보는 필요가 없습니다. (Scripting Guy에게는 좋은 보너스죠.) 이름에 Vista라는 단어가 있는 운영 체제를 찾을 때까지 검색하기만 하면 됩니다.

참고 컴퓨터에 Windows Vista의 인스턴스가 여러 개 설치되어 있으면 어떻게 될까요?이 경우 Vista Ultimate나 Vista Enterprise 같은 문자열을 검색해야 할 수 있습니다.

Windows Vista를 찾으면 다음 두 줄의 코드를 사용하여 Windows 부팅 관리자를 연 다음 기본 운영 체제를 Windows Vista로 설정합니다.

objStore.OpenObject BootMgrId, objBootMgr 
objBootMgr.SetObjectElement _
  DefaultType, objObject.ID 

이번 달에 준비한 내용은 여기까지입니다. Scripting Guy도 일주일 내내 극도의 흥분 상태를 견디어 낼 수는 없으니 이정도만 하겠습니다.하지만 걱정하지 마십시오. 다음 달에 흥미로운 다른 Hey, Scripting Guy! 칼럼으로 다시 찾아뵙겠습니다.그때까지 마음을 좀 진정시켜 두시기 바랍니다.

Dr. Scripto의 Scripting Perplexer

매달 퍼즐 풀이 실력뿐만 아니라 스크립팅 능력까지 시험해 볼 수 있는 문제입니다.

2008년 7월:VBScript 정사각형

예, 제목과는 달리 정사각형이 아니라 직사각형입니다. 하지만 그건 별로 중요하지 않습니다.이 퍼즐을 풀려면 오른쪽에 있는 사각형을 왼쪽에 있는 빈 사각형에 맞추어 VBScript 함수의 이름을 만들어야 합니다.각 사각형은 한 번씩만 사용할 수 있습니다.다음은 퍼즐 풀이 예제입니다.

이 예제를 올바르게 풀려면 OU 사각형(직사각형)을 첫 단어의 빈 사각형으로 이동하고 MS와 OX를 두 번째 단어의 빈 사각형으로 이동해야 합니다.그러면 다음과 같이 VBScript 함수 UBound와 MsgBox라는 함수 이름이 됩니다.

이제 퍼즐을 풀어보십시오.

답:

Dr. Scripto의 Scripting Perplexer

답:VBScript 정사각형, 2008년 7월

Scripting Guy는 Microsoft에서 고용되어 일하고 있는 Microsoft의 직원들입니다.이들은 좋아하는 야구 경기와 기타 여러 활동을 하는 시간을 제외하고는 항상 TechNet 스크립트 센터를 운영합니다.자세한 내용은 www.scriptingguys.com에서 확인하십시오.

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