C# Active Directory中的userAccountControl

C# Active Directory中的userAccountControl,c#,properties,active-directory,user-accounts,C#,Properties,Active Directory,User Accounts,我想知道userAccountControl的当前值,并确定它处于哪个阶段 参考: 根据上述文件,应将2的值返回到幂N 但当我运行我的c#程序时,它会为正常帐户返回值544,为禁用帐户返回值546。我怀疑它们是十进制数。但是我怎样才能链接回参考中所示的值呢 谢谢。 544=十六进制0x220 546=十六进制0x222 根据法律,这意味着: 0x200 = normal account 0x020 = passwd_notreqd = password not required 0x002 =

我想知道userAccountControl的当前值,并确定它处于哪个阶段

参考:

根据上述文件,应将2的值返回到幂N

但当我运行我的c#程序时,它会为正常帐户返回值544,为禁用帐户返回值546。我怀疑它们是十进制数。但是我怎样才能链接回参考中所示的值呢

谢谢。

  • 544=十六进制0x220
  • 546=十六进制0x222
根据法律,这意味着:

0x200 = normal account
0x020 = passwd_notreqd = password not required
0x002 = account disabled
所以

  • 544(十进制)的值为
    0x220
    十六进制,表示:正常帐户,不需要密码
  • 546(十进制)的值为
    0x222
    十六进制,表示:正常帐户,已禁用,不需要密码

通过将结果转换为枚举,您可以轻松地对其进行解码

int userAccountControlValue = 544;
UserAccountControl userAccountControl = (UserAccountControl) userAccountControlValue;

// This gets a comma separated string of the flag names that apply.
string userAccountControlFlagNames = userAccountControl.ToString();

// This is how you test for an individual flag.
bool isNormalAccount = (userAccountControl & UserAccountControl.NORMAL_ACCOUNT) == UserAccountControl.NORMAL_ACCOUNT;
bool isAccountDisabled = (userAccountControl & UserAccountControl.ACCOUNTDISABLE) == UserAccountControl.ACCOUNTDISABLE;
bool isAccountLockedOut = (userAccountControl & UserAccountControl.LOCKOUT) == UserAccountControl.LOCKOUT;
以下是您需要的枚举定义:

/// <summary>
/// Flags that control the behavior of the user account.
/// </summary>
[Flags()]
public enum UserAccountControl : int
{
    /// <summary>
    /// The logon script is executed. 
    ///</summary>
    SCRIPT = 0x00000001,

    /// <summary>
    /// The user account is disabled. 
    ///</summary>
    ACCOUNTDISABLE = 0x00000002,

    /// <summary>
    /// The home directory is required. 
    ///</summary>
    HOMEDIR_REQUIRED = 0x00000008,

    /// <summary>
    /// The account is currently locked out. 
    ///</summary>
    LOCKOUT = 0x00000010,

    /// <summary>
    /// No password is required. 
    ///</summary>
    PASSWD_NOTREQD = 0x00000020,

    /// <summary>
    /// The user cannot change the password. 
    ///</summary>
    /// <remarks>
    /// Note:  You cannot assign the permission settings of PASSWD_CANT_CHANGE by directly modifying the UserAccountControl attribute. 
    /// For more information and a code example that shows how to prevent a user from changing the password, see User Cannot Change Password.
    // </remarks>
    PASSWD_CANT_CHANGE = 0x00000040,

    /// <summary>
    /// The user can send an encrypted password. 
    ///</summary>
    ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080,

    /// <summary>
    /// This is an account for users whose primary account is in another domain. This account provides user access to this domain, but not 
    /// to any domain that trusts this domain. Also known as a local user account. 
    ///</summary>
    TEMP_DUPLICATE_ACCOUNT = 0x00000100,

    /// <summary>
    /// This is a default account type that represents a typical user. 
    ///</summary>
    NORMAL_ACCOUNT = 0x00000200,

    /// <summary>
    /// This is a permit to trust account for a system domain that trusts other domains. 
    ///</summary>
    INTERDOMAIN_TRUST_ACCOUNT = 0x00000800,

    /// <summary>
    /// This is a computer account for a computer that is a member of this domain. 
    ///</summary>
    WORKSTATION_TRUST_ACCOUNT = 0x00001000,

    /// <summary>
    /// This is a computer account for a system backup domain controller that is a member of this domain. 
    ///</summary>
    SERVER_TRUST_ACCOUNT = 0x00002000,

    /// <summary>
    /// Not used. 
    ///</summary>
    Unused1 = 0x00004000,

    /// <summary>
    /// Not used. 
    ///</summary>
    Unused2 = 0x00008000,

    /// <summary>
    /// The password for this account will never expire. 
    ///</summary>
    DONT_EXPIRE_PASSWD = 0x00010000,

    /// <summary>
    /// This is an MNS logon account. 
    ///</summary>
    MNS_LOGON_ACCOUNT = 0x00020000,

    /// <summary>
    /// The user must log on using a smart card. 
    ///</summary>
    SMARTCARD_REQUIRED = 0x00040000,

    /// <summary>
    /// The service account (user or computer account), under which a service runs, is trusted for Kerberos delegation. Any such service 
    /// can impersonate a client requesting the service. 
    ///</summary>
    TRUSTED_FOR_DELEGATION = 0x00080000,

    /// <summary>
    /// The security context of the user will not be delegated to a service even if the service account is set as trusted for Kerberos delegation. 
    ///</summary>
    NOT_DELEGATED = 0x00100000,

    /// <summary>
    /// Restrict this principal to use only Data Encryption Standard (DES) encryption types for keys. 
    ///</summary>
    USE_DES_KEY_ONLY = 0x00200000,

    /// <summary>
    /// This account does not require Kerberos pre-authentication for logon. 
    ///</summary>
    DONT_REQUIRE_PREAUTH = 0x00400000,

    /// <summary>
    /// The user password has expired. This flag is created by the system using data from the Pwd-Last-Set attribute and the domain policy. 
    ///</summary>
    PASSWORD_EXPIRED = 0x00800000,

    /// <summary>
    /// The account is enabled for delegation. This is a security-sensitive setting; accounts with this option enabled should be strictly 
    /// controlled. This setting enables a service running under the account to assume a client identity and authenticate as that user to 
    /// other remote servers on the network.
    ///</summary>
    TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0x01000000,

    /// <summary>
    /// 
    /// </summary>
    PARTIAL_SECRETS_ACCOUNT = 0x04000000,

    /// <summary>
    /// 
    /// </summary>
    USE_AES_KEYS = 0x08000000
}
//
///控制用户帐户行为的标志。
/// 
[标志()]
公共枚举UserAccountControl:int
{
/// 
///将执行登录脚本。
///
脚本=0x00000001,
/// 
///用户帐户已禁用。
///
ACCOUNTDISABLE=0x00000002,
/// 
///主目录是必需的。
///
HOMEDIR_必需=0x00000008,
/// 
///该帐户当前被锁定。
///
锁定=0x00000010,
/// 
///不需要密码。
///
PASSWD_NOTREQD=0x00000020,
/// 
///用户无法更改密码。
///
/// 
///注意:不能通过直接修改UserAccountControl属性来分配PASSWD\u CANT\u CHANGE的权限设置。
///有关详细信息和显示如何防止用户更改密码的代码示例,请参阅用户无法更改密码。
// 
PASSWD\u CANT\u CHANGE=0x00000040,
/// 
///用户可以发送加密密码。
///
加密的\u文本\u密码\u允许=0x00000080,
/// 
///这是主帐户位于另一个域中的用户的帐户。此帐户为用户提供对此域的访问权限,但不提供访问权限
///任何信任此域的域。也称为本地用户帐户。
///
临时重复账户=0x00000100,
/// 
///这是代表典型用户的默认帐户类型。
///
正常账户=0x00000200,
/// 
///这是信任其他域的系统域的信任许可证帐户。
///
域间信任帐户=0x00000800,
/// 
///这是属于此域成员的计算机的计算机帐户。
///
工作站信任账户=0x000011000,
/// 
///这是作为此域成员的系统备份域控制器的计算机帐户。
///
服务器信任帐户=0x00002000,
/// 
///没有用。
///
未使用1=0x00004000,
/// 
///没有用。
///
未使用的2=0x00008000,
/// 
///此帐户的密码永远不会过期。
///
不过期\u PASSWD=0x00010000,
/// 
///这是一个MNS登录帐户。
///
MNS\u登录\u帐户=0x00020000,
/// 
///用户必须使用智能卡登录。
///
所需智能卡=0x00040000,
/// 
///运行服务的服务帐户(用户或计算机帐户)受Kerberos委派的信任。任何此类服务
///可以模拟请求服务的客户端。
///
委托的受信任\u=0x00080000,
/// 
///即使服务帐户设置为Kerberos委派的受信任帐户,用户的安全上下文也不会委派给服务。
///
未授权=0x00100000,
/// 
///限制此主体仅对密钥使用数据加密标准(DES)加密类型。
///
仅使用_DES_KEY_=0x00200000,
/// 
///此帐户登录时不需要Kerberos预身份验证。
///
不需要预授权=0x00400000,
/// 
///用户密码已过期。此标志由系统使用Pwd Last Set属性和域策略中的数据创建。
///
密码\u过期=0x00800000,
/// 
///该帐户已启用委派。这是一个安全敏感设置;启用此选项的帐户应严格禁用
///受控。此设置允许在帐户下运行的服务采用客户端身份并作为该用户进行身份验证
///网络上的其他远程服务器。
///
受信任的\u为\u委派对\u进行身份验证\u=0x01000000,
/// 
/// 
/// 
部分机密帐户=0x04000000,
/// 
/// 
/// 
使用密钥=0x08000000
}

这是一个位图。字中的每一位都是开或关(0或1)。它其实不是一个数字,更像是一排开关,每个开关开或关。操作系统在内部使用它们,因为它们可以通过将它们与位掩码进行逻辑比较来非常快速地操作它们

属性的LDIF表示可以将结果显示为十进制数(相当于掩码表示的二进制数,如果它是一个数字,那么它就不是真正的数字!),并且它非常容易解码,因为它基本上是通过将一些2的幂加在一起来实现的

例如:

  512 = normal account
  514 = 512 + 2 = normal account, disabled
  546 = 512 + 32 + 2 = normal account, disabled, no password required
 2080 = 2048 + 32 = Interdomain trust, no password required
66048 = 65536 + 512 = normal account. password never expires
66050 = 65536 + 512 + 2 = normal account. password never expires, disabled
66080 = 65536 + 512 + 32 = normal account. password never expires, no password required

测试标志时,另一种稍微不太详细但功能等效的语法是:
bool isNormalAccount=(userAccountControl&userAccountControl.NORMAL\u ACCOUNT)>0
@TawabWakil如果要使用,请使用
!=0
而不是
>0
。在某些情况下,测试>0可能会有问题。除此之外,你是对的。您可以在不重复比较右侧的标志的情况下执行此操作。我这样做是为了一致性和可读性。我想不出在OP的上下文中会出现问题的场景,但是使用