嗨,Scripting Guy!

嗨,Scripting Guy!

歡迎使

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

今天的問題:如何取得 Active Directory 中所有停用使用者帳戶的清單?


如何取得 Active Directory 中所有停用使用者帳戶的清單?

嗨,Scripting Guy!我要如何取得 Active Directory 中所有停用使用者帳戶的清單?

-- RT

RT,您好。先說好了,這是您自找的。我們是有個指令碼可以傳回 Active Directory 中停用使用者帳戶的清單,唯一的問題是部分指令碼有點艱澀 (這麼說還太輕描淡寫了),我們沒辦法在這個專欄中充分說明所有運作細節。如果您可以接受的話,我們就繼續討論下去。

唉,我在鬼扯什麼,請您繼續讀就是了。反正說不定可以從中學得什麼。

我們的問題在於,帳戶狀態 (啟用或停用) 是 userAccountControl 屬性的一部份,而這剛好是位元遮罩屬性的例子之一,所謂位元遮罩屬性,實際上是包含許多屬性值的單一屬性。事實上,下列所有屬性值都儲存在這個單一屬性中:

  • 使用者帳戶已停用。
  • 帳戶目前已鎖定。
  • 不需要密碼。
  • 使用者不能變更密碼。
  • 這是代表一般使用者的預設帳戶類型。
  • 設定後,此帳戶上的密碼將不會過期。
  • 設定後,這個旗標會強制使用者使用智慧卡登入。
  • 使用者密碼已經過期。

雖然位元遮罩屬性可能有點難懂,但是大多不難處理,除了需要搜尋 Active Directory 的例外情況,而我們現在正好需要搜尋 Active Directory。一般而言,您會使用如下的 SQL 查詢來搜尋 Active Directory:

Select Name from 'LDAP://dc=fabrikam,dc=com' Where Department = 'Finance'

多數的 Active Directory 屬性都可以這樣處理,但是對位元遮罩屬性就沒什麼效果,老實說,是根本行不通。因此,我們只好改採 B 計劃,使用 LDAP 查詢語法:

<LDAP://dc=fabrikam,dc=com>;(&(objectCategory=User)" & _
        "(userAccountControl:1.2.840.113556.1.4.803:=2));Name;Subtree

沒錯,我們知道,我們也不喜歡這樣。不過說真的,等到您逐漸瞭解各部分的含意後,就不會覺得有這麼糟了:

  • <LDAP://dc=fabrikam,dc=com>。這只是搜尋的起點:fabrikam.com 網域的根目錄。除了 ADsPath 外圍的角括弧以外,其餘部分您應該都很熟悉。
  • (&(objectCategory=User)。這是「Where」子句的一部份 (注意,實際上在查詢中並不會用到「Where」這個字)。objectCategory=User 部分應該蠻直接了當的,我們只對使用者物件感興趣。& 相當於 SQL 子句中的 AND 運算子。這只是表示我們要結合 objectCategory=User 和其他東西。
  • (userAccountControl:1.2.840.113556.1.4.803:=2))。這剛好是我們說的那個其他東西。聽起來好像胡說八道,但是它真的會告訴指令碼搜尋已啟用 userAccountControl 屬性中的位元 2 的物件 (此處指使用者)。位元遮罩屬性的討論到此為止,如需簡要說明,請參閱《Microsoft Windows 2000 Scripting Guide》中的<Reading User Account Password Attributes>(英文) 一節。目前我們只需要知道,如果啟用位元 2,則使用者帳戶便會停用

    1.2.840.1113556.1.4.803 又如何呢?這剛好是 LDAP 位元比對規則,等於是「布林值」AND 運算子 (我知,我知)。換言之,這個怪異的混合體基本上就等於:

If objUser.userAccountControl AND 2 Then

如果您熟悉位元遮罩,應該就能大致瞭解。假使不然,也不用太擔心,照樣可以使用這段指令碼,以後再慢慢瞭解。

  • Name。這只是我們希望傳回的屬性。
  • Subtree。這是我們的搜尋範圍,只是表示我們希望搜尋整個 Active Directory 樹狀目錄。

簡直就像泥漿一樣清楚,對吧?您可以閱讀 2005 年 4 月的 Tales from the Script(英文) 專欄,其中會提供搜尋 Active Directory 的簡介 (第二篇將於 2005 年 5 月推出,敬請期待)。如果您真的想要多瞭解如何搜尋 Active Directory (您應該這麼想,因為這是功能強大的工具),您也可以看看Scripting Guys 網路廣播(英文) 。

噢,對了,您可能還想看一下傳回 Active Directory 中所有停用使用者帳戶清單的完整指令碼。早說嘛!

On Error Resume Next
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.CommandText = _
    "<LDAP://dc=fabrikam,dc=com>;(&(objectCategory=User)" & _
        "(userAccountControl:1.2.840.113556.1.4.803:=2));Name;Subtree"  
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
Do Until objRecordSet.EOF
    Wscript.Echo objRecordSet.Fields("Name").Value
    objRecordSet.MoveNext
Loop

如需詳細資訊

查看嗨,Scripting Guy!- 過往文件

 

回到頁首 回到頁首