嗨,Scripting Guy!

嗨,Scripting Guy!

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

還有,別忘了瞧瞧全新經過改良的嗨,Scripting Guy!過往文件

今天的問題:如何監視處理序的活動,查看是否有任何人在使用?


如何監視處理序的活動等級?

嗨,Scripting Guy!如何監視處理序的活動,查看是否有任何人在使用?

-- AJ

AJ,您好。你知道嗎?難得有這麼一次,寫指令碼本身反而是解答中最容易的一部份。雖然有幾種不同方式來處理這個問題,我們選擇了定期檢查應用程式所使用處理器時間的累計總量。如果處理器時間總量從不改變,很可能就表示沒有人在使用該應用程式。

但如果那是解答中最容易的部份,那麼,困難的又是什麼?在這種情況下,困難的部份是在於決定:什麼算是 (或不算是)「未加以使用」?在我們的範例指令碼中,我們要測量累計的處理器使用時間 11 次,每次測量後,中間暫停 30 秒。指令碼結束時,我們會得到一組測量數字,測量時間前後共計 5 分鐘;我們是假設:如果在五分鐘之內,處理器時間一直沒有改變,就表示沒有人在使用該應用程式。這項假設對我們的範例指令碼來說很合適,但是在真實狀況下,可能不太適用。畢竟,假設您的使用者在講電話、休息喝咖啡,或者是在開會;在這些情況下,應用程式有 5 分鐘 (或者更長時間) 不在使用中,因而不會另外佔用處理器時間,就不足為奇。您必須自行決定,對您來說,多少時間才算合理。

我們也需要再說明一點,並沒有特別的理由一定要每隔 30 秒測量一次,我們主要只是想讓您在螢幕上看到累計的處理器時間,以便讓您確切地知道,指令碼仍在運作中。我們一樣也可以測量一次,等候五分鐘,然後再進行第二次測量。五分鐘時間也許好像不太長,但是如果等著看指令碼是否確實有所動靜,那簡直就像是永無止盡。同樣地,您也必須自行決定間隔時間是否合理。

是呀,我們知道,目前看來都沒問題,Scripting Guys,只是你們談了半天的指令碼,到底在哪裡啊?欸,就在這裡:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
For i = 1 to 11
    Set colProcesses = objWMIService.ExecQuery _
        ("Select * from Win32_Process Where Name = 'Notepad.exe'")
    For Each objProcess in colProcesses
        sngProcessTime = (CSng(objProcess.KernelModeTime) + _
                CSng(objProcess.UserModeTime)) / 10000000
        Wscript.Echo objProcess.Name, sngProcessTime
    Next
    Wscript.Sleep 30000
Next


注意:這個指令碼所監控的處理序是 Notepad.exe,並假定在您的電腦上只執行了一個 Notepad 執行個體,如果有 (或者可能有) 多個 Notepad 執行個體,則應該依處理序識別碼來進行監控,而不要用處理序名稱。


指令碼一開始先連接到本機電腦的 WMI 服務。然後將 For Next 迴圈設定為執行 11 次,我們計劃要進行的每個測量都執行一次。接著在迴圈之內,再以下面這行程式碼,傳回在這部電腦上執行且名稱為 Notepad.exe 之所有處理序的集合:

Set colProcesses = objWMIService.ExecQuery _
    ("Select * from Win32_Process Where Name = 'Notepad.exe'")


重要事項:請確定這行程式碼是包含在您的 For Next 迴圈「之內」,只有這樣才能確定,每次跑迴圈時,所擷取的都是最新處理序資訊。


結果顯示,WMI 是使用兩個不同的屬性來追蹤記錄處理器時間:KernelModeTime 和 UserModeTime。若要追蹤處理器總時間,則必須加入這兩個屬性的值。此外,WMI 是以 100 個十億分之一秒為單位來追蹤處理器時間。由於大多數人通常不會以 100 個十億分之一秒的時間來思考 (嗨,我們說的是大多數人),所以也將這兩個屬性的總和除以 10,000,000,將 100 個十億分之一秒轉換成秒。當然,這聽起來很複雜,但是只需一行程式碼就可以搞定:

sngProcessTime = (CSng(objProcess.KernelModeTime) + _
    CSng(objProcess.UserModeTime)) / 10000000

您若寧可以分鐘為單位來計算處理器時間,則請將總和改除以 600,000,000 (10000000 x 每分鐘 60 秒)。

我們回應處理序名稱和處理器時間總數,然後使用 Sleep 方法,讓指令碼暫停 30 秒 (30,000 毫秒)。經過 30 秒之後,我們就執行迴圈作業,重複整個程序。經過 11 次迴圈以後,指令碼即終止。

當我們執行指令碼時,便會取回如下所示的資訊:

notepad.exe 0.1602304
notepad.exe 0.801152
notepad.exe 0.801152
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664
notepad.exe 0.8111664

您可以看到,剛開始監控 Notepad 時,有極短暫的活動「波動」,但是最後 8 次測量時,Notepad 就完全沒有使用到任何處理器時間(而且整體來說,這個應用程式所使用的處理器時間也低於一秒鐘)。這樣是否表示沒有人在使用 Notepad?嗯,前面也已經說過,這完全要由您自行決定。畢竟我們是為 Microsoft 工作,而 Microsoft 沒有任何員工會在任何時候冒昧地指示您應該如何行動。(哦,幾乎是從來不會)。


如需詳細資訊

請參閱嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首