Probably the greatest feature I enjoy, and get the most out of, from PowerShell is the pipeline. Because of the pipeline if I can do something for one thing, I can usually do it for 10, 100 or 1000 with no extra work. Managing Active Directory user accounts with PowerShell is a perfect example.

Moving a single user

Let’s say a user has been transferred to another department. Al Fredo, who had been a senior sales manager in the Government Sales department has been promoted to Assistant VP for Sales. In order for his user account to receive all of the executive perks delivered through Group Policy, you need to move is account to the Executive organizational unit.

Now, you could certainly do this manually via Active Directory Users and Computers once you launched the MMC, navigated or found the account and then move it to the new OU. In PowerShell, I would have had this done before you finished loading the MMC. The solution that I’m going to show you is using the Microsoft Active Directory module which many of you already have. Let me step you through the process. I’ll assume you are running at least PowerShell 3.0 so you don’t have to import the module first.

I always find it easiest in these situations to get the objects in question first assuming you know the user’s samAccountname.

PS C:\> get-aduser afredo

get-aduser

get-aduser

You can see in the user’s distinguished name where his user account currently resides. Now to move the user account. You might try looking for help using Set-ADUser or Move-ADUser. Sadly, the former doesn’t work and you won’t find the latter. So ask PowerShell.

PS C:\> get-command -module ActiveDirectory -verb move

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Move-ADDirectoryServer                             ActiveDirectory
Cmdlet          Move-ADDirectoryServerOperationMasterRole          ActiveDirectory
Cmdlet          Move-ADObject                                      ActiveDirectory

The cmdlet to use is a more generic Move-ADObject. Looking at help and examples you discover all you really need, is to specify the distinguished name of the target OU.

PS C:\> get-aduser afredo | move-adobject -targetpath "ou=executive,ou=employees,dc=globomantics,dc=local" -whatif
What if: Performing the operation "Move" on target "CN=Al Fredo,OU=Sales,OU=Sales and Marketing,OU=Departments,OU=Employees,DC=GLOBOMANTICS,DC=local".

Yes, the Move-ADObject cmdlet supports –WhatIf so you can verify your syntax before committing. Although this is still a bit to type, and assumes you know the target distinguished name off the top of your head.

Using a nested pipeline you could simplify the expression.

PS C:\> get-aduser afredo | move-adobject -targetpath (Get-ADOrganizationalUnit -filter "name -eq 'executive'")

I omitted –Whatif to implement the move which I can verify by getting the user account again.

PS C:\> get-aduser afredo | select distinguishedname

distinguishedname
-----------------
CN=Al Fredo,OU=Executive,OU=Employees,DC=GLOBOMANTICS,DC=local

The same technique can now be used across multiple user accounts.

Moving many

Let’s say you need to reorganize and move members of the Customer Service department to a new OU. For the sake of my demonstration, like you, the accounts may be scattered.

get-aduser -filter

get-aduser -filter

Using the same technique it is snap to move all of these accounts with a single command.

PS C:\> get-aduser -filter "department -eq 'Customer Service'" | move-adobject -targetpath (Get-ADOrganizationalUnit -filter "name -eq 'Customer Service'")

By the way, if an account is already in the target destination nothing really happens to it. After giving replication a chance to finish I can verify the moves.

PS C:\> get-aduser -filter * -searchbase (Get-ADOrganizationalUnit -filter "name -eq 'Customer Service'") -property Department,City | Select Name,Department,City

get-aduser -filter  -searchbase

get-aduser -filter  -searchbase

Build your own

Another great advantage to learning a management tool like PowerShell, is that once you have a command working, it doesn’t take that much more effort to turn it into a re-usable tool. Even though there is no Move-ADUser command, you can create your own. Here’s my bare bones function that you can start with.

#requires -version 3.0
#requires -module ActiveDirectory

Function Move-ADuser {

[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Position=0,Mandatory=$True,
HelpMessage="Enter a user's samAccountname",
ValueFromPipeline=$True)]
[ValidateNotNullorEmpty()]
[Alias("samaccountname","name")]
[string]$Username,

[Parameter(Position=1,Mandatory=$True,
HelpMessage="Enter the name of an OU")]
[ValidateNotNullorEmpty()]
[string]$TargetOU,

[switch]$Passthru

)
Begin {
 #get the OU
 Write-Verbose "Getting OU $TargetOU"
 $OU = Get-ADOrganizationalUnit -filter "Name -eq '$TargetOU'"

 #define a hash table of parameters to splat to Move-ADObject
 $moveParams=@{
   TargetPath=$OU
   Identity=$Null
 }
 if ($Passthru) {
    $moveParams.Add("Passthru",$True)
 }
}
Process {
 $User = Get-ADUser -identity $username
 $moveParams.Identity=$User
 Write-Verbose "Moving $username to $($OU.Distinguishedname)"

 Move-ADObject @moveParams
}

End {
 Write-Verbose "Finished moving user accounts"
}

} #end function

The function lacks error handling, support for alternate credentials and comment based help. But it is simple now to move either a single account with either of these two approaches

move-aduser afredo Executive
get-aduser afredo | move-aduser -TargetOU Executive

Or many:

get-aduser -filter "department -eq 'Customer Service'" | move-aduser -TargetOU 'Customer Service'

My function even supports –Whatif. I’ll let you take it from here.

Summary

If you are still managing Active Directory accounts manually, you are spending way too much time in the MMC and not enough time enjoying your job. Next time we’ll look at a similar approach to handle group membership.

8 Comments
  1. Daekwon 9 years ago

    Hello,
    Thanks for the kind and nice explanation.
    I am trying to move multiple users(about 60) to a specific OU but they have no common things such as same team or description. In other words, Jimmy, Zack, and others should be moved.
    In this case, how can I easily move them?

  2. Author

    If you want to move multiple users with a single command you’ll have to find something they have in common. You can could create a compound query if that helps. Worse case, put the account names in a text file and read in the text file to get the user accounts and move them.

  3. Daekwon 9 years ago

    For some who may have the same concern, please use this command.

    Import-csv “C:\filename.csv” | % { Get-ADUser $_. Username | move-ADobject -TargetPath “OU=~”}

  4. Peter Griffiths 9 years ago

    While I am new to Powershell and servers I am familiar with basic commands from a command prompt, batch files and macro programming in Excel. I personally find that powershell commands are really only practical for running scripts etc for the majority of cases. To run a command directly involves researching which command to use, which parameters to apply, substituting in your own organisations namings, and hope you don’t make a typo in the process. For example, I tried to follow your example above. I gave up after 10 minutes (I timed myself) and I am still not sure which bit went wrong. I am studying for my MCSA exam and get very frustrated when the exam question is “what is the quickest way to achieve …” and the answer is a powershell command. When I try to duplicate the command I find it wont work as presented, and needs extra parameters, and I have taken at least 5 minutes by the time I have got it to work, and that is with an answer already presented to me!. For a user who isn’t using a range of powershell commands daily it will be quicker to use a GUI (which is why we moved from DOS to Windows). Having had my complain, there is some incredible things that can be done by scripting, and that is where I see the real benefit of this language.

  5. Eric (FNG) S 8 years ago

    I was able to find specific users form a text file with UPN only them move-ADOobject them to a disabled users OU then I was able to take the same file and set the Protection from accidental deletion, see the code snipet below

    Get-Content c:\temp\userremoval.txt | ForEach {Get-ADUser -filter {userprincipalname -eq $_ }}| Set-ADObject -ProtectedFromAccidentalDeletion:$False -whatif

  6. Richard 8 years ago

    Awesome explanation, very helpful

  7. jore 7 years ago

    Is it possible to use GetADObject to pull an entire OU and move it from one domain (eg., contoso.local) to another (eg., contoso.com) by piping it to Move-ADObject?

  8. Jorge 2 years ago

    I need to move a user from a subdomain to the main domain, is it possible through powershell?

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account