由於公司在彙整一些主機伺服器上的資訊,所以請我這裡作主機帳號及群組匯出的動作
但是在網路上找了很久,大家使用的方式,絕大多數都是透過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的屬性,這樣就可以成功的抓出我想要的內容拉
下圖為最後的結果