Scripting Guy 為您解答問題

Hey, Scripting Guy!

歡迎使用 TechNet 專欄,Microsoft Scripting Guy 會在此為您解答有關系統管理指令碼的常見問題。您有關於系統管理指令碼方面的問題嗎?請將電子郵件傳送到 scripter@microsoft.com。我們無法保證能夠逐一回答每個問題,不過我們會盡力而為。

資源

如何提示使用者輸入資訊,然後傳遞該項資訊給命令列工具?

Hey, Scripting Guy! Question

嗨,Scripting Guy!如何提示使用者輸入資訊,然後傳遞該項資訊給命令列工具?

        -- SD

Hey, Scripting Guy! Answer

SD,您好。efh;r9d/fjwf

抱歉,讓我們再試一次。j ewewrj 2gr CX # 2kkkkw

不好意思,撰寫本專欄的 Scripting Guy 今天不太能移動他的手臂。昨晚,Scripting 小子認為到體育館來回游泳 40 分鐘會比到體育館騎健身腳踏車 40 分鐘更「有趣」。

我們有沒有提過 Scripting 小子有多蠢?

附註:您說得沒錯:如果 Scripting 小子提議來回游泳兩趟 40 分鐘很蠢,為什麼 Scripting 老爹還會接受這項提議?別擔心,我們都知道這個問題的答案。讓事情更糟的原因在於 Scripting 老爹了解箇中秘辛。在他的高中時代,某位體育老師提議說,如果有人能在指定的時間內游完一英里,他就在當季給那位學生一個 A。撰寫本專欄的 Scripting Guy 能夠游完一英里,而且贏得一個 A。幾天之後,當他最後勉強用自由式游完時,他發誓再也不做這種蠢事。 往好的方面想,假設 Scripting 老爹發現自己在離海岸邊約一英里的船上,而且突然沈船。經過昨晚之後,Scripting 老爹就知道他能夠游回岸上,完全沒問題。 當然,前提是水裡面每隔約 50 碼就有牆壁,讓他能靠著休息。

當然,每個人心裡現在一定都在想:像這種無法移動手臂的小事真的會讓撰寫本專欄的 Scripting Guy 沒辦法撰寫他的專欄嗎?如果可以選擇的話,是的。但是,不用說,撰寫本專欄的 Scripting Guy 似乎完全沒得

Script Center
Set objShell = CreateObject("Wscript.Shell")

strName = InputBox("Please enter the user name:")

If strName = "" Then
    Wscript.Quit
End If

strCommand = "%comspec% /k dsquery user -name " & Chr(34) & strName & chr(34)
strCommand = strCommand & " | dsget user -tel"

objShell.Run strCommand

SD,根據您的電子郵件,表示您真正要做的是提示使用者輸入名稱,然後使用命令列工具 Dsquery 和 Dsget 來搜尋 Active Directory、找出含有該名稱的使用者,然後顯示他或她的電話號碼。為了讓每個人進入狀況,下面是 SD 所傳來的範例命令,其中含有代表使用者名稱的變數 x

dsquery user -name x | dsget user -tel

我們剛顯示給您看的指令碼是什麼意思?該則指令碼將會執行命令,以使用者所輸入的名稱取代變數 x

不,我們並沒有腦積水。呃,或許有點吧。聽著,如果我們解釋一下該指令碼的運作方式應該會有點幫助。如您所見,我們一開始要先建立 Wscript.Shell 物件的執行個體 (呼叫命令列工具時使用該物件)。然後,我們會使用下列這行程式碼來顯示 InputBox、請求輸入使用者名稱,然後將該名稱儲存於名為 strName 的變數中:

strName = InputBox("Please enter the user name:")

下一個步驟是選擇性的,但似乎是個好主意。如果您在 InputBox 中輸入名稱,然後按一下 [確定] (或按下 ENTER),該名稱將儲存 (在此範例中) 於變數 strName 中。但是,如果您改為按一下 [取消] 按鈕,將會發生什麼事?在此情況下,空字串值 (“”) 就會儲存於 strName 中。除此之外,如果您按一下 [取消],可能就表示您想要取消指令碼(沒錯,我們的 Scripting Guy 確實相當聰明吧)。因此,我們插入這個程式碼區塊,以便判斷 strName 是否包含空字串。如果它包含空字串,我們就要呼叫 Quit 方法並終止指令碼:

If strName = "" Then
    Wscript.Quit
End If

嘿嘿,這就是我們拿大筆薪水的原因了。

我們現在可以準備撰寫命令列字串 (是的,通常最簡單的方式是撰寫命令列字串、將它儲存在變數中,然後執行命令)。雖然這種做法不太困難,但是仍有一些地方需要注意:

  • 只有執行這兩個命令列工具仍不夠好:雖然這些工具會執行,但是輸出的捲動速度過快而難以讀取。因此,我們必須改成開啟新的命令視窗、執行這些工具,然後確定這些工具執行完成時命令視窗保持在開啟狀態中。在我們的範例中,這就是 %comspec% /k 所做的工作 (%comspec% 會開啟命令視窗而 /k 會將視窗保持在開啟狀態中)。

  • 我們必須在命令中加入雙引號。不可否認,在字串變數中嵌入雙引號可能有點複雜。但是,我們將說明一種相當直接的方式來處理這項作業。

為了簡化程序,我們選擇使用兩個步驟,將命令列字串放在一起。下面是步驟 1:

strCommand = "%comspec% /k dsquery user -name " & Chr(34) & strName & chr(34)

這裡的動作是要做什麼呢?首先,我們要開啟新的視窗,並確定在 Dsquery 和 Dsget 執行完成之後視窗會維持開啟狀態 (同樣地,這就是 %comspec% /k 的任務)。然後,我們要發出基本的 Dsquery 命令:dsquery user -name。接著就是複雜的部分:指定使用者名稱,並確定該名稱括在雙引號中。

現在看一下指令碼時,感覺上其實沒有非常複雜對吧。注意,當我們加入 Dsquery 命令時,要在 -name 參數後面放一個空格 (輸入使用者名稱的現成位置)。這就是我們使用此一簡單語法所進行的作業:Chr(34) & strName & Chr(34)

這是什麼意思呢?基本上,初學者或許不太了解,Chr 函數會接受 ASCII 值並取代對應至該值的實際字元。結果,雙引號具有 34 的 ASCII 值,因此 Chr(34) 將會為我們插入雙引號。

之後,我們要插入變數 strName 以及第二個雙引號。假設您輸入 Ken Myer 當做使用者名稱,變數 strCommand 現在就會等於:

%comspec% /k dsquery user -name "Ken Myer"

怎樣,很簡單吧!

然後,我們要使用這行程式碼來加入後半段命令:

strCommand = strCommand & " | dsget user -tel"

我們在這裡所做的就是將 strCommand 的值設定為 strCommand 的目前值加上:| dsget user -tel。如此一來,就會讓 strCommand 等於:

%comspec% /k dsquery user -name "Ken Myer" | dsget user -tel

恰巧這就是讓 Dsquery 和 Dsget 擷取 Ken Myer 電話號碼所需的命令。

事實上,現在剩下的作業就是呼叫 Run 方法:

objShell.Run strCommand

我們應該強調一下,這則指令碼只會呼叫 Dsquery 和 Dsget,然後在命令視窗中顯示 Ken Myer 的電話號碼而已。那麼是否能夠抓取該電話號碼,然後用於指令碼中的其他位置呢?沒錯,您確實可以這樣做,但是必須進行一些額外的程式碼編寫作業 (而且要使用 Exec 方法來取代 Run 方法)。如需詳細資訊,請參閱《指令碼物語》專欄的 <從 WSH 指令碼執行程式 (英文)> (對於小典故有興趣的讀者,這剛好是 Script Center 發行的第一篇專欄)。

是的,這可能值錢。歡迎您提供贊助。

至於撰寫本專欄的 Scripting Guy,目前他能說的只有 dsfhg3e^t r4。

這次,這是他的真心話。