Hey, Scripting Guy! How Can I Move a Group from One Organizational Unit to Another?

<?xml:namespace prefix = v ns = “urn:schemas-microsoft-com:vml” />
<?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />

Hey, Scripting Guy! Question

Hey Scripting Guy! I need to be able to move a group from one organizational unit to another. The problem is that our network has thousands of groups and organizational units. What I need is a way to easily find the group and the organizational unit. After the group and the organizational unit have been found, it would be great if the script would pass the path to the group and to the organizational unit to the code that is used to move the group. If it did that, it would be great because I would not need to copy and paste the path to the objects. Is this possible?

– OS

 

 

 

Hey, Scripting Guy! Answer

Hello OS,

With Windows PowerShell it seems that most things you need to do on your computer are possible to automate. At times the question might be how badly you want to write the script, but generally there are few things that are impossible to do. Luckily, this is not one of the nearly impossible tasks. However, it does involve two separate tasks. The first task is searching Active Directory, and the second is moving objects in Active Directory. The thing that might be confusing is that neither of these scripts looks much like its VBScript counterpart. A VBScript that moves an object in Active Directory uses the movehere method, while a VBScript that searches for groups in Active Directory uses ActiveX Data Objects (ADO). In Windows PowerShell, the techniques that are used are a bit more straightforward.

I decided to write the SearchForGroupMoveToOU.ps1 script to illustrate how to search Active Directory for a group and then move it to a different organizational unit. The SearchForGroupMoveToOU.ps1 script uses command-line arguments to simplify the process of running the script. The complete SearchForGroupMoveToOU.ps1 script is seen here.

SearchForGroupMoveToOU.ps1

Param(
  [string]$group,
  [string]$ou,
  [switch]$help,
  [switch]$whatif
) #end param

Function Get-AdObject($class,$name)
{
 $ds= New-Object System.DirectoryServices.DirectorySearcher
 $ds.filter = “(&(objectcategory=$class)(name=$name))”
 $ds.findall()
} #end function Get-AdObject

Function Move-AdGroup($group, $ou)
{
 $de = $group.GetDirectoryEntry()
 $destination = $ou.path
 $de.psbase.MoveTo($destination)
} #end function Move-AdGroup

Function Get-ScriptHelp
{
  “SearchForGroupMoveToOu.ps1 -group testGroup1 -ou students”
  “SearchForGroupMoveToOu.ps1 -group testGroup1 -ou students -whatif”
} #end function Get-ScriptHelp

Function Get-Whatif($group,$ou)
{
  “WHATIF: Moving group $group to ou $ou”
} #end function Get-Whatif

# *** Entry Point to Script ***
if($help) { Get-ScriptHelp ; exit }
if(-not($group -and $ou)) { throw “missing group name or ou name” }
if($whatif) { Get-Whatif -group $group -ou $ou ; exit }

$groupDE = Get-AdObject -class group -name $group
$ouDE = Get-AdObject -class organizationalUnit -name $ou
Move-AdGroup -group $groupDE -ou $ouDE

To move a group to a different organizational unit, you can use the Active Directory Users and Computers Microsoft Management Console, which is seen here:

Image of the Active Directory Users and Computers MMC

If you have more than one group that needs to be moved, it makes sense to create a script to perform the task. The first thing that must be done in the SearchForGroupMoveToOU.ps1 script is to create the command-line parameters. This will allow you to run the script without needing to edit it. The script uses two strings: the name of the group and the name of the organizational unit to which the group will be moved. The help switched parameter is used to provide help for the script. The whatif switched parameter is used to indicate what the script will do before it moves the group to the destination organizational unit. The command-line parameters are seen here:

Param(
  [string]$group,
  [string]$ou,
  [switch]$help,
  [switch]$whatif
) #end param

The first function to create is the Get-AdObject function, which is used to search for an object by name. By searching for an object by name you do not need to know the exact location of an object. This is helpful in large networks where you could have hundreds or even thousands of organizational units. You might not always know which organizational unit an object resides in. The Get-AdObject function requires two input parameters. The first is the type of object to search for, and the second is the name of the object. In the SearchForGroupMoveToOU.ps1 script, the Get-AdObject function is used to search for organizational units and groups. But it could be used in other scripts to search for users, printers, folders, computers, or any other object you could store in Active Directory. The function declaration is seen here:

Function Get-AdObject($class,$name)
{

After you have created the parameters for the Get-AdObject function, it is time to create an instance of the System.DirectoryServices.DirectorySearcher .NET Framework class. The returned DirectorySearcher is stored in the $ds variable. The DirectorySearcher has an overloaded constructor, which means the DirectorySearcher can be created in many different configurations. These different constructors are seen in Table 1.

Table 1

Name

Description

 DirectorySearcher()

Initializes a new instance of the DirectorySearcher class with default values.

 DirectorySearcher(DirectoryEntry)

Initializes a new instance of the DirectorySearcher class using the specified search root.

 DirectorySearcher(String)

Initializes a new instance of the DirectorySearcher class with the specified search filter. 

 DirectorySearcher(DirectoryEntry, String)

Initializes a new instance of the DirectorySearcher class with the specified search root and search filter. 

 DirectorySearcher(String, String[ ])

Initializes a new instance of the DirectorySearcher class with the specified search filter and properties to retrieve. 

 DirectorySearcher(DirectoryEntry, String, String[ ])

Initializes a new instance of the DirectorySearcher class with the specified search root, search filter, and properties to retrieve.

 DirectorySearcher(String, String[ ], SearchScope)

Initializes a new instance of the DirectorySearcher class with the specified search filter, properties to retrieve, and search scope. 

 DirectorySearcher(DirectoryEntry, String, String[ ], SearchScope)

Initializes a new instance of the