Active Directory 在 Windows 服务中获取 Locked/Unlocked 状态
Active Directory Acquiring Locked/Unlocked status in a Windows Service
我正在创建一个 Windows 服务,它获取本地域 TRY.local 中所有 Active Directory 帐户的 Locked/Unlocked 状态。
即使名为 user1 的帐户被锁定,它也会为 IsAccountLocked().
提供 false 值
using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
Library.WriteErrorLog("First Name: " + de.Properties["givenName"].Value);
try{
string name = (string)de.Properties["samaccountname"].Value;
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,"TRY.local","CN="+name+",OU=Users,DC=TRY,DC=local","administrator","password");
UserPrincipal usr = UserPrincipal.FindByIdentity(ctx, name);
if(usr!=null){
Library.WriteErrorLog("IsAccountLockedOut\t"+usr.IsAccountLockedOut());
}
usr.Dispose();
ctx.Dispose();
}
catch(Exception e){
Library.WriteErrorLog(e);
}
}
}
我也试过了
using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
Library.WriteErrorLog("SAM Account Name : " + de.Properties["samaccountname"].Value);
int uc = Convert.ToInt32(de.Properties["userAccountControl"][0]);
const int ADS_LOCKOUT = 0x00000010;
bool account_LockedOut = (uc & ADS_LOCKOUT)==ADS_LOCKOUT;
Library.WriteErrorLog("IsAccountLockedOut : "+account_LockedOut);
}
}
}
WriteErrorLog(string abc) 将 abc 写入文本文件
我是 Active Directory 的新手,如果能得到有关此问题的指导,我将不胜感激。
提前致谢!
您必须拥有有效的网络凭据才能查询 Active Directory。
当服务 运行 作为本地服务时,它没有网络凭据 - 它只能在本地系统上运行。如果您需要网络凭据,请将服务配置为 运行 作为网络服务。 (如果您需要本地计算机的管理员访问权限,请使用本地系统;它具有网络凭据和本地管理员访问权限。)
作为网络服务或本地系统的服务 运行 在访问网络时使用计算机的 Active Directory 帐户,即,如果计算机名为 PLUGH
,则用于访问网络的用户名是PLUGH$
.
我发现当 UserPrincipal 对象用于获取帐户的锁定状态时,整个 LDAP 路径 直到组织用户所在的单位 (OU) 应与管理员登录名和密码一起作为参数提供给 PrincipalContext。
例如:
using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
string path = de.Path;
var offset = path.IndexOf('/');
offset = path.IndexOf('/', offset+1);
offset = path.IndexOf('/', offset+1);
path = path.Substring(offset+1);
string user_id = Convert.ToString(de.Properties["samaccountname"].Value);
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
"TRY.local",
path,
"administrator",
"password");
为了使用 UserPrincipal,我们现在将 ctx 和 user_id 作为参数传递给 UserPrincipal.FindByIdentity(PrincipalContext, string) 方法。
字符串路径最终将包含:"CN=User,OU=USERS,OU=DEPARTMENT,DC=SERVER,DC=COM"
UserPrincipal user_locked = UserPrincipal.FindByIdentity(ctx, username);
if (user_locked != null) {
if (user_locked.IsAccountLockedOut()){
user_locked.UnlockAccount();
}
user_locked.Dispose();
Console.WriteLine("Unlocked");
}
ctx.Dispose();
我正在创建一个 Windows 服务,它获取本地域 TRY.local 中所有 Active Directory 帐户的 Locked/Unlocked 状态。 即使名为 user1 的帐户被锁定,它也会为 IsAccountLocked().
提供 false 值using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
Library.WriteErrorLog("First Name: " + de.Properties["givenName"].Value);
try{
string name = (string)de.Properties["samaccountname"].Value;
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,"TRY.local","CN="+name+",OU=Users,DC=TRY,DC=local","administrator","password");
UserPrincipal usr = UserPrincipal.FindByIdentity(ctx, name);
if(usr!=null){
Library.WriteErrorLog("IsAccountLockedOut\t"+usr.IsAccountLockedOut());
}
usr.Dispose();
ctx.Dispose();
}
catch(Exception e){
Library.WriteErrorLog(e);
}
}
}
我也试过了
using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
Library.WriteErrorLog("SAM Account Name : " + de.Properties["samaccountname"].Value);
int uc = Convert.ToInt32(de.Properties["userAccountControl"][0]);
const int ADS_LOCKOUT = 0x00000010;
bool account_LockedOut = (uc & ADS_LOCKOUT)==ADS_LOCKOUT;
Library.WriteErrorLog("IsAccountLockedOut : "+account_LockedOut);
}
}
}
WriteErrorLog(string abc) 将 abc 写入文本文件
我是 Active Directory 的新手,如果能得到有关此问题的指导,我将不胜感激。 提前致谢!
您必须拥有有效的网络凭据才能查询 Active Directory。
当服务 运行 作为本地服务时,它没有网络凭据 - 它只能在本地系统上运行。如果您需要网络凭据,请将服务配置为 运行 作为网络服务。 (如果您需要本地计算机的管理员访问权限,请使用本地系统;它具有网络凭据和本地管理员访问权限。)
作为网络服务或本地系统的服务 运行 在访问网络时使用计算机的 Active Directory 帐户,即,如果计算机名为 PLUGH
,则用于访问网络的用户名是PLUGH$
.
我发现当 UserPrincipal 对象用于获取帐户的锁定状态时,整个 LDAP 路径 直到组织用户所在的单位 (OU) 应与管理员登录名和密码一起作为参数提供给 PrincipalContext。
例如:
using (var context = new PrincipalContext(ContextType.Domain, "TRY.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
string path = de.Path;
var offset = path.IndexOf('/');
offset = path.IndexOf('/', offset+1);
offset = path.IndexOf('/', offset+1);
path = path.Substring(offset+1);
string user_id = Convert.ToString(de.Properties["samaccountname"].Value);
PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
"TRY.local",
path,
"administrator",
"password");
为了使用 UserPrincipal,我们现在将 ctx 和 user_id 作为参数传递给 UserPrincipal.FindByIdentity(PrincipalContext, string) 方法。
字符串路径最终将包含:"CN=User,OU=USERS,OU=DEPARTMENT,DC=SERVER,DC=COM"
UserPrincipal user_locked = UserPrincipal.FindByIdentity(ctx, username);
if (user_locked != null) {
if (user_locked.IsAccountLockedOut()){
user_locked.UnlockAccount();
}
user_locked.Dispose();
Console.WriteLine("Unlocked");
}
ctx.Dispose();