Using DSMod to update Active Directory
January 1, 2007 25 Comments
DSMOD foundation course 101
I originally wrote this as an email reply to a colleague’s question about updating many Active Directory objects in one go, and later thought I could write it up “tutorial style”. I still think the DSQuery, DSGet, DSMod functions are underused by even fairly knowledgeable administrators, so here is a beginner’s guide to getting the most of these tools.
This is intended to show the principles for changing many AD objects’ properties in one go. There are lots more clever things you could do with this – like a lot of command line stuff, the principles are very simple but can be strung together to very powerful end results with a bit of thought and a step-by-step logical approach.
Basically, DSMOD allows you to change many (not all) of the AD properties of an object, usually a user, computer or group. This tutorial discusses users specifically, but the principles extend to other objects.
It uses the full canononical name for the object ie “CN=Eliza Doolittle, OU=etc.” but you don’t need to worry about that. The way to use it in practice is by using dsquery to do a “search” (even if this is for only one object) and pipe the returned results to dsmod, where you change one or more properties of that object.
First try something with dsquery:
dsquery user -name Chris* “OU=Building 1, dc=internal,dc=mycompany,dc=co,dc=uk”
This should give you several results for everyone whose common name matches Chris* (* as wildcard as usual, note that this also matches zero characters so *Chris* would also return these same results even though there is nothing in front of the “Chris”, but would also find “John Christopher” if he existed)
We can now find users who match certain criteria. Then we can pass the results straight into dsmod to modify the properties. A simple example:
dsquery user -samid JHC “OU=Building 2, dc=internal,dc=mycompany,dc=co,dc=uk” | dsmod user -tel “555 – 112 233” -u AdminUser -p AdminPassword
translation:
dsquery <object type = user> where <SAM account> = JHC, in the OU …(must be full canononical form) pipe the answer into a
dsmod and modify this <object type = user> <property of object: “telephone number”> to be “555 etc” <using admin account AdminUser> <password APassword>
So, get the CN of this user, then change their telephone number to X. Simple. (By the way your Outlook web access users will love this – they can get at the internal directory securely, just by looking at the properties of a user in the Address Book, then call someone directly. You could claim you spent all weekend typing in these numbers and get the overtime as well, as long as your PHB does not read this!)
For these kinds of changes where there are lots of unique ones I would usually expect to be using some kind of source list and using excel (or whatever you prefer) to parse the bits together into commands, then copy and paste out to notepad (not even bothering to save as CSV, notepad is dumb enough to just take the results regardless). You can paste straight to a command line, but my general recommendation is always write these as batch files, this way they are easier to edit and re-use, and you can keep exact copies of what you have done as change-control records. This is really useful if you screw up and need to undo (ie overwrite) anything, like changing everyone’s phone number to the same thing or something equally daft (I’m admitting nothing at this point!). At least you can see what has been done and know what to change back.
You don’t need a user name and password if you are running the command window with sufficient privileges. I tend to run the command window with my normal account so I include the admin account details in the command for simplicity.
You need quotes around entries if they contain spaces (in the above example this is true for the OU “Building 2” and the telephone number entry. If this was HeadOffice and just the extension number, quotes not required. As far as I can tell, it is all case-INsensitive.
Slightly more advanced example, doing many users at once, let’s say to change user passwords to enable IT staff to set up profiles for them in a new domain during a weekend office move and migration:
dsquery user “OU=Sales,OU=New York,dc=internal,dc=AcmeCorp,dc=com” | dsmod user -pwd ChangeThisNow! -u Admin -p APassword
This would change password of all users in Sales in New York to “ChangeThisNow!”.
Note: the dsquery will return matching objects anywhere in the OU you specify, or further down the OU structure. So, if you start from New York you will get everyone in New York – I would suggest you do it team by team (ish) to avoid changing things like IT staff or service accounts etc.
Having done that you now have everyone that you want with a changed password. On Sunday night you would possibly want to use:
dsquery user “OU=Sales,OU=New York,dc=internal,dc=AcmeCorp,dc=com” -limit 300 | dsmod user -mustchpwd yes
to force them all to change at next login.
You might also want
dsquery user “OU=Sales,OU=New York,dc=internal,dc=AcmeCorp,dc=com” -limit 300 | dsmod user -office “New Building 3”
Note the use of “-limit 300” – default limit is to return 100 results, useful when you are just doing the dsquery on it’s own to make sure you have the syntax correct. If you miss this off it will do the first 100 and stop, so if you expect more results use this switch at a reasonable level (300, 1000, 100000?)
To get useful help files you can just do the usual /?
eg dsmod /?
or dsmod user /?
or dsquery computer /?
I tend to redirect the output to text files for convenience (they are quite detailed).
DSGET is also useful to get the properties in the first place (perhaps to use in Excel to parse a new batch file together), so use “dsquery | dsget ” approach to find eg all SAM ID’s for Sales, or all their email addresses or whatever.
Summary of the most useful (I have found) user properties :
pwd == user password
mustchpwd == force change of password after next logon
tel == telephone number
samid == we know this is domain-unique so it’s a good start point
profile == path to profile *
hmdir == path to home directory *
hmdrv == drive letter for home directory
fn == first name #
ln == last name #
office == Office location, building name, whatever makes sense in your organisation
*The wildcard $username$ can be used to insert the SAM id for the -profile or -hmdir parameter. Note the $, rather than % as you would get in a DOS command using an environmental variable
dsquery user “OU=Sales,OU=New York,dc=internal,dc=AcmeCorp,dc=com” | dsmod user -hmdir \\internal\DfsRoot\homes\$username$ -hmdrv u:
#eg I will use dsget to do an export of samid, lastname and firstname, then in Excel strip the first initial of the first name and use it with surname to lookup this against the telephone list supplied by the Facilities / reception team which only has surname.initial. From there I can create the script to change the telephone number entries. What I would probably do in practice is change ALL New York user telephone numbers to “unknown”, then change the ones my script can match perfectly, then we can do a query for all users whose telephone number is still “unknown” and do these by hand (eg where their first name Elizabeth is in the phone system as “B” for Beth, and for spelling errors etc.)
Very frustrating thing to watch out for, the syntax and names for the properties in dsquery, dsget and dsmod are not identical, eg in dsquery there is no syntax to search for first name alone, you have to use a wildcard-based mask, but having found them you can’t write directly back to the name, you have to write to first name, surname or display name as required. This is another reason to use batch files – when it doesn’t work because the syntax is wrong you can more easily change it and re-run.
Have fun! (?) I would reckon the amount of time you spend learning this just for any one-off exercise of changing all the passwords or telephone numbers will pay for itself straight away. You then get to reap more rewards down the line for free!
Very useful page – thanks.
Do you have a method where you can get the computer name if you only have the user name? Preferably on screen.
Also I’m looking to populate the Computer Description with the users name (different problem to the above) – is this possible?
Thanks again,
Laurence
$username$ won’t work if a $ appears somewhere else in the parameter
Pingback: Some helpful links for security checking! « rdpetti
Gab is right.. Any solution except renaming folder structure? (For example from \\server\userdata$\$username$ to \\server\userdata\$username$ ?
The approach I would probably take would be to use dsquery | dsget to get a list of the usernames and redirect the output to a text file (check them on screen first, then re-use the command with the redirect on the end) eg:
dsquery user "OU=SomeOU,OU=RootOU,DC=MyDomain,DC=local" | dsget user -samid > c:\temp\SAMlist.txtOpen the list in Excel or some other spreadsheet tool and delete any rows you don’t want to affect eg user templates or service accounts (hopefully they would be in a different OU anyway). Use a formula to construct the commands you need to do the modification without a wildcard for $username$, eg in cell B1 use:
="dsquery user -samid "&A1&" |dsmod user -hmdir "\\server\userdata$\"&A1Copy the formula all the way to the bottom so you have a unique line for each username. Copy and paste this into Notepad, save as a .cmd (or .bat if you prefer). Run this and every user gets updated.
Of course you can refine the dsquery to only include certain users, or add more fields to the dsget to help you identify the right sets of users for each folder path you need, such as -office or -desc
Not a direct way of doing it, but not too longwinded, certainly compared to doing them by hand.
Yes, I agree.. This is the way I was going to use but only wanted to know if anyone knows a better solution (like using quotation marks or whatever).. Anyway, thanks for the responce.
Hi, is it possible to change the telephone number using DSMOD, I have a list of users that need to be updated so would like to use a CSV to do this.
Open your csv in Excel and use a simple formula to construct a dsquery / dsmod around the user names (see above comment for an example). Depending on your data you may need to translate the names you have into samids (eg using first initial plus surname). Otherwise use -name and their full name in quotes: dsquery user -name “Eliza Doolittle”
pipe this to a dsmod user -tel.
To get the double quotes in the result you will need triple double-quotes in the middle, so overall you might have a formula in C1 downwards:
=”dsquery user -name “”” &A1& “”” |dsmod user -tel “””&B1&””””
Copy all of column C and simply paste into Notepad, save as a cmd file and run it.
Thanks, I seem to get an error message DSMOD failed: ‘target object for this command’ is missing..
C:\>dsquery user -name “””username””” “OU=Systems,OU=Production,DC=XXXX,DC=XXXXX,DC=com” |dsmod user -tel “XXXX” -u XXX -p XXX
Run the dsquery on its own to see any errors.
Make sure you don’t actually have curly quotes in your command line (or in your Excel formula). I am assuming you are substituting “username” with a user’s full name. If you want to use their logon id, use -samid instead of -name and eg “elizad1” instead of “Eliza Doolittle”
Note also that the -u and -p parameters will be per command, so if you don’t have admin rights to read the objects from that OU, you may need to do this for the dsquery part as well as for dsmod.
thanks, there are no errors on the DSQUERY, seems to be the DSMOD, the users are in a sub ou called system in the prod OU
Also another thought – are your user accounts in the OU called Production\Systems ? or does that have the computer accounts in?
So dsquery brings back a FQDN for a given user? But dsmod claims there is no target for the command? what happens if you use the returned value explicitly (ie copy and paste it in)?
I wonder if there is an issue using a pipe to pass the result of the dsquery if you are running dsquery and dsmod as different user accounts (as you are).
You might be better off using runas to run a command line window with the required user account to get (domain) admin privileges, then run dsquery and dsmod without -u or -p options.
What I’m doing at the min is throwing these commands into a dos window (as domain admin) on a w2k8R2 server. its driving me crazy, as it looks like there is a tiny syntax error..grr.
I tried this command :
DSQUERY USER -name “””myusername””” | DSGET USER -samid and get the following :
dsget failed:’Target object for this command’ is missing.
What about just:
dsquery user -name “Your Name”
or
dsquery user -samid “yourlogonname”
You need to use name or samid depending on whether you are feeding it a user’s full name or logon account name.
One of these should return a FQDN for a user, the other will not fail in the sense of an error message but will not return any results.
It works now! <B you are a genius. pint of virtual Guinness heading your way.
Glad you finally got it sorted!
opps almost forgot the command I used was
dsquery user -samid “me” “OU=Systems,OU=Production Services,DC=xxxx,DC=xxxx,DC=com” | dsmod user -tel “xxxx” -u xxxxx -p xxxxx
It was a typo! I never put in Services..!
Nice little tutorial.
Question – I am using dsmod in conjunciton with dsquery to change the location of a bunch of Computers to their relevant departments, all good. BUT…
dsquery doesn’t work to query on locaiton, in fact I can find no tool which will let me query by location…
Wouldn’t it be nice if you could post to Department (a searchable field) rather than location…?
Thank you so much for this! The DSMOD command is amazing. I have been pulling what few hairs I have left out, trying to write vbcode to get the list of members in a group and then update their email addresses to match their name. Now I ended up with one easily scriptable line:
dsquery group -name “mygroup” | dsget group -members -expand | dsmod user -email $username$@myschool.edu
Mark, I’m very glad this old post helped you out, and thanks for sharing your command for others to see you far you can take this using the right pipes.
Thanks a lot for this article.
I’ve resolve my AD modification script issue!
How do I modify an existing group(s) – particularly the Managedby and Description in AD?
been trying to work with Powershell but i keep on receiving errors, really need to have it done the sooner so I am considering different options.
Thanks in Advance!
LOL, this thread is still going, 9 years later!
I don’t think you can update the “ManagedBy” attribute in a group using DSMOD. You can add and remove users from a group easily, but I’ve never read about a way to change the “ManagedBy ” attibute.
updating the description is easy:
dsmod group -desc
example:
dsmod group “CN=TestGroup,OU=Group Accounts,DC=xxxxx” -desc “Test Group”
remember you must be using an account with the necessary permissions or use the “-u” option to connect as a different user