1

I'm trying to update a user attribute in Active Directory using pyad. This is my code

from pyad import *

pyad.set_defaults(ldap_server="server.domain.local", 
username="admin", password="password")

pyad.adobject.ADObject.update_attribute(self='testuser1', attribute='mail', 
newvalue='my@email.com')

and this is the error i recieve.

Traceback (most recent call last):
 File "c:\Users\Administrator\Desktop\scripts\AD-Edit-user.py", line 12, in 
 <module>
 pyad.adobject.ADObject.update_attribute(self='testuser1', attribute='mail', 
 newvalue='my@email.com')
 File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36-
 32\lib\site-packages\pyad-0.5.20-py3.6.egg\pyad\adobject.py", line 318, in 
 update_attribute
 elif pyadutils.generate_list(newvalue) != self.get_attribute(attribute):
 AttributeError: 'str' object has no attribute 'get_attribute'

This makes me assume that I need to change the attribute type from str to something else. I have verified that mail is the correct attribute name.

I know ldap connection is working because i can create a user using a similar script.

1 Answers1

0

Your problem is how you use pyad. Specifically in this line:

pyad.adobject.ADObject.update_attribute(self='testuser1', attribute='mail', 
newvalue='my@email.com')

if we look at the source of pyad.adobject.ADObject, we can see the following:

def update_attribute(self, attribute, newvalue, no_flush=False):
    """Updates any mutable LDAP attribute for the object. If you are adding or removing
    values from a multi-valued attribute, see append_to_attribute and remove_from_attribute."""
    if newvalue in ((),[],None,''):
        return self.clear_attribute(attribute)
    elif pyadutils.generate_list(newvalue) != self.get_attribute(attribute):
        self._set_attribute(attribute, 2, pyadutils.generate_list(newvalue))
        if not no_flush:
            self._flush()

self here is not a parameter of the function, it is a reference to the class instance. Your call includes self='testuser1' which is str.

Please lookup the documentation on how to use this function / functionality / module, here. You will notice that there is no "self"... other than looking into the source code I am not sure how you got to the conclusion you needed self.

I have no way of testing the following, but this is roughly how it should work:

# first you create an instance of the object, based on 
# the distinguished name of the user object which you 
# want to change
my_ad_object = pyad.adobject.ADObject.from_dn('the_distinguished_name')

# then you call the update_attribute() method on the instance
my_ad_object.update_attribute(attribute='mail', newvalue='my@email.com')
Edwin van Mierlo
  • 2,398
  • 1
  • 10
  • 19
  • Thanks for the response. I originally left self out but got the following message: Traceback (most recent call last): File "c:\Users\Administrator\Desktop\scripts\AD-Edit-user.py", line 12, in pyad.adobject.ADObject.update_attribute(attribute='mail', newvalue='my@email.com') TypeError: update_attribute() missing 1 required positional argument: 'self' – Ben Caldwell Feb 14 '18 at 19:50
  • yes, that is to be expected, as you did not create an instance of the object, please see my updated answer. I could not test this. And I could not find any sample code ... but ran out of time.. good luck. – Edwin van Mierlo Feb 14 '18 at 19:52
  • I'm still getting an error, I haven't had time to look into it but I wanted to come back and say thank you for your help and for the detail in your answer! – Ben Caldwell Feb 15 '18 at 14:54
  • The last error i recieved was due to the DN being wrong I was using ou=users when i should have been using cn=users Thanks again for your help. my_ad_object = pyad.adobject.ADObject.from_dn("cn=testuser1,cn=Users,dc=domain,dc=local") my_ad_object.update_attribute(attribute='mail', newvalue='my@email.com') – Ben Caldwell Feb 23 '18 at 14:32