Administering Active Directory is one of the most critical roles in any Windows network.
Active Directory and PowerShell together offer a powerful set of cmdlets to manage and automate standard domain-related tasks. Here are the most useful cmds.
In this article we'll look at some of the basics of working with Active Directory groups and accounts using PowerShell. You'll learn how to add accounts, delete them and edit their group memberships. We'll also go over how to search around and discover information about those accounts and about the domain itself.
But first, let's start with how to create a test domain to play around with using PowerShell 5 and its default access to the PowerShell Gallery and Desired State Configuration (DSC) resources. This is to ensure that we're playing in a safe environment.
How to create a test domain
Don't worry, these steps are super easy thanks to DSC and the PowerShell Gallery. Start by creating a Windows Server 2012 R2 virtual machine (VM). We'll create ours in Azure, but you can decide where to create yours. Azure makes it easy to isolate VMs into individual networks and not run the risk of doing something on a production network that could make people cranky.
If you're running PowerShell 5 you get access to the PowerShell Gallery by default. If you aren't running Powershell 5 yet, go ahead and download it for your VM from this Microsoft Download Center page. Once it's installed, execute the script below to install the xActiveDirectory module.
After the module is installed, you can use the script from this excellent blog post by Ashley McGlone on how to set up a new Domain Controller from scratch with a single script. Don't forget to tweak the drive letters to match your current environment, and set the domain name to one that you want to use. I changed mine to ADTestDomain.com just because AdamTheAutomator.com is too long for a NetBios name.
Your computer will restart, and when it comes back you will be able to log in with the same username and password you did before. The difference is that this account is now a domain account, not a machine account.
Exploring a domain with PowerShell
To start with, let's get some basic information about our new domain by executing the Get-AdDomain cmdlet.
One of the interesting things we can see in this screen is the DomainMode. The DomainMode has a big influence on some features that will be available, like whether you can use the latest version of Managed Service Accounts. If you didn't set up the domain you're looking around in, it's handy to be able to get this information easily.
PowerShell will tell you anything you want to know about a domain, and to get an idea of what's available we can use the Get-Command cmdlet to show us all of the cmdlets that use the Get verb.
There are 43 Active Directory Get cmdlets in the module, so as you can see you can get a lot of information. One of the first things we are usually going to want to find is information about users. Let's use Get-ADUser to find one.
Uh oh. We've already run into something unexpected. This is an easy fix though. If you think about it, in most domains, we don't really want to return every single user in a domain, so Get-ADUSer always requires some sort of filter whenever you use it. Let's try again.
We can either call Get-ADUser and give it a single user name, or provide a filter to find multiple accounts. Either one will work, but I'll use the filter syntax just so we can see what that looks like.
The filter parameter can target any of the properties you see in that list and will use some of the standard PowerShell comparison operators against the value you enter for the second part of the filter. I say some because not all comparison operators are supported by the –Filter parameter. To see what I mean, execute the following script for a detailed description.
|Get-Help Get-ADUser –Parameter filter|
The properties you see here are in fact only a few of the properties of this object type. If you add the -Properties * parameter you can get a full listing of available properties.
Now that we've seen the filter syntax, you don't always have to type out an entire filter to find a user. You could just call Get-ADUserabertram if you know the specific user you want to look at.
The next thing we might want to find would be groups. Getting groups is just as easy as finding users if you use Get-ADGroup, so let's look at finding a user's group membership instead.
The cmdlet for finding those uses a slightly different name; it's called Get-ADPrincipalGroupMembership. The cmdlet refers to an AD Principal instead of a User because you could be talking about computers just as easily as users. To illustrate, we will find the group memberships of the current computer.
Creating and working with users
To add users to the domain it's easy to use the New-ADUser cmdlet, but let's take advantage of PowerShell's ability to automate things and create lots of users at once and set some properties as well.
First, we'll create a few security groups so we can add the users to them later using the one liner in the screenshot below.
Now we'll add some users with the next script.
As you can see, if we had something like a csv file with users and the groups we wanted to add them to, we could add a lot of users very fast. I did forget something though. If you don't explicitly mark accounts as enabled when you create them, then by default they are disabled.
We will need to use the Set-ADUser cmdlet to enable them, but there's no need to do that one by one. Use a script like the one below to find them and pipe them to Set-ADUser and get them all enabled at once.
That script will get all six of the users we just created and enable them. In a mature domain with lots and lots of users, this kind of filtering and pipelining is a lifesaver, and can make you look like a wizard to your non-PowerShell coworkers.
The last part of the script we used to create our users also added them to security groups. The script didn't return any output so we should check to confirm that it worked the way we expected it to. Use the script below to find one of the groups we thought we were adding users into and make sure it has the users we expect.
To practice disabling accounts let's assume that we know there is some unusual activity happening on the network associated with one of the QA accounts. We can disable accounts one at a time or in groups using the pipeline. Both are shown below.
Now we'll say that it's a few weeks later, and after an investigation Alan is cleared of all charges, but Grace is let go. What we need to do now is delete Grace's account, and re-enable Alan's.
To delete an account we simply use Remove-ADUser and specify the account. Needless to say that if you have lots of accounts to delete this could be powerful, but use caution and make sure you have backups. The script below shows how to delete a single account.
Next, we can re-enable Alan's account we just use the Enable-ADAccount cmdlet.
To practice removing group members let's say we found that our method of adding users to groups was wrong. It's not hard to imagine. We just added every user to every group. The first group we want to fix is the administrators group.
We can remove users one at a time by targeting them individually as shown below.
|Remove-ADGroupMember -Identity testAdministrators -Members ATuringTest|
That works for a few at a time, but this could easily happen to lots of users, and you don't want to remove them each by hand. Instead if we can articulate some blanket statement like "users from either Dev or Test should not be admins, only QA department accounts" then we can express that as a script like the one below.
That script will work but you might notice and wonder why we didn't just pipe the results of the Get-ADUser command directly to Remove-ADGroupMember. The answer has to do with which parameters for that cmdlet will take pipeline input and which ones won't.
If we look at the help information for the cmdlet using Get-Help we will see that the –Members parameter doesn't accept pipeline input, or wildcards for filtering either.
The solution is found in the same Get-Help output where we see that it will accept an array of ADPrinciple Objects as denoted by the [TypeName] notation for its input type.
You can also get this little hint by using your arrow keys to get down to the –Members parameter while the Intellisense menu is up, and the tooltip will give you the input type information just like the screenshot below.
So after all of the shuffling around of users and deleting and adding group memberships, we can check to see who's in what groups by invoking the Get-ADPrincipalGroupMemberships one at a time like this.
|Get-ADPrincipalGroupMembership -Identity ghoppertest|
Since one at a timing user accounts isn't great, we could also get a bunch of account memberships at once.
The problem, as you can see from the output above, is that if we use the pipeline to do this, our output only knows about the groups that are returned by Get-ADPrincipalGroupMemberships, and nothing about which account it's dealing with.
The result is a list of groups with no information about which user caused that group to show up in the listing. For example, TestAdministrators shows up in the listing above only once, but the listing on its own doesn't show us which user is a member of that group, only that there is only one member. To fix that, we can generate a kind of report using the script below.
Now that you're familiar with the basics, check out some of the more advanced topics dealing with Active Directory and PowerShell. You can start with this article on the Hey, Scripting Guy! Blog, which is all about the Active Directory Schema and how to manage it with PowerShell.