Changing a Windows NT Password Using ADSI

Credit: Devin Leung

Problem

You need to change a user’s password on Windows NT.

Solution

The simplest approach is to access the Active Directory Services Interface (ADSI) via COM automation:

import pythoncom
import win32com.client

class NTUser:
    # Uses ADSI to change password under user privileges
    def _ _init_ _(self, userid):
        self.adsiNS = win32com.client.Dispatch('ADsNameSpaces')
        Userpath = "WinNT://DOMAIN/" + userid + ",user"
        self.adsNTUser = self.adsiNS.GetObject("", Userpath)

    def reset(self, OldPasswd, NewPasswd):
        self.adsNTUser.ChangePassword(OldPasswd, NewPasswd)

    # If you're running under admin privileges, you might use:
        self.adsNTUser.SetPassword(NewPasswd)

def changepass(account, OldPassword, NewPassword):
    try:
        nt = NTUser(account)
        nt.reset(OldPassword, NewPassword)
        print "NT Password change was successful."
        return 1
    except pythoncom.com_error, (hr, msg, exc, arg):
        # Give clearer error messages; avoid stack traces
        scode = exc[5]
        print "NT Password change has failed."

        if scode == 0x8007005:
            print "Your NT Account (%s) is locked out."%account
        elif scode == 0x80070056:
            print "Invalid Old NT Password."
        elif scode == 0x800708ad:
            print "The specified NT Account (%s) does not exist."%account
        elif scode == 0x800708c5:
            print "Your new password cannot be the same as any of your"
            print "previous passwords, and must satisfy the domain's"
            print "password-uniqueness policies."
        else:
            print "ADSI Error - %x: %s, %x\n" % (hr, msg, scode)
        return 0

Discussion

This recipe gives an example of how to use Python COM to instantiate an ADSI object and change an NT user’s password. ADSI, Microsoft’s Active Directory Services Interface, is documented at http://www.microsoft.com/windows2000/techinfo/howitworks/activedirectory/adsilinks.asp.

Python’s COM access is perhaps the most important single feature of Mark Hammond’s win32all extensions. You call win32com.client.Dispatch with the COM automation ProgID string as its single argument and get as a result a Python object on which you can call methods and get and set properties to access all of the functionality of the COM server named by ProgId. The set of methods and properties available is different for every COM server, and you need to find and study the documentation for the specific object model of each server to use it most fruitfully. For example, the methods we call here on COM objects that model active-directory namespaces and NT users are documented in the ADSI documentation.

This recipe can be used to roll your own password-change program. I am currently using it as part of a multiplatform password-changing utility, which helps users keep their passwords in sync on many machines that run different operating systems, both Windows and non-Windows.

See Also

Documentation for pythoncom and win32com.client in win32all (http://starship.python.net/crew/mhammond/win32/Downloads.html) or ActivePython (http://www.activestate.com/ActivePython/); Windows API documentation available from Microsoft (http://msdn.microsoft.com); Python Programming on Win32, by Mark Hammond and Andy Robinson (O’Reilly).

Get Python Cookbook now with the O’Reilly learning platform.

O’Reilly members experience live online training, plus books, videos, and digital content from nearly 200 publishers.