Lead Image © Eric Issele, 123RF.com

Lead Image © Eric Issele, 123RF.com

Automate Active Directory management with the Python PyAD library

Snappy Python

Article from ADMIN 78/2023
By
Windows admins can use the Python PyAD library to automate Active Directory configuration and management. Deployment on a Windows server is a snap and paves the way for delegating tedious routine tasks to Python scripts.

PyAD [1] is a useful tool for Active Directory (AD) automation with Python in many environments. However, about two years ago, the developer decided to stop maintaining the open source product. The lack of pull requests in the Git repository shows that the library generally works without problems.

In practice, however, the library needs to be assessed as a potential risk; after all, it does affect Active Directory. Administrators who are not forced to use Python will want to evaluate their alternatives. Moreover, conscientious testing is strongly recommended before rolling out a new Windows Server version.

Getting Set Up

Unix operating systems come with a Python runtime in place out of the box. However, Windows Server 2022, which is used in the following examples, does not have Python support. The Python you need is available from the Python website [2]. For this project, I used the 3.11.3 version current at the time of writing and the Windows Installer for 64-bit architectures. For easier handling, it makes sense to let the installation wizard include the Python EXE file in the server's path. Otherwise, you can work with the Install Now option: You do not need to adjust the default settings of the installation wizard. At the end of the installation, you will want to disable the path length limitations and then restart the server to complete the installation.

The Python development team takes care to make the integration of extensions easy. All of the current crop of Python runtimes come with a package manager that is based on the structure of the defaults known from Linux. The pip command can be used in the following, but watch out: As part of the initial execution, Pip offers to update from version 22.3.1 to 23.1.2 (Figure 1). Do not agree to this request under any circumstances if you want to use PyAD, because the library relies on an outdated installation command that no longer works in the new version.

Figure 1: The deprecation warning in Pip is relevant for PyWin32: Avoid the update.

The PyWin32 extension is required to use PyAD. You can install the extension and the PyAD library with

pip install pywin32
pip install PyAD

Previously, it was necessary to download PyWin32 manually because the PyAD development team was a little lacking in the dependencies department. The repository does not have a dependency on PyWin32, so Pip does not install the support library when deploying the Active Directory access module.

First Steps

After restarting the server, you need a work file in PY format. For an initial test, I used the sample program:

import pyad
from pyad import aduser
user = pyad.aduser.ADUser.from_cn("Administrator");
print (user);

ADUser is an AD user object. The method assigned to user fetches the user object from the domain controller (DC) associated with the currently active user account.

The PyAD.set_defaults method can be used to adjust the default settings for connecting to AD instances. It supports configurations that the library implicitly accepts on calls and uses them to establish the connection:

import pyad
from pyad import *
pyad.set_defaults(ldap_server="<DC address>", username="<Account>", password="<Password>")
user = pyad.aduser.ADUser.from_cn ("<user>")

You can also specify settings within the connection setup as follows:

import pyad
from pyad import aduser
user = aduser.ADUser.from_cn ("<user account>", options=dict (ldap_server="<domain controller address>"))

The library supports the ldap_server, gc_server, ldap_ port, gc_port, username, password, and ssl parameters. Note that the data transfer between the Python runtime and AD server is typically encrypted. If you do not want encryption, manually change the SSL value to False.

Managing Users in AD

The returned ADUser object provides insights into the settings applicable to the user account. The class contains methods for editing the account. One good example is determining the age of the password. The user.get_ password_last_set() method returns a date-time object, so now you can send the return value directly to the command line with print. The following two-liner reveals the age of the admin password:

user = pyad.aduser.ADUser.from_cn ("Administrator");
print (user.get_password_ last_set());

You can find more options in the documentation [3]. The set_expiration(dt) method is interesting. It lets you set the password expiration date for users.

Because you are using the PyWin library, standard Python datetime objects are incompatible. Calls therefore fail and output an error message stating TypeError: must be a pywintypes time object (got datetime.date) . However, converting Python data types to PyWin time types is a task that has already been solved [4].

In practice, however, it can be more convenient to create a direct instance of a date-time object instead. The object can be transferred directly afterward:

import time
import pywintypes
from pyad import aduser
now_seconds = time.time ()
now_pytime = pywintypes.Time (now_seconds+60*60*24*2)
user = pyad.aduser.ADUser.from_cn ("Administrator");
print (user.set_expiration( now_pytime));

In the lab, when I tried to set an expiration time for the administrator account, I occasionally saw an error stating A device attached to the system is not functioning.\r\n . The recommendation is to use scripts with exception handling to field any errors caused by PyAD.

PyAD also lets you use new users to AD. In the simplest case, it looks like this:

from pyad import aduser
from pyad import *
ou = pyad.adcontainer.ADContainer.from_dn ("test.tamoggemon.com");
new_user = pyad.aduser.ADUser.create ("<New User>", ou, password="<Password>")
print (new_user)

The method for new_user requires an AD organizational unit (OU) in addition to a username and password. The easiest way to meet these requirements is by typing

PyAD.adcontainer.ADContainer.from_dn

The parameter passed is the distinguished name of the OU container you need to address.

The most important obstacle when running the above script is that the password criteria stored on the Windows server also apply to users entered via PyAD. If the supplied password does not meet these conditions, Active Directory refuses to accept it and outputs an error message. Assuming everything works, you will find the accounts in Active Directory Users and Computers (Figure 2).

Figure 2: Sufficiently complex passwords lead to the display of user accounts created in Python.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus