dotNET Core how to operate the AD (Continued)

In the previous article how to operate AD "dotNET Core in? " Mainly to synchronize data AD to the scene database described in how to operate the AD dotNetCore herein will introduce some other common operations continue to operate in dotNetCore in AD.

surroundings

  • dotNET Core:3.0

  • Novell.Directory.Ldap.NETStandard2_0:3.1.0

  • AD:windows server 2012

Basic Operations

Inquire

User operation in AD, usually need to determine whether the user is present, then you need to use the query, the query may be performed in AD with the following codes:

 var entities = _connection.Search(ADClient.BaseDC,LdapConnection.SCOPE_SUB,
     $"sAMAccountName={loginName}",
     null, false);

Parameter Description:

  • base: general search range specified, usually specify a BaseDC up a connection, the latter showing the operation within this range DC, if desired to start the search from the root, this parameter may be null passed

  • scope: Query traverse way into SCOPE_BASE, SCOPE_ONE and three kinds SCOPE_SUB

    • SCOPE_BASE: usually know when DN object and want to get their properties, use this

    • SCOPE_ONE: Query base next level

    • SCOPE_SUB: all the objects in the query base, containing base

  • filter: to filter expressions, the following expressions are some common

    (cn=oec2003):返回 cn 等于 oec2003 的用户
    (sAMAccountName=oec*):返回登录名以 oec 开头的用户
    !(cn=oec2003):返回 cn 不等于 oec2003 的用户
    (|(cn=oec2003)(telephonenumber=888*)):返回 cn 等于 oec2003 ,或者电话号码以 888 开头的用户
    (&(cn=oec2003)(telephonenumber=888*)):返回 cn 等于 oec2003 ,并且电话号码以 888 开头的用户
    

    Other more expressions can refer to the official document: https: //www.novell.com/documentation/developer/ldapcsharp/ page = / documentation / developer / ldapcsharp / cnet / data / bovtuda.html?

  • attrs: string array, may specify property returns a list of all attributes is not specified return

For example, according to the sample code to query the user's login name as follows:

public static LdapEntry GetUser(string loginName)
{
    var entities = _connection.Search(ADClient.BaseDC,LdapConnection.SCOPE_SUB,
               $"sAMAccountName={loginName}",
               null, false);
    LdapEntry entry = null;
    while (entities.HasMore())
    {

        try
        {
            entry = entities.Next();
        }
        catch (LdapException e)
        {
            Console.WriteLine($"GetUser Error: {e.Message}");
            continue;
        }
    }

    return entry;
}

Add user

public static bool AddUser(string userName, string loginName, string defaultPwd, string container)
{
    //设置默认密码
    defaultPwd = $"\"{defaultPwd}\"";
    sbyte[] encodedBytes = SupportClass.ToSByteArray(Encoding.Unicode.GetBytes(defaultPwd));

    LdapAttributeSet attributeSet = new LdapAttributeSet();
    attributeSet.Add(new LdapAttribute("objectclass", "user"));
    attributeSet.Add(new LdapAttribute("sAMAccountName", userName));
    //设置创建用户后启用
    attributeSet.Add(new LdapAttribute("userAccountControl", (66080).ToString()));
    attributeSet.Add(new LdapAttribute("unicodePwd", encodedBytes));

    string dn = $"CN={loginName},{container}";
    LdapEntry newEntry = new LdapEntry(dn, attributeSet);
    _connection.Add(newEntry);
    return true;
}

important point:

  • Set the default password of password needed to add quotes

  • Created by the user is disabled by default, if you need to add the code to enableattributeSet.Add(new LdapAttribute("userAccountControl", (66080).ToString()));

change Password

public static bool UpdatePassword(string loginName, string password)
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    password = $"\"{password}\"";
    sbyte[] encodedBytes = SupportClass.ToSByteArray(Encoding.Unicode.GetBytes(password));
    LdapAttribute attributePassword = new LdapAttribute("unicodePwd", encodedBytes);

    _connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));

    return true;
}

Disable User

public static bool EnblaedUser(string loginName)
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    LdapAttribute attributePassword = new LdapAttribute("userAccountControl", (66082).ToString());
    _connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));

    return true;
}

Enable User

public static bool EnblaedUser(string loginName)
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    LdapAttribute attributePassword = new LdapAttribute("userAccountControl", (66080).ToString());
    _connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));

    return true;
}

Moving users to the new OU

public static bool MoveUserToOU(string loginName, string rcn = "", string ouContainer = "")
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    string cn = entry.AttrStringValue("cn");
    cn = rcn == "" ? cn : rcn;
    string newRCN = $"CN={cn}";

    if (string.IsNullOrWhiteSpace(ouContainer))
    {
        _connection.Rename(entry.DN, newRCN, true);
    }
    else
    {
        _connection.Rename(entry.DN, newRCN, ouContainer, true);
    }

    return true;
}

important point:

  • 一个用户一旦创建,DN 是不能修改的,可以通过Rename方法来修改 CN 来达到修改 DN 的目的

  • 如果传入第三个参数ouContainer,就可以实现将用户移动到目标 OU

添加用户到组

public static bool AddUserToGroup(string loginName, string groupDN)
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    List<string> memberOf = entry.AttrStringValueArray("memberOf");
    if (memberOf.Contains(groupDN))
    {
        throw new Exception($"名为:{loginName} 的用户已经加入了组: {groupDN}");
    }

    LdapModification[] modGroup = new LdapModification[1];
    LdapAttribute member = new LdapAttribute("member", entry.DN);
    modGroup[0] = new LdapModification(LdapModification.ADD, member);

    try
    {
        _connection.Modify(groupDN, modGroup);
    }
    catch (LdapException e)
    {
        System.Console.Error.WriteLine("Failed to modify group's attributes: " + e.LdapErrorMessage);
        return false;
    }
    catch (Exception e)
    {
        Console.Error.WriteLine("AddUserToGroup Error:" + e.Message);
        return false;
    }
    return true;
}

用户从组中移除

public static bool RemoveUserFromGroup(string loginName, string groupDN)
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    List<string> memberOf = entry.AttrStringValueArray("memberOf");
    if (!memberOf.Contains(groupDN))
    {
        throw new Exception($"名为:{loginName} 的用户不存在于组: {groupDN} 中");
    }

    LdapModification[] modGroup = new LdapModification[1];
    LdapAttribute member = new LdapAttribute("member", entry.DN);
    modGroup[0] = new LdapModification(LdapModification.DELETE, member);

    try
    {
        _connection.Modify(groupDN, modGroup);
    }
    catch (LdapException e)
    {
        System.Console.Error.WriteLine("Failed to delete group's attributes: " + e.LdapErrorMessage);
        return false;
    }
    catch (Exception e)
    {
        Console.Error.WriteLine("RemoveUserFromGroup Error:" + e.Message);
        return false;
    }
    return true;
}

添加用户登录到

public static bool UpdateUserWorkStation(string loginName, string computerName, UserWorkStationOperType type)
{
    LdapEntry entry = GetUser(loginName);
    if (entry == null)
    {
        throw new Exception($"名为:{loginName} 的用户在AD中不存在");
    }

    List<string> stations = entry.AttrStringValue("userWorkstations").Split(',').ToList();
    if (type == UserWorkStationOperType.Add && !stations.Contains(computerName))
    {
        stations.Add(computerName);
    }
    else if (type == UserWorkStationOperType.Remove && stations.Contains(computerName))
    {
        stations.Remove(computerName);
    }

    LdapAttribute attributePassword = new LdapAttribute("userWorkstations", string.Join(',', stations));
    _connection.Modify(entry.DN, new LdapModification(LdapModification.REPLACE, attributePassword));
    return true;
}

最后

本文的示例代码已推送到 GitHub:https://github.com/oec2003/DotNetCoreAdDemo

官网也有些示例,但不是很完善,而且有很多代码并不能正常执行(可能跟 AD 的版本有关),所以才有了本示例。本示例也会添加更多的使用场景,不断完善。

希望本文对您有所帮助。

发布了1535 篇原创文章 · 获赞 586 · 访问量 237万+

Guess you like

Origin blog.csdn.net/sD7O95O/article/details/104067214