Move OU Object Script

Hi All,

I’ve written this PowerShell script to do the following logic :

  • get machine name
  • is it desktop or laptop
  • is it in AD ? yes/no
  • no - break
  • Yes - check ou
  • correct ou ?
  • yes, continue

Its to run at the start of an SCCM build. The OSDComputerName is set through an HTA at the start.

Just wanted you thoughts and comments on how it looks :slight_smile:

[cmdletbinding()]
param (
      )
        

#Get Desktop name from Task Variable
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$ComputerName = $tsenv.Value('OSDComputerName')


#Is this a desktop or Laptop
If ($Computername -match "LAP") {
     $Laptop 
} else 
     {
     $Desktop
     } 


#TargetOU
$LAPTargetOU = 'OU=Laptops,OU=Desktop-Devices,OU=Company,DC=Comp,DC=local' 
$DKTTargetOU = 'OU=Workstations,OU=Desktop-Devices,OU=Company,DC=Comp,DC=local'

#Laptop Code
$Laptop = $($LapADComputer = (Get-ADComputer $Computername)) 
            $LAPComputerOU = $($ADComputer.DistinguishedName).Substring(13)

  
if ($LAPTargetOU -match $LAPComputerOU) {
       Write-verbose "$Computername is in the correct AD OU of $LAPComputerOU" -Verbose
       Break 
} else
     { Move-ADObject -Identity $LapADComputer -TargetPath $LAPTargetOU
       write-verbose "$Computername has been moved to the new OU of $LAPTargetOU" -Verbose
       Break
     }
     
#Desktop Code         
$Desktop = $($DktADComputer = (Get-ADComputer $Computername)) 
             $DKTComputerOU = $($ADComputer.DistinguishedName).Substring(13)

  
if ($DKTTargetOU -match $DKTComputerOU) {
      Write-Output "$Computername is in the correct AD OU of $DKTComputerOU" -Verbose
      Break
} else
     { Move-ADObject -Identity $DktADComputer -TargetPath $DKTTargetOU
      write-verbose "$Computername has been moved to the new OU of $DKTTargetOU" -Verbose
      Break
     }

Graham,

That’s not going to do what you think it should. Referencing $Laptop and $Desktop like that isn’t going to execute any code. Your code for laptop and desktop are the same, so you don’t need it twice, you can just change the variables. cmdletbinding and param don’t to anything if you don’t have any parameters.

Try something like this:

#Get Desktop name from Task Variable
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment
$ComputerName = $tsenv.Value('OSDComputerName')

#TargetOU
$LAPTargetOU = 'OU=Laptops,OU=Desktop-Devices,OU=Company,DC=Comp,DC=local' 
$DKTTargetOU = 'OU=Workstations,OU=Desktop-Devices,OU=Company,DC=Comp,DC=local'

#Is this a desktop or Laptop
If ($Computername -match "LAP")
    {
    $CorrectOU = $LAPTargetOU
    }
else
    {
    $CorrectOU = $DKTTargetOU
    } 

$ADComputer = Get-ADComputer $Computername

If ( $ADComputer )
    {
    $CurrentOU = $ADComputer.DistinguishedName.Split( ",", 2 )[1]

    if ( $CurrentOU -eq $CorrectOU )
        {
        Write-Verbose "$Computername is in the correct AD OU of $CurrentOU" -Verbose
        }
    else
        {
        Move-ADObject -Identity $ADComputer -TargetPath $CorrectOU
        Write-Verbose "$Computername has been moved to the new OU of $CorrectOU" -Verbose
        }
    }

What Tim suggested is spot on. Also, if you plan on automating this with the chance you will not be at the console to see the verbose messages why not add in some more logging power?

Jason Wasser has a great function write up on the TechNet Gallery about adding some detailed logging ability to scripts that will suit this situation perfectly.

<a href="https://gallery.technet.microsoft.com/scriptcenter/Write-Log-PowerShell-999c32d0"

Thanks guys. Tim that’s brilliant and far more simpler. I like what you have done comparison part.
If the machine is not in AD, what happens ?

Graham,

If the machine is not in AD, $ADComputer will be null. In an If conditional, a null value evaluates as true.
If ( $ADComputer )
is the same as
If ( $ADComputer -ne $Null )
so the code is skipped.

(BTW - You may need to add -ErrorAction ‘SilentlyContinue’ to the Get-ADComputer command to prevent a not-found “error” from causing the script to fail.)