[英]Enumerate Windows user group members on remote system using c#
在c#中,我需要能夠
因此,例如,我將使用適當的信用連接到\\ SOMESYSTEM,並獲取本地管理員列表,包括SOMESYSTEM \\ Administrator,SOMESYSTEM \\ Bob,DOMAIN \\ AlanH,“DOMAIN \\ Domain Administrators”。
我已經嘗試使用system.directoryservices.accountmanagement但遇到了身份驗證問題。 有時我得到:
不允許同一用戶使用多個用戶名與服務器或共享資源建立多個連接。 斷開與服務器或共享資源的所有先前連接,然后重試。 (HRESULT異常:0x800704C3)
以上是嘗試,因為有些情況下我根本無法取消映射現有的驅動器或UNC連接。
其他時候我的程序獲得UNKNOWN ERROR並且遠程系統上的安全日志報告錯誤675,代碼0x19是KDC_ERR_PREAUTH_REQUIRED。
我需要一個更簡單,更不容易出錯的方法來做到這一點!
大衛是在正確的軌道上,我正在給他答案。
但是必要的WMI查詢比直接的要少一些,因為我不僅需要整個機器的用戶列表,而且還需要本地Administrators組成員的本地或域用戶和組的子集。 為了記錄,該WMI查詢是:
SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = "Win32_Group.Domain='thehostname',Name='thegroupname'"
這是完整的代碼片段:
public string GroupMembers(string targethost, string groupname, string targetusername, string targetpassword)
{
StringBuilder result = new StringBuilder();
try
{
ConnectionOptions Conn = new ConnectionOptions();
if (targethost != Environment.MachineName) //WMI errors if creds given for localhost
{
Conn.Username = targetusername; //can be null
Conn.Password = targetpassword; //can be null
}
Conn.Timeout = TimeSpan.FromSeconds(2);
ManagementScope scope = new ManagementScope("\\\\" + targethost + "\\root\\cimv2", Conn);
scope.Connect();
StringBuilder qs = new StringBuilder();
qs.Append("SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = \"Win32_Group.Domain='");
qs.Append(targethost);
qs.Append("',Name='");
qs.Append(groupname);
qs.AppendLine("'\"");
ObjectQuery query = new ObjectQuery(qs.ToString());
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
ManagementPath path = new ManagementPath(m["PartComponent"].ToString());
{
String[] names = path.RelativePath.Split(',');
result.Append(names[0].Substring(names[0].IndexOf("=") + 1).Replace("\"", " ").Trim() + "\\");
result.AppendLine(names[1].Substring(names[1].IndexOf("=") + 1).Replace("\"", " ").Trim());
}
}
return result.ToString();
}
catch (Exception e)
{
Console.WriteLine("Error. Message: " + e.Message);
return "fail";
}
}
所以,如果我調用Groupmembers(“Server1”,“Administrators”,“myusername”,“mypassword”); 我得到一個返回的字符串:
SERVER1 \\管理員
MYDOMAIN \\ Domain Admins
實際的WMI回報更像是這樣的:
\\\\ SERVER1 \\ ROOT \\ CIMV2:Win32_UserAccount.Domain = “SERVER 1”,名稱= “管理員”
...所以你可以看到,我不得不做一些小的字符串操作來完善它。
這應該很容易使用WMI。 在這里你有一個指向一些文檔的指針:
即使您以前沒有WMI經驗,也應該很容易將頁面底部的VB Script代碼轉換為某些.NET代碼。
希望這有幫助!
我建議使用Win32 API函數NetLocalGroupGetMembers 。 它比試圖找出瘋狂的LDAP語法要簡單得多,這對於這里推薦的其他一些解決方案來說是必要的。 只要您通過調用“LoginUser”來模擬要運行檢查的用戶,就不應該遇到任何安全問題。
您可以在此處找到進行模擬的示例代碼。
如果你需要幫助搞清楚如何從C#調用“NetLocalGroupGetMembers”,我建議你查看Jared Parson的PInvoke助手,你可以從codeplex 下載 。
如果您在IIS中運行的ASP.NET應用程序中運行代碼,並且想要模擬訪問網站以進行調用的用戶,則可能需要向生產Web服務器授予“Trusted for Delegation”權限。
如果您在桌面上運行,那么使用活動用戶的安全憑證應該不是問題。
網絡管理員可能已撤消對您嘗試訪問的特定計算機的“安全對象”的訪問權限。 不幸的是,訪問對於所有網絡管理API函數都是必需的。 如果是這種情況,那么您將需要為要執行的任何用戶授予對“安全對象”的訪問權限。 但是,使用默認的Windows安全設置,所有經過身份驗證的用戶都應具有訪問權
我希望這有幫助。
斯科特
您應該能夠使用System.DirectoryServices.DirectoryEntry執行此操作。 如果您無法遠程運行它,也許您可以在遠程計算機上安裝一些東西,通過某種RPC(如遠程處理或Web服務)為您提供數據。 但我認為你所嘗試的應該可以遠程進行,而不會過於花哨。
如果Windows不允許您通過它的登錄機制進行連接,我認為您唯一的選擇是使用開放端口(直接或通過遠程處理或Web服務,如上所述)在遠程計算機上運行某些東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.