I went to move some AD objects with PowerShell recently, and realised that I didn’t have any examples to hand. Despite covering AD permission delegation and GPO operations, I’d somehow missed the fairly obvious task of moving and renaming objects!
So this seemed like a good time fix that …
We need to bind to some objects in AD, starting with the Users OU, and a fictional OU for our example, Service Accounts where we will move our objects to.
$root = [adsi]“”
$users = [adsi](“LDAP://cn=users,”+$root.distinguishedName)
$sa = [adsi](“LDAP://ou=Service Accounts,”+$root.distinguishedName)
Now that we have bindings to the directory locations, we need to bind to an account we’d like to move.
$admin = [adsi](“LDAP://cn=Administrator,”+$users.distinguishedName)
The actually moving of an object isn’t made available through the PowerShell wrapper from what I could see. So to achieve this we need to expose the raw .Net methods using psbase.
$admin.psbase | get-member | where-object {$_.Name -eq “MoveTo”}
System.Void MoveTo(DirectoryEntry newParent), System.Void MoveTo(DirectoryEntry newParent, String newName)
I already knew the name of the method we’d need to use MoveTo(), so we used a where-object cmdlet to reduce our output to just what we needed. Looking at the above method, we can see that we can also rename the object by passing a second set of parameters.
Having bound to the Service Accounts OU, and the Administrator account, the only thing left to do is the actual move:
$admin.PSBase.MoveTo($sa)
Something to bear in mind if we want to rename an object, is that we could pass the same DirectoryEntry location as the object current exists in, or a new location. This method won’t update the sAMAccountName attribute.
If you want to change attributes on an object, it’s worth doing this before the move, and the binding becomes invalid. In our example of renaming the account, there’s a couple of attributes worth changing:
$admin.put(“sAMAccountName”, “zNobodyHere”)
$admin.put(“Description”, “Nobody Service Account”)
$admin.put(“userPrincipalName”, “zNobodyHere@leadfollowmove.com”)
$admin.Setinfo()
Renaming, the Administrator account, and keeping it in the Users container:
$admin.PSBase.MoveTo($users, “cn=zNobodyHere”)
Renaming the Administrator account, and moving it to our Service Accounts OU:
$admin.PSBase.MoveTo($sa, “cn=zNobodyHere”)
Alternatively, you could use the Quest AD cmdlets to move or rename. Sometimes, however you don’t always have the tools available that you might like!