Organizing Active Directory accounts

199 views Asked by At

I am trying to get a script to work that will organize my active directory accounts based off of their display name since all of our accounts have their OU in their name (or a subOU). I am trying to do this with an If statement inside of a ForEach loop in PowerShell. Every time I run it though, it keeps asking me for an identity. Can anyone help me fix this? This is what I have...

Import-Module ActiveDirectory
$OU = "OU=Test, OU=com"
$Test1OU = "OU=Test1, OU=Test, OU=Com"
$Test2OU = "OU=Test2, OU=Test, OU=Com"

$Users = (Get-ADUser -SearchBase $OU -Filter * -Properties samAccountName,DisplayName)
ForEach ($user in $users)
{
If ($($user.DisplayName -like ("*Supply*" -or "*Supplies*"))
{Move-ADObject -Identity $($user.samAccountName -TargetPath $Test1OU}
ElseIf ($($user.DisplayName -like ("*Accounting*" -or "*Accountant*"))
{Move-AdObject -TargetPath $Test2OU}
}
2

There are 2 answers

8
Matt On BEST ANSWER

You are running into a few problems here

  1. Like Vesper said you are not passing anything to Move-ADObject hence the error you are getting
  2. $DisplayNames is not a string array of names but an object with a displayname property. That is what -ExpandProperty parameter is for with Select-Object FYI.
  3. You are pulling all the users but only really want to process certain ones. Instead of -Filter * lets use a more targeted approach.
  4. While it is tempting you cant nest -like conditions like that. If you take "*Supply*" -or "*Supplies*" and type that it will evaluate to true. Same as all non zero length strings.

For what we plan on doing we will not have to address all those issues. We should use the pipeline to help with this. Depending on how many variances you have something like a switch statement might be better which is covered below.

$supplyFilter = 'DisplayName -like "*Supply*" -or DisplayName -like "*Supplies*"'
$accountFilter = 'DisplayName -like "*Accounting*" -or DisplayName -like "*Accountant*"'

Get-ADUser -SearchBase $OU -Filter $supplyFilter -Properties displayName | Move-ADObject -TargetPath $Test1OU
Get-ADUser -SearchBase $OU -Filter $accountFilter -Properties displayName | Move-ADObject -TargetPath $Test2OU

You could get freaky with this and make a custom object in a loop with filter and target pairs so that you don't need to repeat the cmdlet call to each Get-ADuser instance.

$moves = @(
    @{
        Filter = 'DisplayName -like "*Supply*" -or DisplayName -like "*Supplies*"'
        OU = "OU=Test1, OU=Test, OU=Com"  
    },
    @{
        Filter = 'DisplayName -like "*Accounting*" -or DisplayName -like "*Accountant*"'
        OU = "OU=Test2, OU=Test, OU=Com"
    }
) | ForEach-Object{New-Object -TypeName PSCustomObject -Property $_}

ForEach($move in $moves){
    Get-ADUser -SearchBase $OU -Filter $move.Filter -Properties displayName | Move-ADObject -TargetPath $move.OU
}

You should be able to scale into this easily by adding new $moves. This would be cleaner with PowerShell v3.0 but I do not know what version you have.

Using a switch

If you want something closer to what your currently have I would suggest something like this instead then.

$Users = Get-ADUser -SearchBase $OU -Filter * -Properties DisplayName
ForEach ($user in $users){
    switch($user.DisplayName)  {
        ($_ -like "*Supply*" -or $_ -like "*Supplies*"){Move-ADObject -Identity $user -TargetPath $Test1OU}
        ($_ -like "*Accounting*" -or $_ -like "*Accountant*"){Move-ADObject -Identity $user -TargetPath $Test1OU}
    }
}
4
AndyMeFul On

I'm not able to test currently, but this should do the trick:

Import-Module ActiveDirectory

$OU = "OU=Test, OU=com"
$Test1OU = "OU=Test1, OU=Test, OU=Com"
$Test2OU = "OU=Test2, OU=Test, OU=Com"

$users = (Get-ADUser -SearchBase $OU -Filter * -Properties displayName)
foreach ($user in $users)
{
    if ($($user.displayName) -like "*Supply*" -OR $($user.displayName) -like "*Supplies*")){
        Move-ADObject -Identity $user -TargetPath $Test1OU
    }
    elseif ($($user.displayName) -like "*Accounting*" -OR $($user.displayName) -like "*Accountant*")) {
        Move-AdObject -Identity $user -TargetPath $Test2OU
    }
}

I've Added an Identity Parameter to Move-ADObject also i've changed some of the var names to better reflect their content.