Link to home
Start Free TrialLog in
Avatar of Terellion
TerellionFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Moving Computers into different OU via Powershell (WEIRD ONE)

Hi guys,

Got a weird issue where I have a script that retrieves a list of machines last known IP addresses and moves them to the corresponding OU to keep things nice and tidy. For some reason 4 machines do just not want to move across, if I run a -whatif it shows the 4 machines in question and says "Performing the operation "Move" on target ..................... but it just will not move them.

I've even tried -verbose and also tried physically moving them in Active Directory which works without any issues.

Any ideas?

Thanks :)
Avatar of footech
footech
Flag of United States of America image

Can you post the script?  Then we could probably see if it a script problem, or something external.
Avatar of Terellion

ASKER

#Add the Active Directory PowerShell module
Import-Module ActiveDirectory

##############################
# Set the Location IP ranges #
##############################

$Site1IPRange = "\b(?:(?:192)\.)" + "\b(?:(?:168)\.)" + "\b(?:(?:1)\.)" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" # 192.168.1.0/24
$Site2IPRange = "\b(?:(?:192)\.)" + "\b(?:(?:168)\.)" + "\b(?:(?:20)\.)" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" # 192.168.20.0/24



########################
# Set the Location OUs #
########################

# OU Locations
$Site1DN = "OU=Computers,OU=New York,OU=Offices,DC=Domain,DC=Local"
$Site2DN = "OU=Computers,OU=London,OU=Offices,DC=Domain,DC=Local"


###############
# The process #
###############

# Query Active Directory for Computers and move the objects to the correct OU based on IP
Get-ADComputer -Filter {OperatingSystem -like "Windows*"} -Properties * -SearchBase 'OU=Domain Computers,DC=Domain,DC=Local' -ResultPageSize 3000 | ForEach-Object {

      # Ignore Error Messages and continue on
      trap [System.Net.Sockets.SocketException] { continue; }

      # Set variables for Name and current OU
      $ComputerName = $_.Name
      $ComputerDN = $_.distinguishedName
      $ComputerContainer = $ComputerDN.Replace( "CN=$ComputerName," , "")

      # Query DNS for IP
      # First we clear the previous IP. If the lookup fails it will retain the previous IP and incorrectly identify the subnet
      $IP = $NULL
      $IP = [System.Net.Dns]::GetHostAddresses("$ComputerName")

      # Use the $IPLocation to determine the computer's destination network location
      #
      #
      if ($IP -match $Site1IPRange) {
            $DestinationDN = $Site1DN
      }
      ElseIf ($IP -match $Site2IPRange) {
            $DestinationDN = $Site2DN
      }

      Else {
            # If the subnet does not match we should not move the computer so we do Nothing
            $DestinationDN = $ComputerContainer      
      }

      # Move the Computer object to the appropriate OU
      # If the IP is NULL we will trust it is an "old" or "very old" computer so we won't move it again
      if ($IP -ne $NULL) {
            Move-ADObject -Identity $ComputerDN -TargetPath $DestinationDN -Verbose
      }
}
Can anyone help with this :(
What happens if you just try to use a single Move-ADObject command to move the computer account (i.e. outside of a script)?

I would rework the script so that the move command isn't called at all for computers that shouldn't be moved.  And add  some output so you can see when the move command is being called (can be commented out after debugging).  Something like this.
#Add the Active Directory PowerShell module
Import-Module ActiveDirectory

##############################
# Set the Location IP ranges #
##############################

$Site1IPRange = "\b(?:(?:192)\.)" + "\b(?:(?:168)\.)" + "\b(?:(?:1)\.)" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" # 192.168.1.0/24
$Site2IPRange = "\b(?:(?:192)\.)" + "\b(?:(?:168)\.)" + "\b(?:(?:20)\.)" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" # 192.168.20.0/24



########################
# Set the Location OUs #
########################

# OU Locations
$Site1DN = "OU=Computers,OU=New York,OU=Offices,DC=Domain,DC=Local"
$Site2DN = "OU=Computers,OU=London,OU=Offices,DC=Domain,DC=Local"


###############
# The process #
###############

# Query Active Directory for Computers and move the objects to the correct OU based on IP
Get-ADComputer -Filter {OperatingSystem -like "Windows*"} -Properties * -SearchBase 'OU=Domain Computers,DC=Domain,DC=Local' -ResultPageSize 3000 | ForEach-Object {

    # Ignore Error Messages and continue on
    trap [System.Net.Sockets.SocketException] { continue; }

    # Set variables for Name and current OU
    $ComputerName = $_.Name
    $ComputerDN = $_.distinguishedName
    $ComputerContainer = $ComputerDN.Replace( "CN=$ComputerName," , "")

    # Query DNS for IP 
    # First we clear the previous IP. If the lookup fails it will retain the previous IP and incorrectly identify the subnet
    $IP = $NULL
    $IP = [System.Net.Dns]::GetHostAddresses("$ComputerName")

    $move = $false
    # Use the $IPLocation to determine the computer's destination network location
    #
    #
    if ($IP -match $Site1IPRange) {
        $DestinationDN = $Site1DN
        $move = $true
    }
    ElseIf ($IP -match $Site2IPRange) {
        $DestinationDN = $Site2DN
        $move = $true
    }


    # Move the Computer object to the appropriate OU
    if ($move -eq $true) {
        Write-Host "Moving ""$ComputerDN"" to ""$DestinationDN""" -ForegroundColor Yellow
        Move-ADObject -Identity $ComputerDN -TargetPath $DestinationDN -Verbose
    }
}

Open in new window


I don't see anything wrong with the script.  Only thing I see that would prevent the account from being moved would be if it was skipped (due to not matching the IP range).  After that look outside the script for reasons (check permissions, event logs, etc.).
Hi there, it seems to be working fine except anything with a /8 subnet, i.e 10.10.10.10/8. Any ideas?
Do you have a regex that matches a /8 subnet?  So far I've only seen the two /24 ones.
Nope I don't know much about regex, I tried:

$Site1IPRange = "\b(?:(?:10)\.)" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" + "\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))" # 10.0.0.0/8

No good though :/
ASKER CERTIFIED SOLUTION
Avatar of footech
footech
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You are absolutely AMAZING! THANK YOU SO MUCH! :)
Thanks for the feedback.  :)