Search code examples
c#active-directoryldapchange-passwordprincipalcontext

C# PrincipalContext only changes password for some users, not all


I'm trying to change the AD password of all members in my system, but my code only changes the password for some members successfully. For members whose password can't be changed, it shows the following error:

System.NullReferenceException: Object reference not set to an instance of an object. at changep1.changep2.changeUserPassword(String _userID, String _oldPassword, String _newPassword) in C:\Users\Intern\source\repos\changep1\changep1\changep2.aspx.cs:line 52

Here is my c# code:

 public string changeUserPassword(string _userID, string _oldPassword, string _newPassword)
        {
            string message="";
            try
            {
                PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, "extra.sales-comm.local", "DC=sales-comm,DC=local",
                ContextOptions.SimpleBind, @"admin", "Passw@rd");
                UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, _userID);

                oUserPrincipal.ChangePassword(_oldPassword, _newPassword);


                oUserPrincipal.Save();
            }
            catch (Exception e)
            {
                message = e.ToString();
            }
            return message;
        }

I don't understand why my code doesn't change passwords for all AD members. Please help thanks.


Solution

  • Your code needs to check if the UserPrincipal value while finding the identity is null, in case if the passed user-id is not found. You've not checked the same in your code. This looks like the reason why it is giving a Null Pointer Exception.

    Read the docs for the method UserPrincipal.FindByIdentity Method (PrincipalContext, String):

    Returns a user principal object that matches the specified identity value.

    Parameters

    context Type: System.DirectoryServices.AccountManagement.PrincipalContext

    The PrincipalContext that specifies the server or domain against which operations are performed.

    identityValue Type: System.String

    The identity of the user principal. This parameter can be any format that is contained in the IdentityType enumeration.


    ... // IdentityType Enumeration members are listed below:

    Member name----------------------- Description

    DistinguishedName-------------- The identity is a Distinguished Name (DN).

    Guid ---------------------- The identity is a Globally Unique Identifier (GUID).

    Name ---------------- The identity is a name.

    SamAccountName--------------- The identity is a Security Account Manager (SAM) name.

    Sid ------------- The identity is a Security Identifier (SID) in Security Descriptor Definition Language (SDDL) format.

    UserPrincipalName The identity is a User Principal Name (UPN).

    Do as shown below:

             try
                {
                    PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, "extra.sales-comm.local", "DC=sales-comm,DC=local", ContextOptions.SimpleBind, @"admin", "Passw@rd");
                    UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, _userID);
                   if ( null != oUserPrincipal){
                    oUserPrincipal.ChangePassword(_oldPassword, _newPassword);    
                    oUserPrincipal.Save();
                   }
                   else {
                   // return the message that the user-id could not be found.
                   // preferably passed argumnet in user-id should be **SamAccountName**
                   // please make sure that the user-id corresponds to the members mentioned above
                   }
                }
                catch (Exception e)
                {
                    message = e.ToString();
                }