Computers are commonly moved between OUs to apply GPOs, enforce delegated administration, organize AD objects, or control sync scope. In hybrid environments, however, not every device management or security policy requires an OU: Microsoft Entra groups, Intune policies, and device filters can provide separate management scopes.
Note. OUs are still important for on-premises AD administration, GPOs, delegation, and some sync cases. In Microsoft Entra and Intune environments, however, you should use Entra groups, dynamic membership, device filters, or Intune assignments when they provide the required management scope. Do not move a computer between OUs solely to control an Intune policy unless the OU is actually part of the required sync/management design.
Our guide explains how to move a computer account from the default container to any other Organizational Unit (OU) using the ADUC graphical snap-ins, or PowerShell (including single, bulk, and cross-domain move operations).
How to Move Computer Objects Using the ADUC GUI
Active Directory Users and Computers (ADUC) is a standard graphical tool for managing computer accounts and moving them between OUs. It is useful for interactive administration, while PowerShell is better suited for repeatable and bulk operations.
- To open the ADUC snap-in, press WIN+R and run dsa.msc.

- Expand the domain root and select the Computers container (if the source container is different, locate the OU manually).
- Find the computer object(s) you want to move. If there are multiple computers to move, you can select them with CTRL+Click. Then right-click and select Move.

- Select the target OU to which you want to move the object(s) and click OK.

In the end you may need to refresh a Group Policy on the machine with gpupdate /force command or restart it (depending on the policies applied in the target OU).
Moving Computer Accounts to a Different OU with PowerShell
To move computers between OUs, you can use the Move-ADObject cmdlet (requires the PowerShell Active Directory module installed). It allows you to move an Active Directory object or a container to a different OU/domain within the same forest.
Using the Move-ADObject Cmdlet in PowerShell
To move a computer, you can use the Get-ADComputer cmdlet in order to find it and specify the DistinguishedName of the target OU. Here is an example:
$Computer = Get-ADComputer -Identity "NY-WSK2132" -ErrorAction Stop
Move-ADObject `
-Identity $Computer.DistinguishedName `
-TargetPath "OU=Computers,OU=NewYork,OU=US,DC=theitbros,DC=com" `
-ErrorAction Stop

Now you need to check if the computer object was moved successfully. You can do this by checking its DistinguishedName attribute:
Get-ADComputer NY-WSK2132 -Properties DistinguishedName |
Select-Object Name, DistinguishedName
If the source computer is protected from deletion, an Access is denied error will appear when trying to move it to a different OU:

In order to display the Object tab in Active Directory Users and Computers (ADUC), open the View menu and enable Advanced Features. Then you need to open the computer object’s properties and select the Object tab. Clear Protect object from accidental deletion only if necessary to perform the move.
To allow move the computer, either uncheck the Protect object from accidental deletion in the object properties in the ADUC console or use this PowerShell command:
Get-ADComputer WKS1101 |Set-ADObject -ProtectedFromAccidentalDeletion:$false

After moving the computer object, you need to restore its original protection state if it was enabled before the move. You should not enable protection unconditionally, because the object may not have been protected originally.ย For example, in case you temporarily disabled protection on a machine that was previously protected, run the following:
Set-ADObject -Identity "CN=WKS1101,OU=Computers,DC=theitbros,DC=com" `
-ProtectedFromAccidentalDeletion $true
Don’t forget to replace the distinguished name with the computer object’s current DN after the move.
Moving Computers Across Domains with PowerShell
A cross-domain move requires appropriate permissions in both the source and target domains. Enterprise Admin membership can provide the required access, but delegated permissions are preferred in environments that follow the least-privilege model.
In case you are performing a cross-domain move within the same AD forest, you need to specify the source and target DCs using -Server and -TargetServer. Note that -Server must identify the RID Master DC in the source domain, and -TargetServer must identify the RID Master domain controller in the target domain. Both servers must be specified using fully qualified domain names (FQDNs). You need to check the RID Master role holders before running the operation.
Get-ADComputer -Identity PC001 -Server "SourceDC.SourceDomain.tld" | `
Move-ADObject `
-TargetPath "OU=Computers,DC=TargetDomain,DC=tld" `
-TargetServer "TargetDC.TargetDomain.tld" `
-Server "SourceDC.SourceDomain.tld"
Here are important prerequisites for cross-domain moves:
- Both the source and target domains must belong to the same AD forest
- DCs holding the RID Master role must be available in both domains during the operation
- For cross-domain moves, you also need appropriate permissions in both domains. The object receives a new SID in the target domain, while the previous SID is preserved in sIDHistory. Cross-forest migrations donโt work that way โ you need a different migration method.
For supported migration cases, see the Microsoft’s Active Directory Migration Tool (ADMT) guidance.
Bulk Move AD Computers to Another OU with PowerShell
The most effective way to bulk move computers to another OU is to use PowerShell console: moving multiple objects in bulk in AD can easily be automated using it.
Move Computers Between OUs Based on TXT File
Prepare a plain TXT file containing a list of AD computer names if you want to bulk move to another OU (for example, file computers.txt).

Next, define the target OU:
$TargetOU = "OU=Servers,OU=London,OU=UK,DC=theitbros,DC=com"
Also note that before running bulk operations, you should check if the target Organizational Unit exists in AD:
if ([string]::IsNullOrWhiteSpace($TargetOU)) {
throw "Target OU is empty."
}
try {
Get-ADOrganizationalUnit -Identity $TargetOU -ErrorAction Stop | Out-Null
}
catch {
throw "Target OU does not exist: $TargetOU"
} Import the computer names from the computers.txt file into the $ADComputers variable:
$ADComputers = Get-Content .\computers.txt |
ForEach-Object { $_.Trim() } |
Where-Object { $_ }
Before running the bulk move, use -WhatIf to preview the changes:
Review the output and verify that the correct computers and target OU are listed. Keep in mind that WhatIf does not modify any objects!
foreach ($computerName in $ADComputers) {
Get-ADComputer -Identity $computerName |
Move-ADObject -TargetPath $TargetOU -WhatIf
} Finally, run this PowerShell script to move the computers in bulk:
foreach ($computerName in $ADComputers) {
try {
$currentComputer = Get-ADComputer `
-Identity $computerName `
-ErrorAction Stop
Move-ADObject `
-Identity $currentComputer.DistinguishedName `
-TargetPath $TargetOU `
-ErrorAction Stop
"OKAY: Moved $computerName to $TargetOU"
}
catch {
"FAIL: $computerName - $($_.Exception.Message)"
}
} Limitations of our basic bulk-move script. This is a basic example for straightforward bulk moves. Keep in mind that it does not create a backup CSV of the computers’ original locations or write an operation log to a file. In case a move fails or the machines need to be returned to their original OUs, you must identify the affected accounts and restore their locations manually. For production environments, use the Move-ADComputersSafe.ps1 script in the next section of our article.
Our script uses error handling to catch failures when retrieving a computer account or moving it to the target OU. In case a computer account cannot be found or the move fails, the error is caught and reported in the output. The script returns a success/failure status for each machine.

Bulk Computers Move Based on Their Hostnames
Many companies use strict naming conventions for computer hostnames in AD, depending on their organizational/territorial location. For example, we always use the prefix ‘wks-la’ for computers in the ‘Los Angeles’ OU (e.g. wks-la21).

The following PowerShell script finds computer accounts matching the wks-la naming pattern in the Workstations OU and its sub-OUs. It records each machine’s original location in a timestamped CSV file and previews the planned moves by default.
Note that the script does not automatically change the Protect from accidental deletion setting. In case a protected machine cannot be moved, the operation is recorded as FAILED, and the error is included in the results CSV. You should review these failures individually rather than disabling protection for all selected objects.
Note that our script supports two modes: previewing the changes without modifying AD and executing the moves after explicit confirmation. It also verifies each move and records the result for troubleshooting/rollback.
Save the code below as Move-ADComputersSafe.ps1. After that, run it from a machine with the Active Directory PowerShell module installed, using an account that has permission to move the selected computer objects and write to the output directory:
Scope and DC selection. Our script is designed to move computer objects between OUs within the same AD domain. It does not implement cross-domain computer migration. Unless a DC is explicitly specified with the -Server parameter, the AD PowerShell cmdlets select a DC automatically. Do not assume that the script always uses the PDC Emulator. For predictable behavior, you need to specify the intended writable DC with -Server and use the same DC consistently for the operations performed by the script.
#Requires -Modules ActiveDirectory
<#
.SYNOPSIS
Safe bulk move of AD computer accounts with backup, dry-run and rollback-compatible CSV.
.EXAMPLE
# From TXT (dry-run by default)
.\Move-ADComputersSafe.ps1 -TargetOU "OU=Servers,OU=London,DC=contoso,DC=com" -ListPath .\computers.txt
# By name pattern
.\Move-ADComputersSafe.ps1 -TargetOU "OU=Computers,OU=LA,DC=contoso,DC=com" `
-SearchBase "OU=Workstations,DC=contoso,DC=com" -NameLike "wks-la*"
# Via Out-GridView (interactive session only)
.\Move-ADComputersSafe.ps1 -TargetOU "OU=Computers,OU=LA,DC=contoso,DC=com" `
-SearchBase "OU=Workstations,DC=contoso,DC=com" -Grid
# Real run
.\Move-ADComputersSafe.ps1 -TargetOU "..." -ListPath .\computers.txt -Execute
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$TargetOU,
[string]$ListPath,
[string]$SearchBase,
[string]$NameLike,
[switch]$Grid,
[switch]$Execute,
[string]$Server,
[string]$OutDir = '.'
)
$ErrorActionPreference = 'Stop'
function Get-ParentDN {
param([Parameter(Mandatory)][string]$DN)
# Removes the first RDN and correctly handles escaped commas (\,)
$parent = $DN -replace '^(?:\\.|[^\\,])+,', ''
if ($parent -eq $DN) { throw "Cannot determine parent DN: $DN" }
$parent
}
# --- Validate input mode -------------------------------------------------
$modes = @(
[bool]$ListPath,
([bool]$SearchBase -and [bool]$NameLike),
([bool]$SearchBase -and $Grid.IsPresent)
) | Where-Object { $_ }
if ($modes.Count -ne 1) {
throw "Specify exactly one mode: -ListPath | -SearchBase with -NameLike | -SearchBase with -Grid"
}
if (-not $Server) { $Server = (Get-ADDomain).PDCEmulator }
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$backupPath = Join-Path $OutDir "move-backup-$stamp.csv"
$resultPath = Join-Path $OutDir "move-result-$stamp.csv"
# --- Validate target OU --------------------------------------------------
try {
$targetObj = Get-ADOrganizationalUnit -Identity $TargetOU -Server $Server
$TargetOU = $targetObj.DistinguishedName # normalized DN
}
catch { throw "Target OU does not exist or is not accessible: $TargetOU" }
# --- Collect computers ---------------------------------------------------
$props = @('DistinguishedName', 'ObjectGUID')
$computers = @()
if ($ListPath) {
if (-not (Test-Path -LiteralPath $ListPath -PathType Leaf)) { throw "File not found: $ListPath" }
$names = Get-Content -LiteralPath $ListPath |
ForEach-Object { $_.Trim() } | Where-Object { $_ } | Select-Object -Unique
$missing = @()
foreach ($n in $names) {
try { $computers += Get-ADComputer -Identity $n -Server $Server -Properties $props }
catch { $missing += $n }
}
if ($missing.Count -gt 0) {
throw "Computers not found in AD ($($missing.Count)): $($missing -join ', '). Fix the list and rerun."
}
}
elseif ($NameLike) {
$computers = @(Get-ADComputer -SearchBase $SearchBase -SearchScope Subtree `
-Filter { Name -like $NameLike } -Server $Server -Properties $props)
}
else {
$computers = @(
Get-ADComputer -SearchBase $SearchBase -SearchScope Subtree -Filter * `
-Server $Server -Properties $props |
Select-Object Name, DistinguishedName, ObjectGUID |
Sort-Object Name |
Out-GridView -PassThru -Title "Select computers to move"
) | ForEach-Object { Get-ADComputer -Identity $_.ObjectGUID -Server $Server -Properties $props }
}
# --- Build plan (skip objects already directly in the target OU) --------
$plan = foreach ($c in $computers) {
$parent = Get-ParentDN $c.DistinguishedName
if ($parent -ieq $TargetOU) { continue }
[pscustomobject]@{
Name = $c.Name
ObjectGUID = [string]$c.ObjectGUID
OriginalDN = $c.DistinguishedName
OriginalParentDN = $parent
}
}
$plan = @($plan)
if ($plan.Count -eq 0) { Write-Warning "Nothing to move."; return }
# --- Backup BEFORE any change -------------------------------------------
$plan | Export-Csv -LiteralPath $backupPath -NoTypeInformation -Encoding UTF8
if (-not (Test-Path -LiteralPath $backupPath)) { throw "Backup was not created. Aborting." }
$plan | Format-Table Name, OriginalParentDN -AutoSize
Write-Host "Computers to move : $($plan.Count)"
Write-Host "Target OU : $TargetOU"
Write-Host "Server : $Server"
Write-Host "Mode : $(if ($Execute) { 'LIVE' } else { 'DRY-RUN' })"
Write-Host "Backup : $backupPath"
if ($Execute) {
$confirm = Read-Host "Type MOVE to perform these changes"
if ($confirm -cne 'MOVE') { Write-Host "Cancelled. Nothing was moved."; return }
}
# --- Execute / dry-run ---------------------------------------------------
$results = foreach ($p in $plan) {
$row = [ordered]@{
Name = $p.Name
ObjectGUID = $p.ObjectGUID
OriginalDN = $p.OriginalDN
OriginalParentDN = $p.OriginalParentDN
CurrentDN = ''
Status = ''
Error = ''
}
try {
if (-not $Execute) {
Move-ADObject -Identity ([guid]$p.ObjectGUID) -TargetPath $TargetOU `
-Server $Server -WhatIf
$row.CurrentDN = $p.OriginalDN
$row.Status = 'DRY-RUN'
}
else {
Move-ADObject -Identity ([guid]$p.ObjectGUID) -TargetPath $TargetOU -Server $Server
$moved = Get-ADComputer -Identity ([guid]$p.ObjectGUID) -Server $Server `
-Properties DistinguishedName
if ((Get-ParentDN $moved.DistinguishedName) -ine $TargetOU) {
throw "Post-move verification failed: $($moved.DistinguishedName)"
}
$row.CurrentDN = $moved.DistinguishedName
$row.Status = 'MOVED'
}
}
catch {
$row.Status = 'FAILED'
$row.Error = $_.Exception.Message
}
[pscustomobject]$row
}
$results | Export-Csv -LiteralPath $resultPath -NoTypeInformation -Encoding UTF8
$results | Format-Table Name, Status, Error -AutoSize
Write-Host "Results: $resultPath"
Write-Host "Rollback: .\Restore-ADComputersMove.ps1 -ResultPath `"$resultPath`""
Running the Computer Move Script
First, you need to run the script in preview mode. Don’t forget to replace the distinguished name in -SearchBase with the DN of your Workstations OU.
.\Move-ADComputersSafe.ps1 `
-TargetOU "OU=NewWorkstations,DC=contoso,DC=com" `
-SearchBase "OU=Workstations,DC=contoso,DC=com" `
-NameLike "wks-la*"
Now review the planned moves and the generated CSV files. Note that our script does not move any objects unless you specify -Execute and confirm the operation.
After verifying the target OU, selected computers, and backup data, you need to run the script with -Execute in order to perform the moves:
.\Move-ADComputersSafe.ps1 `
-TargetOU "OU=NewWorkstations,DC=contoso,DC=com" `
-SearchBase "OU=Workstations,DC=contoso,DC=com" `
-NameLike "wks-la*" `
-Execute
Replace the example distinguished names with the actual DNs in your environment. Keep the generated CSV files until you have verified that the moved machines and their dependent services are working as expected.
How to Roll Back Bulk Computer Moves?
In case a computer account was moved to the wrong OU, you can use the results CSV file generated by Move-ADComputersSafe.ps1 to restore its original location.ย The rollback script identifies computer objects by ObjectGUID, checks that the original parent OU or container still exists, and compares each computer’s current DN with the DN recorded after the move. By default, it previews the rollback without changing AD. It restores only objects marked as successfully moved in the input CSV and skips objects whose location has changed since the recorded move.
Save the following code as Restore-ADComputersMove.ps1:
Before executing a rollback, don’t forget to review the input CSV and confirm that the selected machines should be restored.
#Requires -Modules ActiveDirectory
<#
.SYNOPSIS
Rolls back moves recorded by Move-ADComputersSafe.ps1 (rows with Status = MOVED).
Dry-run by default. Objects moved again after the original operation are skipped.
.EXAMPLE
.\Restore-ADComputersMove.ps1 -ResultPath .\move-result-20261009-120000.csv
.\Restore-ADComputersMove.ps1 -ResultPath .\move-result-20261009-120000.csv -Execute
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$ResultPath,
[switch]$Execute,
[string]$Server,
[string]$OutDir = '.'
)
$ErrorActionPreference = 'Stop'
function Get-ParentDN {
param([Parameter(Mandatory)][string]$DN)
$parent = $DN -replace '^(?:\\.|[^\\,])+,', ''
if ($parent -eq $DN) { throw "Cannot determine parent DN: $DN" }
$parent
}
if (-not $Server) { $Server = (Get-ADDomain).PDCEmulator }
if (-not (Test-Path -LiteralPath $ResultPath -PathType Leaf)) {
throw "Result CSV not found: $ResultPath"
}
$rows = @(Import-Csv -LiteralPath $ResultPath)
if ($rows.Count -eq 0) { throw "Result CSV is empty." }
foreach ($col in 'Name','ObjectGUID','OriginalParentDN','CurrentDN','Status') {
if ($col -notin $rows[0].PSObject.Properties.Name) {
throw "Required column '$col' is missing. Use the CSV produced by Move-ADComputersSafe.ps1."
}
}
$eligible = @($rows | Where-Object { $_.Status -eq 'MOVED' })
if ($eligible.Count -eq 0) { throw "No rows with Status = MOVED. Nothing to roll back." }
# Detect duplicates
$dups = $eligible | Group-Object ObjectGUID | Where-Object Count -gt 1
if ($dups) { throw "Duplicate ObjectGUID in CSV: $($dups.Name -join ', ')" }
Write-Host "Eligible for rollback: $($eligible.Count)"
Write-Host "Mode: $(if ($Execute) { 'LIVE' } else { 'DRY-RUN' })"
if ($Execute) {
$confirm = Read-Host "Type ROLLBACK to restore these computers"
if ($confirm -cne 'ROLLBACK') { Write-Host "Cancelled."; return }
}
$out = foreach ($e in $eligible) {
$r = [ordered]@{
Name = $e.Name
ObjectGUID = $e.ObjectGUID
TargetDN = $e.OriginalParentDN
CurrentDN = ''
Status = ''
Error = ''
}
try {
$guid = [guid]$e.ObjectGUID
if ([string]::IsNullOrWhiteSpace($e.OriginalParentDN)) { throw "OriginalParentDN is empty." }
# Original parent must still exist (OU or container)
$parent = Get-ADObject -Identity $e.OriginalParentDN -Server $Server
if ($parent.ObjectClass -notin 'organizationalUnit','container') {
throw "Original parent is not an OU/container: $($e.OriginalParentDN)"
}
$comp = Get-ADComputer -Identity $guid -Server $Server -Properties DistinguishedName
$r.CurrentDN = $comp.DistinguishedName
# Do not undo a later, intentional move
if ($comp.DistinguishedName -ine $e.CurrentDN) {
$r.Status = 'SKIPPED_CHANGED'
$r.Error = 'Object is no longer at the DN recorded after the move. Manual review required.'
}
elseif ((Get-ParentDN $comp.DistinguishedName) -ieq $parent.DistinguishedName) {
$r.Status = 'ALREADY_RESTORED'
}
elseif (-not $Execute) {
Move-ADObject -Identity $guid -TargetPath $parent.DistinguishedName `
-Server $Server -WhatIf
$r.Status = 'DRY-RUN'
}
else {
Move-ADObject -Identity $guid -TargetPath $parent.DistinguishedName -Server $Server
$after = Get-ADComputer -Identity $guid -Server $Server -Properties DistinguishedName
if ((Get-ParentDN $after.DistinguishedName) -ine $parent.DistinguishedName) {
throw "Post-rollback verification failed: $($after.DistinguishedName)"
}
$r.CurrentDN = $after.DistinguishedName
$r.Status = 'ROLLED_BACK'
}
}
catch {
$r.Status = 'FAILED'
$r.Error = $_.Exception.Message
}
[pscustomobject]$r
}
$rollbackPath = Join-Path $OutDir "rollback-result-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"
$out | Export-Csv -LiteralPath $rollbackPath -NoTypeInformation -Encoding UTF8
$out | Format-Table Name, Status, Error -AutoSize
Write-Host "Rollback results: $rollbackPath"
if (-not $Execute) {
Write-Host "Preview only. No changes were made. Add -Execute after reviewing the output."
}
Running the Rollback Script
First, you need to run the rollback script without -Execute to preview the restoration. Specify the path to the results CSV generated by the move script:
.\Restore-ADComputersMove.ps1 `
-ResultPath ".\move-result-20261009-120000.csv"
Now review the proposed rollback operations and confirm that the original parent containers are correct. You should use the actual CSV filename generated by your run.
In order to perform the rollback, run the script with -Execute:
.\Restore-ADComputersMove.ps1 `
-ResultPath ".\move-result-20261009-120000.csv" `
-Execute
Our script requests explicit confirmation before making changes. After the rollback, you need to review its output CSV and verify the restored computer accounts in AD.
Important. The rollback script restores computer objects to their original parent containers. It does not reverse unrelated changes made after the move/restore other properties that may have changed independently.
Move Computers with PowerShell Grid View
You can also use another cool PowerShell script that allows you to select computers and the target OU from a grid instead of manually compiling them into a list.
First, run the following command to list all domain computers in a grid. Our example below searches the Workstations OU and its child OUs:
# Set the OU in which to search for computers
$SearchBase = "OU=Workstations,DC=theitbros,DC=com"
$ADComputers = @(
Get-ADComputer -Filter * `
-SearchBase $SearchBase `
-SearchScope Subtree `
-Properties DistinguishedName `
-ErrorAction Stop |
Select-Object Name, DistinguishedName |
Sort-Object Name |
Out-GridView -PassThru -Title "Select Computers to Move" |
Select-Object -ExpandProperty DistinguishedName
)
if ($ADComputers.Count -eq 0) {
throw "No computers selected. No objects will be moved."
}
Select the computer objects you want to move to another OU and click OK. 
Note. Out-GridView is intended for interactive PowerShell sessions with a supported graphical environment. It is not suitable for Windows Server Core/most non-interactive remote sessions. You should use a CSV-based workflow with -WhatIf instead of relying on the grid interface for remote administration and automated tasks.
Next, run the below command to display all OUs in another grid:
$ADOU = Get-ADOrganizationalUnit -Filter * -Properties CanonicalName |
Select-Object -Property CanonicalName, DistinguishedName |
Sort-Object -Property CanonicalName |
Out-GridView -OutputMode Single -Title "Select the target OU"
if (-not $ADOU) {
Write-Host "No target OU selected. Operation cancelled."
return
}
$ADOU = $ADOU.DistinguishedName
Once the grid lists all OUs, select the target OU for the move and click OK (Note! Do not select multiple OUs):
Finally, run the following script to back up the selected computer objects, preview the planned moves, and move them to the target OU after explicit confirmation. Note that the script logs the result of each operation to a CSV file and continues processing if an individual move fails.
Note that the following script also leaves accidental-deletion protection unchanged. In case a protected computer cannot be moved, the operation is recorded as FAILED in the results CSV and requires separate review.
# Configure the domain controller and output files.
$Server = (Get-ADDomain -ErrorAction Stop).PDCEmulator
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$backupPath = ".\grid-move-backup-$stamp.csv"
$resultPath = ".\grid-move-results-$stamp.csv"
# Resolve selected computers and save their original locations.
$backup = @(
foreach ($dn in $ADComputers) {
try {
$computer = Get-ADComputer -Identity $dn `
-Server $Server `
-Properties DistinguishedName `
-ErrorAction Stop
$originalParentDN = $computer.DistinguishedName -replace '^(?:\\.|[^\\,])+,' , ''
if ($originalParentDN -eq $computer.DistinguishedName) {
throw "Cannot determine the original parent DN: $($computer.DistinguishedName)"
}
[pscustomobject]@{
Name = $computer.Name
ObjectGUID = $computer.ObjectGUID
OriginalDN = $computer.DistinguishedName
OriginalParentDN = $originalParentDN
}
}
catch {
throw "Cannot resolve selected computer '$dn': $($_.Exception.Message)"
}
}
)
if ($backup.Count -eq 0) {
throw "No computers selected. No objects will be moved."
}
# Validate the target OU and write the backup before any changes.
Get-ADOrganizationalUnit -Identity $ADOU `
-Server $Server -ErrorAction Stop | Out-Null
$backup | Export-Csv -LiteralPath $backupPath `
-NoTypeInformation -Encoding UTF8 -ErrorAction Stop
# Preview every planned move.
foreach ($computer in $backup) {
Move-ADObject -Identity $computer.ObjectGUID `
-TargetPath $ADOU `
-Server $Server `
-WhatIf -ErrorAction Stop
}
$confirmation = Read-Host "Type MOVE to perform these changes"
if ($confirmation -cne 'MOVE') {
Write-Host "Operation cancelled. No objects were moved."
return
}
# Execute each move independently and record its result.
$results = foreach ($computer in $backup) {
try {
Move-ADObject -Identity $computer.ObjectGUID `
-TargetPath $ADOU `
-Server $Server `
-ErrorAction Stop
$moved = Get-ADComputer -Identity $computer.ObjectGUID `
-Server $Server `
-Properties DistinguishedName `
-ErrorAction Stop
if (-not $moved.DistinguishedName.EndsWith(
",$ADOU",
[System.StringComparison]::OrdinalIgnoreCase
)) {
throw "Post-move verification failed: $($moved.DistinguishedName)"
}
[pscustomobject]@{
Name = $computer.Name
ObjectGUID = $computer.ObjectGUID
OriginalDN = $computer.OriginalDN
OriginalParentDN = $computer.OriginalParentDN
CurrentDN = $moved.DistinguishedName
Status = 'MOVED'
Error = ''
}
}
catch {
[pscustomobject]@{
Name = $computer.Name
ObjectGUID = $computer.ObjectGUID
OriginalDN = $computer.OriginalDN
OriginalParentDN = $computer.OriginalParentDN
CurrentDN = ''
Status = 'FAILED'
Error = $_.Exception.Message
}
}
}
$results | Export-Csv -LiteralPath $resultPath `
-NoTypeInformation -Encoding UTF8 -ErrorAction Stop
$results | Format-Table Name, Status, Error -AutoSize
Write-Host "Backup: $backupPath"
Write-Host "Results: $resultPath"
Check the result:

Considerations for Hybrid Microsoft Entra ID Environments
In case your AD environment is synced with Microsoft Entra ID, you need to check ifย both the source and destination OUs are included in the configured sync scope before moving computer accounts. Moving a computer to an OU outside the sync scope can affect sync of its corresponding Microsoft Entra device object.
An OU move does not directly determine Microsoft Intune group membership/policy assignments. These depend on Microsoft Entra group membership, dynamic membership rules, device filters, and assignment settings.
For current Microsoft Entra Connect Sync requirements and guidance, see the Microsoft Entra Connect documentation. In case you are considering a move to Microsoft Entra Cloud Sync, first check if your config and required features are supported by Cloud Sync.
Change the Default OU for New Computer Accounts in AD
As mentioned above, by default new computers are created in the root Computers container in AD (technically, this is not an OU, so you cannot link a GPO to it). You can use the redircmp command to change the default OU for new computer objects.
Check the current default OU for new computers:
Get-ADDomain | select ComputersContainer

Change the default OU using the command by specifying its distinguished name in the redircmp command:
redircmp "OU=Computers,OU=LA,DC=theitbros,DC=com"
Get-ADDomain | Select-Object ComputersContainer

Active Directory admins can use either the ADUC snap-in or the Move-ADObject PowerShell cmdlet to move computers between Organizational Units within a domain or between domains within a forest. To automatically place new computer accounts in a specific OU, use the redircmp command to modify the domain’s ComputersContainer attribute.
How can I move a computer to another OU using the GUI?
You can use the Active Directory Users and Computers (ADUC) snap-in. Open it by running dsa.msc, locate the computer object, right-click it, choose Move, and select the target OU.
Can I move multiple computer accounts at once using ADUC?
Yes. In ADUC, you can select multiple computer objects using CTRL + Click, then right-click and move them together to another OU.
How do I move a computer account to another OU using PowerShell?
You can use the Move-ADObject cmdlet together with Get-ADComputer, specifying the Distinguished Name (DN) of the target OU. This requires the Active Directory PowerShell module.
How can I find the Distinguished Name of an OU?
You can list all OUs and their Distinguished Names using the Get-ADOrganizationalUnit cmdlet.
How can I bulk move computers to another OU?
PowerShell is the most effective method. You can move computers in bulk by reading their names from a TXT or CSV file and looping through them with a script.
How can I change the default OU for new computer accounts?
You can use the redircmp command to change the default location where new computer objects are created, ensuring they are placed directly into a specified OU.
Is it possible to move computer objects across domains?
Yes. You can move computer accounts between domains within the same forest using PowerShell. This requires Enterprise Admin permissions and specifying the source and target domain controllers.



Hi,
To move delete protected objects, add
Set-ADObject -ProtectedFromAccidentalDeletion:$false -PassThru
Else computer wont move to different OU.