【发布时间】:2014-02-25 19:28:50
【问题描述】:
我们有一个内部 Windows 控制台应用程序,用于更新我们的 Active Directory。这个应用已经成功运行了好几年了。
最近我的任务是添加代码以禁用超过 90 天未登录系统的用户。
代码似乎运行正常,只是每次应用运行时都会出现一些用户。
这里是搜索代码:
public SearchResultCollection SearchAD(string szSearchOU, string szSearchArg, string szObjectClass)
{
if (szSearchOU == "")
{
ds.SearchRoot = c_DirectoryEntry;
}
else
{
if (!szSearchOU.StartsWith("LDAP://"))
{
szSearchOU = "LDAP://" + szSearchOU;
}
ds.SearchRoot = new DirectoryEntry(szSearchOU);
}
string szFilter = "";
if (szObjectClass == "")
szFilter = "(objectClass=user)";
else
szFilter = "(objectClass=" + szObjectClass + ")";
if (szSearchArg != "")
{
if (szSearchArg.Substring(0, 3) != "CN=")
szSearchArg = "CN=" + szSearchArg;
szFilter = "(&" + szFilter + "(" + szSearchArg + "))";
}
else
ds.PageSize = 1001;
ds.Filter = szFilter;
SearchResultCollection results = ds.FindAll();
return results;
}
此方法在整个应用程序中都使用,因此我有理由确定它可以正常工作。
这是调用搜索并处理它的存根:
SearchResultCollection src = SearchADUsers(szOU, "");
clsDisableLog.WriteLog("Processing: " + src.Count.ToString());
foreach (SearchResult r in src)
{
DirectoryEntry deUser = r.GetDirectoryEntry();
if (c_Debug)
clsDisableLog.WriteLog("Processing: " + deUser.Name + " Path: " + deUser.Path.ToString());
PropertyCollection userAttribs = deUser.Properties;
int flags = (int)deUser.Properties["userAccountControl"].Value;
if (!Convert.ToBoolean((flags & UF_DISABLED) == UF_DISABLED))
{
bool bDisableAccount = false;
DateTime dLastLogon = GetLastLogon(deUser);
if (dLastLogon != DateTime.MinValue)
{
TimeSpan diff = DateTime.Now - dLastLogon;
int iDaysSince = diff.Days;
if (iDaysSince > iDays)
{
clsDisableLog.WriteLog("\t" + deUser.Name);
clsDisableLog.WriteLog("\t\t" + "Has not logged in for " + iDaysSince.ToString() + " days.");
clsDisableLog.WriteLog("\t\t" + "Last logon date: " + dLastLogon.ToLongDateString() + " " + dLastLogon.ToLongTimeString());
clsDisableLog.WriteLog("\t\t" + deUser.Path.ToString());
bDisableAccount = true;
}
}
else
{
clsDisableLog.WriteLog("\t" + deUser.Name);
clsDisableLog.WriteLog("\t\t" + "Has never logged into domain.");
clsDisableLog.WriteLog("\t\t" + "Created: " + deUser.Properties["whenCreated"].Value.ToString());
clsDisableLog.WriteLog("\t\t" + deUser.Path.ToString());
iAccountsNoLogin++;
}
if (bDisableAccount)
{
if (deUser.Path.Contains("UtilityAccounts"))
{
bDisableAccount = false;
clsDisableLog.WriteLog("\t\t" + "NOT Disabling Utility Account: " + deUser.Name);
}
else
{
if (UpdateUserFlag(deUser, UF_DISABLED, true))
{
clsDisableLog.WriteLog("\t\t" + "Disabled");
iAccountsDisabled++;
}
else
clsDisableLog.WriteLog("Error disabling " + deUser.Name);
if (deUser.Path.ToString().ToLower() != deInactiveOU.Path.ToLower())
{
if (MoveUser(deUser, deInactiveOU))
{
clsDisableLog.WriteLog("\t\t" + "Moved to: " + deInactiveOU.Name);
iAccountsMoved++;
}
else
clsDisableLog.WriteLog("Error moving " + deUser.Name + " to " + deInactiveOU.Name);
}
}
}
}
应用程序每次运行时都会处理大约 14 个帐户。
例子:
2/25/2014 12:56:27 PM: CN=XXXXXXXX
2/25/2014 12:56:27 PM: Has not logged in for 252 days.
2/25/2014 12:56:27 PM: Last logon date: Tuesday, June 18, 2013 10:14:45 AM
2/25/2014 12:56:27 PM: LDAP://CN=XXXXXXXX,OU=XXXX User Accounts,DC=XXXXXXXX,DC=LOCAL
2/25/2014 12:56:27 PM: Disabled
2/25/2014 12:56:27 PM: Moved to: OU=Inactive
应用程序运行后,此帐户 IS IN OU=Inactive 并已禁用;但是,如果我重新运行应用程序,用户会再次出现,就像这里一样!
有什么建议吗?
我已设置 DS.CacheResults = false 但是如果我这样做,循环将永远不会执行。
谢谢, 约翰
public bool UpdateUserFlag(DirectoryEntry deUser, int iFlag, Boolean bSet)
{
bool bReturn = false;
int flags = (int)deUser.Properties["userAccountControl"].Value;
try
{
if (bSet)
deUser.Properties["userAccountControl"].Value = flags ^ iFlag;
else
deUser.Properties["userAccountControl"].Value = flags & ~iFlag;
deUser.CommitChanges();
deUser.RefreshCache();
bReturn = true;
}
catch (Exception ex)
{
clsLog.WriteLog("Error updating user flag: " + deUser.Name);
clsLog.Write(ex.Message);
clsLog.WriteLog("");
}
return bReturn;
}
public bool MoveUser(DirectoryEntry deUser, DirectoryEntry deOU)
{
bool bReturn = false;
try
{
deUser.MoveTo(deOU);
deUser.CommitChanges();
deUser.RefreshCache();
bReturn = true;
}
catch (Exception ex)
{
clsLog.WriteLog("Error moving: " + deUser.Name.ToString() + " to: " + deOU.Path);
clsLog.WriteLog(ex.Message);
}
return bReturn;
}
public bool MoveUser(DirectoryEntry deUser, string szOU)
{
bool bReturn = false;
try
{
deUser.MoveTo(new DirectoryEntry(szOU));
deUser.CommitChanges();
deUser.RefreshCache();
bReturn = true;
}
catch (Exception ex)
{
clsLog.WriteLog("Error moving: " + deUser.Name.ToString() + " to: " + szOU);
clsLog.WriteLog(ex.Message);
}
return bReturn;
}
public DateTime GetLastLogon(DirectoryEntry deUser)
{
DateTime dtLL = DateTime.MinValue;
try
{
if (deUser.Properties["lastLogonTimeStamp"].Count != 0)
dtLL = GetDateTimeFromLargeInteger((IADsLargeInteger)deUser.Properties["lastLogonTimeStamp"][0]);
}
catch (Exception ex)
{
clsLog.WriteLog("Error Retrieving Last Logon Time Stamp for: " + deUser.Name.ToString());
clsLog.Write(ex.Message);
clsLog.WriteLog("");
}
return dtLL;
}
根据一个答案,我已经发布了存根中调用的方法的代码 - 尽管它们与问题无关,因为我已经确认它们在必要时起作用。帐户被禁用,它们被移动到相关的 OU。
问题不是代码没有做它应该做的事情 - 而是 AD 发现用户帐户没有被禁用并且不在 OU 中,即使我可以确认使用 Active Directory 用户和计算机。
约翰
【问题讨论】:
标签: c# active-directory