Hey, Scripting Guy!Scripting Guys의 OU에 대한 고찰 - 5센트를 위하여!

Microsoft Scripting Guys

이 기사의 코드 다운로드: HeyScriptingGuy2007_03.exe (151KB)

Q: Active Directory에서 OU를 선택할 수 있도록 하는 대화 상자를 표시하려면 어떻게 해야 합니까?

여러분에게 문의를 받을 때마다 Scripting Guys가 5센트씩 받았다면... 흠, 뭐 그래도 37.15달러밖에 안 되겠군요. 하지만 질문을 하려고 마음먹었다가 실행에 옮기지 않은 모든 사람에게서 5센트씩 받았다면 얘기가 달라지겠죠? 뭐, 그래도 우리가 돈을 목적으로 Scripting Guys가 된 것은 아니니까요. 우리는 사람들이 시스템 관리 작업을 쉽고 빠르게 수행할 수 있도록 돕는 데서 오는 만족감을 느끼고자 Scripting Guys가 된 것입니다.

참고: 사실 어쨌든 처음에는 돈을 벌기 위해 Scripting Guys가 되었어요. 그렇지만 우리의 직속 상관으로부터 "잘만하면 큰 돈을 벌 수도 있지만, 그러려면 중노동을 각오하고 정말로 높은 품질의 결과물을 만들어 내야 해"라는 이야기를 들은 다음부터 우리 Scripting Guys는 돈이 전부가 아니라는 생각을 하게 되었습니다.

어쨌든 중요한 사실은, 많은 사용자들이 OU를 선택할 수 있는 대화 상자를 표시한 다음 스크립트를 사용하여 해당 OU에 연결할 수 있는 방법을 알고자 한다는 것입니다. 최근 한 독자로부터 "폴더를 선택할 수 있는 대화 상자 표시 방법에 대한 기사를 봤습니다. 또한 파일을 선택하는 대화 상자 표시 방법을 설명한 기사도 봤습니다. 그런데 왜 Active Directory®에서 OU를 선택할 수 있는 대화 상자 표시 방법에 대해서는 다루지 않는 겁니까?"라는 내용의 문의 메일을 받았습니다.

맞습니다. 폴더를 선택할 수 있는 대화 상자 표시 방법부터 연재를 시작했으며, 여기에서 예를 보실 수 있습니다. 또한 파일을 선택할 수 있는 대화 상자를 표시하는 방법도 설명되어 있습니다. 아직 해당 기사를 보지 못했다면 microsoft.com/technet/scriptcenter/resources/qanda/jan05/hey0128.mspx에서 확인하시기 바랍니다. 두 기사 모두 많은 독자들이 참조했으며 기사에서 제시된 방법을 스크립트에 적용한 사용자도 많습니다. 그렇다면 우리가 Active Directory에서 OU를 선택하는 대화 상자 표시 방법에 대해서 다루지 않은 이유는 무엇일까요? Microsoft가 꾸민 모종의 음모일까요?

물론 아닙니다. (잠깐. 혹시 필자가 Microsoft에 몸담고 있기 때문에 진실을 은폐하려 한다고 생각하는 사람은 없겠죠?) 사실 Active Directory에서 OU를 선택하는 대화 상자 표시 방법에 대해 다루지 않은 데는 그만한 이유가 있습니다. 바로 그런 대화 상자는 없기 때문입니다. 야구로 치자면 보이지 않는 공을 칠 수는 없는 노릇이니까요. 그리고 스크립팅으로 말하자면 존재하지 않는 것을 표시할 수는 없습니다.

자, 이번 호에서는 더 이상 설명할 내용이 없는 것 같군요. 그럼 다음 호에서 뵙겠습니다.

허나 제게 그런 행운이 있을 리 없죠! TechNet Magazine 편집자에 따르면 이번 달 칼럼에서는 다른 내용을 다룬다고 합니다. "그런 대화 상자가 없다고 그냥 끝낼 수는 없지 않느냐? Scripting Guys라면 해당 기능을 제공하는 대화 상자를 새로 만들어 내야 하지 않겠나? 스크립팅에 관해서는 못하는 게 없는 사람들 아니냐?"고 말하면서 말이지요.

당연한 얘기지만 TechNet Magazine 편집자들이 우리에 대해 완전히 오해하고 있는 것 같습니다. 스크립팅에 관해서는 못하는 것이 없다고요? 그렇지 않습니다. 사실 Scripting Guys는 스크립팅에 대한 것밖에 할 줄 모르는 사람들입니다.

그나마 다행스러운 건 Active Directory에서 OU를 선택할 수 있는 대화 상자를 만드는 것 역시 우리가 할 수 있는 일 중 하나라는 점입니다. 그림 1을 살펴보시기 바랍니다.

예, 정말 긴 스크립트입니다. 하지만 여러 개의 달걀을 깨지 않고는 오믈렛을 만들 수 없습니다. 마찬가지로 사용자 지정 대화 상자를 만들 때도 달걀을 여러 개 깨야 합니다. (이 칼럼을 반쯤 작성했을 때쯤 배가 고파서 간식을 먹어야 했으니까요.) 이제 배도 채웠으니 설명을 시작하도록 하겠습니다.

지금부터 수행하려는 스크립팅 작업은 Internet Explorer® 개체 모델을 사용하여 의사 대화 상자를 만드는 것입니다. Internet Explorer 인스턴스를 만들고 Active Directory에서 OU의 컬렉션을 가져온 다음 해당 OU를 Internet Explorer 창의 목록 상자에 표시해 보겠습니다. 그리고 사용자가 OU를 선택할 때까지 기다린 다음 선택한 항목의 ADsPath를 가져오고 "대화 상자"를 닫은 후 작업을 계속 진행합니다.

참고: 이 대화 상자가 이제껏 만들었던 대화 상자 중에서 가장 멋지고 기발한 대화 상자가 될 수 있을까요? 맞습니다. "가장 멋지고 기발하다"는 것이 확인 또는 취소 단추도 없는 단순한 대화 상자를 의미하는 것이라면 말입니다. 하지만 변명을 하자면 여기서는 기본적인 골자만 제공하는 것이 목적이므로 대화 상자를 꾸미고 수정하는 작업은 직접 해 보시기 바랍니다.

(우리가 "죄송합니다. 직접 하셔야 합니다."라고 말할 때마다 5센트씩 받았다면 아마 부자가 되었을 겁니다. 뭐, 기부금을 주시겠다면 The Scripting Guys c/o TechNet Magazine으로 보내 주셔도 됩니다.)

한정된 지면에 맞추어 방법을 설명해야 하므로 몇 가지 사항은 생략하도록 하겠습니다. 예를 들어 다음 코드 블록에 대해서는 350x400 픽셀의 Internet Explorer의 인스턴스를 만들고 그 과정에서 주소 표시줄과 상태 표시줄을 숨긴다는 정보만 설명합니다.

Set objExplorer = CreateObject( _
    "InternetExplorer.Application")

objExplorer.Navigate "about:blank"   
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width= 350
objExplorer.Height = 400 
objExplorer.Left = 400
objExplorer.Top = 400
objExplorer.Visible = 1             

물론 이 코드는 빈 Internet Explorer 창을 제공하는 역할을 할 뿐입니다. 도메인에 있는 OU 목록을 가져오려면 Active Directory를 검색해야 합니다. 이 칼럼에서는 Active Directory 검색에 대해 자세히 설명할 수 없으므로 Script Center(microsoft.com/technet/scriptcenter/resources/tales/sg0405.mspx)에서 2부로 구성된 연재 기사를 참조하시기 바랍니다. 여기에서는 fabrikam.com 도메인에 있는 각 OU의 Name 및 ADsPath를 검색하는 데 사용되는 다음 코드만 소개하겠습니다.

objCommand.CommandText = _
    "SELECT Name, ADsPath FROM 'LDAP://DC=fabrikam,DC=com' WHERE objectCategory=
    'organizationalUnit' ORDER BY Name"

그리고 독자 여러분의 이해를 돕기 위해 OU를 이름에 따라 사전순으로 정렬했습니다. ORDER BY Name 절을 사용하여 이러한 작업을 수행할 수 있습니다. 이쯤이야 식은 죽 먹기죠. 여러분을 돕는 것이 우리의 임무이니까요.

Execute 메서드를 호출하면 fabrikam.com에 있는 모든 OU로 구성된 레코드 집합이 반환됩니다. 따라서 다음 단계로 각각의 해당 OU를 목록 상자에 표시해야 합니다.

그러기 위해선 어떻게 해야 할까요? 먼저 메모리에 전체 목록 상자를 구성해야 합니다. 맨 먼저 다음 코드 줄을 사용하여 strHTML이라는 변수에 <SELECT> 태그를 저장합니다.

strHTML = "<select size = '20' name='OUList' style='width:300px'>"

이 코드 줄은 어떤 역할을 할까요? 표준 HTML 목록 상자를 만드는 것(<SELECT> 태그를 사용한 작업)뿐입니다. 그 과정에서 목록 상자의 Name을 OUList로 지정하고 300픽셀(300px) 너비로 한 번에 20개의 항목을 표시하도록 구성했습니다. HTML에 대한 지식이 조금이라도 있다면 위의 코드를 쉽게 이해할 수 있을 것입니다.

다음으로 목록 상자에 항목(OU)을 추가해야 합니다. 신기하게도 우리가 사용할 레코드 집합은 도메인의 각 OU에 대한 정보로 구성되어 있습니다. 따라서 전체 레코드 집합에 대해 반복 실행되는 Do Until 루프를 설정하여 정보를 가져온 다음 목록 상자에 각 OU를 추가할 수 있습니다. 이 루프에서는 다음 코드(목록 상자에 항목을 추가하는 표준 HTML)를 사용하여 각 OU를 추가하고 목록에 OU Name이 표시될 수 있도록 하며, 목록 상자에서 해당 OU를 클릭할 경우 ADsPath가 스크립트로 전달되도록 항목을 구성합니다.

strHTML = strHTML & "<option value= " & _
    Chr(34) & objRecordSet.Fields
    ("AdsPath").Value & Chr(34)
strHTML = strHTML & ">" & objRecordSet.
    Fields("Name").Value

ADsPath를 스크립트로 전달하는 이유는 무엇일까요? 간단합니다. OU Name을 대신 전달한다고 가정해 봅시다. Name이 Finance라면 해당 OU를 바인딩하기가 어렵게 됩니다. "Finance"라는 이름 자체는 유효한 ADSI 바인딩 문자열이 아니기 때문입니다. 그러나 ADsPath(LDAP://ou=Finance,dc=fabrikam,dc=com)를 사용하면 간단히 바인딩할 수 있습니다. 때문에 ADsPath를 찾아 Active Directory의 개체에 연결해야 하는 것입니다.

여기서는 OU의 이름이 고유하다는 가정하에 목록 상자에 Name을 표시하고 있습니다. 그러나 North America\Research 및 Europe\Research와 같이 OU의 이름(Research)이 같다면 이렇게 할 수 없습니다. OU의 이름이 중복되는 경우에는 목록 상자에 ADsPath나 distinguishedName과 같은 다른 속성을 대신 사용해야 합니다. 이는 여러분이 직접 결정해야 할 사항 중 하나입니다. (또 5센트를 받을 수 있겠군요!)

어쨌든 메모리에 목록 상자를 만드는 작업을 계속하도록 하겠습니다. 이 상자에 추가한 각 항목은 strHTML 변수에 추가됩니다. 이것이 바로 우리 계획의 핵심입니다. 즉, 목록 상자의 전체 코드를 strHTML 변수에 저장한 다음 해당 변수의 값을 사용하여 실제로 목록 상자를 Internet Explorer 인스턴스에 추가하는 것입니다.

OU를 모두 추가한 후에는 아래의 코드 줄을 사용하여 목록 상자의 끝을 표시합니다.

strHTML = strHTML & "</select>"

이때 strHTML에는 목록 상자를 만드는 데 필요한 모든 HTML 태그가 들어 있게 됩니다. 그리고 해당 목록 상자의 각 항목은 Active Directory의 OU를 나타냅니다. 따라서 이제 strHTML 값을 Internet Explorer 문서의 InnerHTML 속성에 할당할 수 있습니다.

objExplorer.Document.Body.InnerHTML = strHTML

결과적으로 도메인의 모든 OU를 표시하는 목록 상자가 만들어집니다.

하지만 이것으로 끝이 아닙니다. 예를 들어 사용자가 대화 상자에서 OU를 선택할 때까지 스크립트를 일시 중지하는 코드가 필요합니다. 이러한 코드가 없으면 목록 상자는 표시되겠지만 사용자가 OU를 선택했는지에 관계없이 스크립트가 계속 실행됩니다. 이와 같은 문제가 생기지 않도록 하기 위해 다음 코드 블록을 사용합니다.

Do While objExplorer.Document.Body.All.OUList.Value = ""
    Wscript.Sleep 300
Loop

이 코드 블록은 반복적으로 목록 상자(앞서 설명했듯이 OUList로 이름을 지정한 목록 상자)의 Value를 확인합니다. Value가 빈 문자열(선택된 항목이 없는 경우)이면 스크립트를 300밀리초 동안 일시 중지하고 루프를 실행한 후 다시 확인합니다. 이러한 프로세스는 a) 영원히, b) 사용자가 목록 상자에서 항목을 선택할 때까지, 또는 c) 사용자가 Internet Explorer를 닫을 때까지 계속됩니다.

사용자가 목록 상자에서 OU를 선택했다고 가정해 봅시다. 이 경우 Value(OU의 ADsPath)를 가져와 strTargetOU라는 변수에 할당합니다.

strTargetOU = objExplorer.Document.Body.All.OUList.Value

그런 다음 아래와 같이 Quit 메서드를 사용하여 Internet Explorer 인스턴스를 종료합니다.

objExplorer.Quit

이제 거의 끝났습니다. 먼저 strTargetOU가 빈 문자열인지 확인합니다.

If strTargetOU = "" Then
    Wscript.Quit
End If

빈 문자열인 경우 사용자가 OU를 선택하지 않고 Internet Explorer를 닫은 것이므로 Wscript.Quit 메서드를 사용하여 스크립트를 종료합니다. (사용자가 OU를 선택하지 않으면 스크립트를 실행할 의도가 없는 것으로 가정하는 것입니다.) 그러나 strTargetOU가 빈 문자열이 아니면 변수의 값을 출력합니다.

Wscript.Echo strTargetOU

물론 실제로 스크립트를 작성할 때는 단순히 ADsPath를 출력하는 데 그치지 않고 Active Directory의 해당 OU에 바인딩하게 될 것입니다. 그러나 항상 말하듯이 그 과정은 여러분의 몫으로 남겨 두겠습니다.

앞서 설명했듯이, 그리고 그림 2에서 볼 수 있듯이 화려한 대화 상자는 아니지만 잘 작동할 뿐만 아니라 ADsPath를 직접 입력하는 것(ADsPath를 알고 있다는 가정하에)보다 훨씬 간단합니다. 또한 코드와 대화 상자를 필요에 따라 알맞게 사용자 지정할 수도 있습니다.

Figure 2 A simple script dialog

Figure 2** A simple script dialog **

자, 이제 Active Directory에서 OU를 선택하는 대화 상자를 표시하는 방법에 대한 칼럼도 썼으니 5센트어치의 값은 한 셈이라고 생각합니다. 결국 TechNet Magazine에서 주는 임금에서 5센트가 늘게 되었군요.

뭐, 절대 불평하는 것은 아닙니다.

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

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