[.NET]透過WinNT的方式取得電腦中的群組與帳號資訊

由於公司在彙整一些主機伺服器上的資訊,所以請我這裡作主機帳號及群組匯出的動作
但是在網路上找了很久,大家使用的方式,絕大多數都是透過LDAP的方式去作資料的存取
所以作了一個透過WinNT的方式取得電腦中的群組與帳號資訊

前幾天,由於公司在彙整一些主機伺服器上的資訊,所以請我這裡作主機帳號及群組匯出的動作

但是在網路上找了很久,大家使用的方式,絕大多數都是透過LDAP的方式去作資料的存取

但是LDAP://的這種方式,是僅能使用在已經加入AD的伺服器上所使用,且使用LDAP的方式,才能使用DirectorySearcher這個類別作為AD資料查詢的功能

但是問題來了,這幾台伺服器都是單一伺服器,並沒有加入AD網域,所以僅能透過WinNT://的方式作群組及帳號資料的存取

透過LDAP存取的方式,大家可以參考下面兩篇已經存在於dotblog上的文章

http://www.dotblogs.com.tw/yc421206/archive/2010/02/07/13510.aspx

http://www.dotblogs.com.tw/yc421206/archive/2010/02/01/13436.aspx

以下,就會為大家說明如何使用WinNT://的方式取得群組與帳號資訊

第一個需求,是要列出電腦上的帳號,以及其啟用或是停用狀態

首先,作法與LDAP://的方式一樣,先取得該電腦中的子項目

 

string strQuery = "WinNT://maduka-nb";
DirectoryEntry objAD = new DirectoryEntry(strQuery, [登入電腦的帳號], [登入電腦的密碼]);

foreach (DirectoryEntry objChildDE in objAD.Children)
{
    // 在這裡判斷子項目是否為使用者帳號的SchemaClassName
    if (objChildDE.SchemaClassName == "User")
    {
        int intFlag = (int)objChildDE.Properties["UserFlags"].Value;
        string strState = (!Convert.ToBoolean(intFlag & 0x0002)) ? "" : "停用";
        string strUserName = objChildDE.Name;
    }
}

在程式碼中,可以看到objChildDE.Name就是該帳號的名稱

要找出這個帳號是否停用比較麻煩,就是找出UserFlags這個屬性

詳細的屬性值可以參考http://msdn.microsoft.com/en-us/library/aa772300%28VS.85%29.aspx

但是由於我只要找出是不是停用,所以就用到
string strState = (!Convert.ToBoolean(intFlag & 0x0002))
作為判斷的方式

第二個需求,則是列出電腦中的所有群組,並列出該群組的成員帳號

這部份比較麻煩的是,找出群組容易,但是列出群組的成員比較麻煩,由尤其沒有DirectorySearcher的類別可使用的情況

因此我將程式碼稍微作了一點調整

if (objChildDE.SchemaClassName == "Group")
{
    string strGroupName = objChildDE.Name;

    using (DirectoryEntry groupEntry = new DirectoryEntry("WinNT://maduka-nb/" + strGroupName + ",group"))
    {
        // 找出該群組的詳細資料
        foreach (object member in (IEnumerable)groupEntry.Invoke("Members"))
        {
            using (DirectoryEntry memberEntry = new DirectoryEntry(member))
            {
                string strGroup = strGroupName;
                string strMember = memberEntry.Name;
            }
        }
    }
}

上面的程式碼簡單來說,就是我用了一點投機的方式

先用第一層的foreach找出是群組的SchemaClassName

再用一次DirectoryEntry的方式,去找出該電腦中,這個群組的DirectoryEntry

最後透過groupEntry.Invoke("Members")的方式,找出這個群組中所有的成員,並列出來

使用的方式我是參考http://stackoverflow.com/questions/252882/get-a-list-of-members-of-a-winnt-group

不過他在列出成員時是採用memberEntry.Path

Path的屬性會連同電腦名稱一起列出,所以並不是我要的資料

因此我將Path改為Name的屬性,這樣就可以成功的抓出我想要的內容拉

下圖為最後的結果

範例檔案:WindowsAccountGroup.rar