Today, I would like to introduce DSADD tool. This is the first tool, from those we got to know, which makes changes in Active Directory database. Its role is new object creation – only (as its name suggest DSADD). Using it, we can create non-existing object(s) in Active Directory but we cannot modify them.
When you have one new user to create then it’s much more simple and faster to do that in Active Directory Users and Computers console. But what if, you have to create many users in short time or new user needs to be added into many groups in Active Directory? Then you may use for that DSADD. That’s really good tool to add many users in very short time. You can also use it to prepare user template for departments in your company as simple script. We will go through both cases in this article.
DSADD like previous tools require appropriate syntax to start working. What parameters we can use with this tool, we can see after reading its help. Some parameters can be ommited because they are not important for new object creation or they are used with default values but some are required to create the object properly. So, first of all, let’s see what parameters are available for DSADD in user context
dsadd user /?
OK, now we will try to create John Doe, new user in wroc/users/it OU in testenv.local domain
for that, we will use the minimum of required parameters in DSADD syntax
dsadd user “CN=John Doe,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -samid jdoe -upn email@example.com -fn John -ln Doe -display “John Doe” -pwd InitialPassword -memberof “CN=gg-it-common,OU=groups,OU=wroc,DC=testenv,DC=local” “CN=gg-it-wroc-common,OU=groups,OU=wroc,DC=testenv,DC=local” -hmdrv P: -hmdir \FS01Privatejdoe -loscr logon.vbs -mustchpwd yes
and we can see that John Doe was created under specified path in Active Directory with predefined attributes
OK, let’s see what these parameters do, step-by-step
- dsadd user – add new user object in AD
- “CN=John Doe,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” – Distinguished Name of new user object (Remember! Each DS Tool always require DN to start working!), DN points what and where must be created.
- -samid jdoe – create user login jdoe
- -upn firstname.lastname@example.org – create User Principle Name
- -fn John – set First Name to John
- -ln Doe – set Last Name (surname) to Doe
- -display “John Doe” – set Display Name to First Name and Last Name
- -pwd InitialPassword – set initial password for user (by default Domain Password Policy doesn’t allow for user creation with blank password)
- -memberof – all groups to which the new user should be added (all groups must be given in Distinguished Name format; you may place as many groups as you need, separate them using <space>)
- -hmdrv P: – set up user’s home drive to P-Drive in AD profile
- -hmdir \FS01Privatejdoe – specify user’s home folder location
- -loscr logon.vbs – assign logon script to user
- -mustchpwd yes – force password change during first logon
That was simple for one user. What if we want to create in the same department many users or what if, we want to have a template for new user, i.e. for IT department? This is also simple but requires from us few changes in a syntax.
Let’s see what we have to do to prepare IT department template for new user:
dsadd user “CN=%1 %2,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -samid %3 -upn %email@example.com -fn %1 -ln %2 -display “%1 %2” -pwd InitialPassword -memberof “CN=gg-it-common,OU=groups,OU=wroc,DC=testenv,DC=local” “CN=gg-it-wroc-common,OU=groups,OU=wroc,DC=testenv,DC=local” -hmdrv P: -hmdir \FS01Private%3 -loscr logon.vbs -mustchpwd yes
save this syntax as batch file with cmd or bat extension (i.e. IT-dept.cmd) and check below explanation how to use that
In command-line type batch file name and put after that three parameters:
- %1 – First Name
- %2 – Last Name
- %3 – user login
that’s all what you need to specify, if you want to create new use for IT department
IT-dept.cmd Ann Smith asmith
and you will see that new user (Ann Smith) was created in wroc/users/it OU
Prepare as many templates as you need for departments in your organization. I know that’s much work to do but this is only one time action, after that you can simply and in short time create new users in your environment.
Now, it’s time for bulk user creation in a domain. That’s also simple. It requires only small changes in previous script (template) and some input file. Let’s see what we can do for that
First of all, we need to prepare a text file with necessary data. It must be flat text file because DS Tools don’t support CSV or other file formats. There are also three arguments necessary
- First Name
- Last Name (surname)
- User login
OK, put these necessary information into notepad and save it on a C-Drive as new-users.txt
after that create new file wher you need to put this modified script content
for /f “tokens=1-3” %%i in (c:new-users.txt) do dsadd user “CN=%%i %%j,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -samid %%k -upn %%firstname.lastname@example.org -fn %%i -ln %%j -display “%%i %%j” -pwd InitialPassword -memberof “CN=gg-it-common,OU=groups,OU=wroc,DC=testenv,DC=local” “CN=gg-it-wroc-common,OU=groups,OU=wroc,DC=testenv,DC=local” -hmdrv P: -hmdir \FS01Private%%k -loscr logon.vbs -mustchpwd yes
and save it with the same place as new-users.txt file (i.e. bulk-it.cmd)
Now, you need to only run this batch file in command-line, all attributes will be pull from text file. You can use other variables convetion in your script. I started using i as the first variable in a syntax but you can simply start using them as you wish even beginning from a. Next letters are in the alphabet order.
and just for verification, let’s see Active Directory Users and Computers console, if these users were created in wroc/users/it OU
Author: Krzysztof Pytko
We know how to use DSQUERY command for context search or for more advanced LDAP query. Now, we will learn how to use DSGET to request object attributes. That command can be used in “standalone” mode or in piped mode with DSQUERY. It works also in read-only mode like previously discussed tool, so we cannot destroy anything in an environment. DSGET is not so powerful as DSQUERY but it’s also good if we want to easily get some object attributes.
For this command, Microsoft defined parameters which can request value from object attributes and we cannot form our own LDAP query. DSGET is limited but still enough for many daily requests in Active Directory management. Let’s see what we can do using it
DSGET has the same contexts like other DS Tools, so we should remember them from previous article. If not, just for short overview: computer, contact, subnet, group, ou, site, server, user, quota, partition.
In this article we will discuss only two of them: user and group
Let’s start with user context. As you remember, to get more detailed help for a context of DS tool, you need to use
<DS Tool name> plus <context name> and </question mark (?)>
dsget user /?
and now, we can see what is possible to get from user object running DSGET query:
I don’t remember if I mentioned it before (if not, that’s good place for that) that DS Tools require Distinguished Name of an object to start query. That’s always the first value which must be given in a syntax!
Let’s start to get some details for “Krzysztof Pytko” user. The user is located in “wroc/users/it” OU under testenv.local domain
for start, we want to get user’s First Name, Last Name and login.
syntax for the query should look like this:
dsget user “CN=Krzysztof Pytko,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -samid -fn -ln
simple, isn’t it? 😉
Now, we will request more information from this user object. Let’s see what will be displayed as an output
dsget user “CN=Krzysztof Pytko,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -samid -upn -fn -ln -display -desc -email -hmdrv -hmdir -loscr -mustchpwd -canchpwd -pwdneverexpires -disabled -acctexpires
Oh, what a mess! How can I read anything from this output? Yes, that’s true. We requested too many attributes and the output is not readable. In this case we can solve that problem by redirecting command’s output to a flat text file. At the end of previous syntax add >c:user-info.txt
dsget user “CN=Krzysztof Pytko,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -samid -upn -fn -ln -display -desc -email -hmdrv -hmdir -loscr -mustchpwd -canchpwd -pwdneverexpires -disabled -acctexpires >c:user-info.txt
Now, open a text file in notepad, disable word-warpping and review the output. It’s much more readable!
Another usage of DSGET in user context is to get all user’s group membership. For that you need to use different parameters. Let’s try to get Krzysztof Pytko group membership
dsget user “CN=Krzysztof Pytko,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -memberof
we can see group membership of Krzysztof Pytko. What if some groups are members of other groups (nested membership)? We don’t see that using only -memberof switch. For that we have to use one more parameter -expand Then all groups membership will be displayed
dsget user “CN=Krzysztof Pytko,OU=it,OU=users,OU=wroc,DC=testenv,DC=local” -memberof -expand
above command returns all groups in which user is a member.
OK, everything looks pretty good but do I have to each time specify Distinguised Name of a user to start query one by one? NO! As you remember, I mentioned about piped mode. By default DSQUERY returns DN of an object. Let’s try to use combination fo DSQUERY and DSGET together
dsquery user -name “Krzysztof Pytko” | dsget user -samid -fn -ln -display
so, we used DSQUERY to search for user object “Krzysztof Pytko” and we received Distinguished Name of that object. Instead of standard display this DN on a screen, we piped it to another command using pipe “|” character. As you noticed in DSGET command Distinguished Name of a user is missing. In this place, tool will use “piped variable” received from previous command and will display requested attribute values (user login, First Name, Last Name and Display Name).
Now, we run the query for all user accounts in a domain
dsquery user -name * -limit 0 | dsget user -samid -fn -ln -display
Accoring to above syntax, we can also use text file with user logins to get their basic user details. Prepare flat text file with user names, each user in separate line and save it on C-Drive as users.txt From command-line run this query
for /f %i in (C:users.txt) do dsquery user -samid %i | dsget user -samid -fn -ln -display
Thanks to this query, you can get only details for some sort of users, not for all users in whole domain.
That’s all about DSGET user context. It’s time to see what we can do using group context.
Actually, there is no big difference between previous context, just only other switches but the same idea. It can be used similarly to user context. I will only show you, how to get all group members and then display their login, First Name, Last Name and Display Name. Let’s try to run this query
dsquery group -name “gg-all-sites-admins” | dsget group -members -expand | dsget user -samid -fn -ln -display
You will receive all users which are members of this group (gg-all-sites-admins)
Author: Krzysztof Pytko
DSQUERY is one of the most powerful tool which can be used to query any existing object within any domain in a forest.
It can be run in one of available method
- standard predefined context (basic query)
- LDAP syntax (more advanced query)
The first one is limited and it’s mostly used with cooperation with other DS Tools. DSQUERY always returns a Distinguished Name of a queried object. That’s the only one purpose of it in any context search. There is no possibility to change any object’s attribute using DSQUERY command. So, don’t worry, you cannot break anything in an environment using it!
You may ask “What’s so great in this tool if it can only return a DN of an object”? At this point the answer in not obvious but for those who used it at least once with other DS commands (i.e. DSGET) it’s one of the greatest tool which simplifies a life. It will become much more clear for us a little bit latter when we use it in “piped” mode.
Let’s check what contexts are available for that command. Each time you want to get help for DSQUERY, run in command-line
and you will receive an output where you can find these contexts:
the last one * (asterisk) is used for more advanced query (using LDAP syntax) which will be discussed in this article latter.
The most frequent used contexts are: computer, user, group and server. We use them almost every day in Active Directory management. Let’s start to see these tools a little bit closer to understand how to get them working.
We start explanation only with user context of DSQUERY tool. The rest works the same way. It’s time to check what we can request using that context. First of all, we will review its help by running in command-line
dsquery user /?
after typing this in command-line, we received all available switches to use in the syntax. This may look scary but don’t worry, we will discuss all necessary parts here. You need only couple of minutes to understend them all.
As each command-line tool, DSQUERY also requires some parameters to start working. There must be given at leat one parameter to start quering Active Directory for object(s). The most basic is -name parameter which meaning is equal to “Name” column in “Active Directory Users and Computers” console
OK, let’s try to run our first syntax of DSQUERY tool in command-line for “Krzysztof Pytko” user-object
dsquery user -name “Krzysztof Pytko”
Why do you put user Full Name in quotas? Because it’s necessary part of syntax, if object name contains a space.
REMEMBER! In each command-line tool, where you need to place an object name containing space, you have to put it within quotas “” to get it working properly!
and after typying that, review an output
Do you remember when I said that DSQUERY tool in context mode always returns Distinguished Name of an object? Now, you see that’s true! An output of typed command syntax is
OK, but this output is not valuable for us. Very few information can be read in this string:
- object common name – CN=Krzysztof Pytko
- Organizational Unit (OU) location of that object – OU=it,OU=users,OU=wroc (wroc/users/it)
- and a domain in which object exists – DC=testenv,DC=local (testenv.local)
what about other attributes? Actually, there is no possibility to get more using context mode of DSQUERY. Once again, as I said, the output is DN of an object. If you want to get more details, you need to use DSQUERY in “piped” mode.
That was the most simple syntax for querying user object in a domain. What if we want to find more users with common search criteria? Then we can use and * (asterisk) charecter which means:
- at the beginning of a syntax – find everything ending with specified string (i.e. -> *Pytko find all users with Pytko string at the end or simply saying, find all users with Pytko surname in the domain)
- at the end of a syntax – find everything beginning with specified string (i.e. -> Krzysztof* find all users starting with Krzysztof string or simply saying, find all users with Krzysztof first name in the domain)
- at the beginning and at the end of a syntax – find everything containing specified string (i.e. -> *Krzysztof* find all users with Krzysztof pattern in a string)
syntax for all users which surname is Pytko
dsquery user -name *Pytko
will return all user objects found in a domain.
OK, what if we want to find all users in a domain? Then instead of typing name to find, put * (asterisk) character
dsquery user -name *
The output will be limited to first 100 found entries (default limit). If you want to really display all users, you need to specify at the end of a command -limit 0 parameter
dsquery user -name * -limit 0
Now, you have listed all users in the domain in which query was run (by default query is performed in a domain from which was initiated).
Another possible way to search users is -samid parameter. Using it, you can query a domain for particular user login
dsquery user -samid iSiek
and like in previous parameter, you can query all user logins with * (asterisk) character
dsquery user -samid * -limit 0
similarly to previous command, you will get all users in the domain
So, let’s try to experiment a liitle bit more with DSQUERY user in your environment. Don’t worry, you cannot destroy anything!
The second usage of DSQUERY is more powerful. You can query for any object attibute and get value from it. For that you need to use generic LDAP queries. To start performing LDAP queries you need to know a DSQUERY syntax and a liitle bit more about object classes and categories.
To start LDAP query you need to use this syntax
dsquery * -filter “&(&(objectClass=objectClass)(objectCategory=objectCategory))” -attr AttributesListToQuery
the most common classes and categories used in LDAP queries are:
- for user object (objectClass=User)(objectCategory=Person)
- for computer object (objectClass=Computer)(objectCategory=Computer)
- for group object (objctClass=Group)(objectCategory=Group)
using this DSQUERY method for getting object attributes, you can get everything what you want. OK, but you can ask, how can I find LDAP attributes to be able to start querying a domain? You have few ways, one of them is to search the Internet and the second is to create sample query to get all set up attributes for the object.
User LDAP attributes you can find here
Group LDAP attributes you can find here
When you check both above links to LDAP attributes, you will be able to get any of them.
Another mentioned method by me is using sample query. Let’s try to do this for user object.
In this example we use existing user login (iSiek) to get all its attributes. We need to know that LDAP attribute for user login is sAMAccountName. When you skip (sAMAccountName=iSiek) in a syntax, you will request all attributes for 100 users in a domain. If you want to do that for all users, remember that you have to add -limit 0 at the end of syntax
Run this query in command-line
dsquery * -filter “&(&(objectClass=User)(objectCategory=Person)(sAMAccountName=iSiek))” -attr *
this query will request all LDAP attributes for iSiek user. Please notice, that each LDAP attribute is on the left side of colon (:) character whereas attrubute’s value is on the righ side of colon (:) character
if you wish to use only few of them, then instead of * character use LDAP attribute name. When you want to get more than one attribute, separate them using <space>
To get only First Name, Last Name and user login use this structure
dsquery * -filter “&(&(objectClass=User)(objectCategory=Person(sAMAccountName=iSiek))” -attr givenName sn sAMAccountName
I hope that this article helped you with basic DSQUERY understanding and now you can practice yourself in your test/production environment. Once again, don’t worry, DSQUERY works in read-only mode and you cannot break anything. Good luck!
Author: Krzysztof Pytko
Many people afraid of using Microsoft DS Tools. They think that those command-line tools are very complicated and difficult to understand and use. This can be true but (in my opinion) only for couple of minutes. After some short time of using them, everything becomes more clear.
I’m big fan of these tools and I will try to explain, how to use them painless 🙂
First of all, to be able to use Microsoft DS Tools, you need to log on into Domain Controller or install Administrative/RSAT Tools on a workstation or a member server from which you want touse them. To install the tools, you need local administrative privileges on a client machine but to use them, you need to be only “Authenticated User” in a domain in which you want to run a query.
DS Tools can cooperate together. That means, you can pipe the output of one command into another. To use pipe, you have to separate two commands with pipe “|” character. Basically, input of one command can be output for another one.
Microsoft DS Tools contain these commands:
- dsquery (to query for existing objects in a domain)
- dsget (to get attributes from existing objects in a domain)
- dsadd (to add new object in a domain)
- dsmod (to modify existing objects in a domain)
- dsmove ( to move existing objects in a domain)
- dsrm (to remove existing objects in a domain)
above commands are available in all editions of Windows Server 2003 and Windows Server 2008/2008 R2.
From Windows Server 2008 we have also few more tools in a package:
- dsac (Active Directory Administrative Center)
- dsacls (to display/modify ACL of existing objects in a domain)
- dsamain (to review AD database backup)
- dsdbutil (to perform AD database management)
- dsmgmt (to manage AD application partitions, FSMO management and metadata cleanup)
For more detailed help of particular command, run
i.e. -> dsquery /?
You will see all available contexts for that command microsoft project online alternative. To get more detailed help for a context, you need to run
<DS-Tool> <context> /?
i.e. -> dsquery user /?
So, you can ask yourself “What are they purpose of usage?”
When you need to get some object details that is difficult to get using standard GUI tools, you can use them, or if you need to get attributes, create/modify many objects in very few steps, then DS Tools come with their help.
So, try to practice with getting help for these commmands and their context, now. We will discuss DS Tools usage in next posts.
Let’s start new frendship, frendship with Microsoft DS Tools! 😀
Author: Krzysztof Pytko
Today, I would like to introduce new feature of DHCP role in Windows Server 2008 R2. This feature is called “Split-Scope“.
This is great improvement in that role for DHCP administrators. In earlier Windows Server versions, administrators needed to calculate by themselves how to split DHCP scope(s) between two DHCP servers for redundancy. In small networks where basic IP addressing scheme was used, that was not big problem. In large networks where VLANs were used and IP addressing scheme was more advanced, that was horrible.
DHCP servers redundancy in many companies is very important and the lowest cost of maintaining them is also crucial. So, DHCP clusters were not an option in many organizations.
Administrators needed to split scope according to their needs or Microsoft DHCP Best practices using one of recommended rules on two separate DHCP servers in a network
- 50/50 (half addresses on one DHCP server and another half on the second server)
- 80/20 (80% addresses on one DHCP server and 20% on the second server)
This required from them making exclusion ranges in scopes on DHCP servers and duplicating reservations on both servers. That was a lot of work to do! Especially, if a network had more than one scope.
When you wanted to check from which DHCP server computer received a lease you had to verify both DHCP servers lease database or run ipconfig /all command on a client to see which DHCP server isssued the lease.
DHCP servers offer leases in the same time and computer could select any of them. Mostly, the first offered lease is accepted but you cannot be sure which server offered it as the first.
From now, you don’t have to worry for all of these “limitations”. When you have both DHCP servers runnig Windows Server 2008 R2, you can simply achieve that using Split-Scope wizard. All necessary calculations will be done automatically. You can forget about making exlusion ranges in each scope on the second DHCP server and you can also forget about duplicating reservations on another server. Everything is done by Split-Scope wizard.
Another new DHCP feature is delay in lease offers. You can set up 1000 miliseconds (1 second) delay for other DHCP server and you can be sure that all of your clients will get lease from the first server.
Let’s start to show, how we can use that wizard. First, you need to install DHCP role on both Windows Server 2008 R2. Now, you can configure a scope on a server.
In this example, I will show you, how to split 192.168.1.0/24 scope between two DHCP servers (DHCP01 and DHCP02)
Log on to DHCP01 and run DHCP management console. Create a scope (if doesn’t exist) or select the existing one which you want to split.
Click right mouse button on selected scope and choose from context menu “Advanced -> Split-Scope”. You will see a wizard which helps you splitting a scope.
On “Additional DHCP Server” screen click “Add server” button and select the second DHCP server to which you want to split the scope
You can search for any DHCP server in your netwok using “Browse” button or select one of discovered from the list below
Now, you need to choose split scheme. You can choose 50/50 or 80/20 (default option) or even your own. To use other option than default, type other values (in percentage) in fields or move scroll-bar in the proper direction to adjust them ad-hoc
As I mentioned earlier, you can set up delay in leases offer to make sure that specified DHCP server will answer delayed and lease will be issued from “primary” server. To set up delay on DHCP02 in “Added DHCP Server” box, type 1000
apply settings by clicking on “Finish” button
verify if everything went well and close wizard
Check “Address pool” on current DHCP server and you will notice that DHCP Split-Scope wizard has done the job for you!
and for test, go to DHCP02 and check if scope is also split there
Notice, that scope on your DHCP02 is deactivated by default. If you wish to use it, you need to activate it first.
That’s all about configuring DHCP Split-Scope wizard.
Author: Krzysztof Pytko
Many times I saw on forums that people ask, how to check current schema version. They want to know if they need to extend it before adding new server OS as Domain Controller. I decided to write this short post about that (yes, I know that in the Internet is many other sites with this topic 🙂 but I wanted to show this my way)
Let’s start. We have few possibilities to check that
- GUI console (ADSI Editor)
- Microsoft DS Tools (dsquery command)
- 3rd party tools (i.e. adfind from Joe Ware)
I will show you how you can check schema version using all of mentioned options
On Windows Server 2003 to be able to run this console (adsiedit.msc) you need to install first Windows Server 2003 Support Tools from the first server installation CD. You can find them in a location of your CD/DVD-ROM drive in SupportTools directory, install suptools.msi file.
Whereas on Windows Server 2008 you need to add “Active Directory Domain Services Tools” from Control Panel -> RSAT -> Role Administration Tools (on a DC these tools are available by default, when you pormote server as Domain Controller, they are installed automatically)
When you have done adding necessary tools to your system, you can start ADSI Editor. To do that in run box type adsiedit.msc and press enter
You should see ADSI Edit, now. To check schema version, select “Schema” well know Naming Context in left pane, expand it and select schema container
Click on it right mouse button and choose “Properties“. In “Attribute Editor” search for objectVersion attibute and check its value. That value is current schema version.
Schema version of
- 13 – Windows 2000 Server
- 30 – Windows Server 2003 (realease 1)
- 31 – Windows Server 2003 R2 (release 2)
- 44 – Windows Server 2008 (release 1)
- 47 – Windows Server 2008 R2 (release 2)
- 51 – Windows Server 8 Developers Preview (new server edition; now only in Developer’s preview for MSDN subscribers)
- 52 – Windows Server 8 Beta (publicly available)
- 56 – Windows Server 2012 (release 1)
- 69 – Windows Server 2012 R2 (release 2)
- 72 – Windows Server Technical Preview (2014)
- 81 – Windows Server Technical Preview 2 (2015)
- 82 – Windows Server 2016 Technical Preview 3 (2015)
- 85 – Windows Server 2016 Technical Preview 4 (2015)
- 87 – Windows Server 2016
Microsoft DS Tools
Another short and also simple method for achiving that are Microsoft DS Tools and to be more specific – dsquery command.
DS Tools are available on each Domain Controller or workstation/server with Administrative/RSAT Tools installed.
To start checking schema version from command-line type
dsquery * “cn=schema,cn=configuration,dc=domain,dc=local” -scope base -attr objectVersion
An output of that command will show you schema version value
3rd party tool ADFIND
This tool is completely free and can be downloaded from http://www.joeware.net/freetools/tools/adfind/index.htm
This is very poweful tool which can be used for other Active Direcrory/LDAP queries, not only for schema version. I learnt using the tool on Experts-Exchange forum from Mike (mkline71) who really knows how to use that :]
When you downloaded ADFIND open command-line and go to folder where it is saved and run this syntax
adfind -sc schver
and that’s all, review its output. You will see everything what you want to know about schema version
Enjoy checking schema version.
Author: Krzysztof Pytko