Search code examples
powershellmoveaccountou

How to dynamically move computer accounts from Computers OU


Its pretty "simple" what i want to achieve. I have people creating Computer Objects on my AD and leaving there without moving them to the appropiate OU.

I would like a powershell script to read the list of computers from the Computers OU, and depending the first 5 or 6 letters from the Computer name, move it to the appropiate OU, reading the list of destination OUs from a CSV or txt or whatever file type.

I need to move more than 100 computers and I would like to scan them, and move them to their corresponding OU.

I've thought to use a variable for the computer accounts, then a foreach and a switch or something similar, and 1-by-1 start moving the accounts. But I'm stuck.

Thank you!!!!


Solution

  • Turning my comment into an answer. You could create a lookup Hashtable for this:

    # create a lookup Hashtable for all OU's in your organisation
    # You can limit this using parameters like '-SearchScope' and '-SearchBase' depending on the structure in your AD environment
    $allOUs = @{}
    Get-ADOrganizationalUnit -Filter 'Name -like "*"' | ForEach-Object {
        $allOUs[$_.Name] = $_.DistinguishedName 
    }
    
    # next, get all computers in the default Computers OU
    $result = Get-ADComputer -Filter * -SearchBase "CN=Computers,DC=Contoso,DC=com" | ForEach-Object {
        $computerName = $_.Name
        $found = $false
        if ($computerName.Length -ge 6) {
            $targetOU = $computerName.Substring(0,6)
            $found    = $allOUs.ContainsKey($targetOU)
        }
        if (!$found -and $computerName.Length -ge 5) {
            $targetOU = $computerName.Substring(0,5)
            $found    = $allOUs.ContainsKey($targetOU)
        }
        if ($found) {
            try {
                $_ | Move-ADObject -TargetPath $allOUs[$targetOU] -ErrorAction Stop -WhatIf
                # add success to the $result
                [PsCustomObject]@{
                    'Computer' = $computerName
                    'TargetOU' = $targetOU
                    'Result'   = 'Moved'
                }
            }
            catch {
                # add exception to the $result
                [PsCustomObject]@{
                    'Computer' = $computerName
                    'TargetOU' = $targetOU
                    'Result'   = 'Not moved. {0}' -f $_.Exception.Message
                }
            }
        }
        else {
            # add failure to the $result
            [PsCustomObject]@{
                'Computer' = $computerName
                'TargetOU' = ''
                'Result'   = 'Not moved. Computername does not begin with a valid OU name'
            }
        }
    }
    
    # output on screen
    $result
    
    # output to file
    $result | Export-Csv -Path 'ComputersMoved.CSV' -NoTypeInformation
    

    Remove the -WhatIf switch if you are satisfied with the results shown in the console.