17 July 2018

Moving Computers to Designated OU during Build Process

It has been four years since I published the last version of the PowerShell script to move systems from one OU to another during a build process. In that version, it required making a task sequence for each OU, which if there are a lot of OUs, that would be a very daunting process.

In this new version, I have done two things to improve it. The first is making it into a one-liner, so you don't have to maintain the script on some share. Second, it can now move systems to any OU using the one-liner thereby cutting down on the number of required task sequences.

To use this method, RSAT must be installed on the system. I have RSAT as part of our reference image, so it is already present when the reference image is laid down. The next step is to create the task sequences. There are three task sequences required. The first is to get the OU that was selected in the initial build screen. This is done by querying the MachineObjectOU task sequence variable. Task sequence variables are only accessible to the administrator account. If you try and access them from any other user account, the output is null. This is the reason why three task sequences are required for this process. So to pass the MachineObjectOU to the next task sequence which will move the system, I have it write the OU to the text file OU.txt located in the c:\ directory.

This is the one-liner for creating the file containing the OU to move the system to:

 powershell.exe -executionpolicy bypass -command "&{$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment;$TSEnv.Value('MachineObjectOU') | out-file c:\OU.txt}"  

The next step is moving the system. This one-liner will read the OU in the text file, check to see if the system is in the desired OU, and then move it if it is. Lastly, the one-liner will do a check to make sure the system is in the correct OU after the system is supposedly moved. It exits with a 0 if successful and a 1 if unsuccessful.

This is the one-liner for moving the system:

 powershell.exe -executionpolicy bypass -command "&{Import-Module ActiveDirectory;[string]$CurrentOU=((Get-ADComputer $env:ComputerName).DistinguishedName.substring((Get-ADComputer $env:ComputerName).DistinguishedName.IndexOf(',')+1));[string]$NewOU=Get-Content c:\OU.txt;If ((Get-WmiObject Win32_Battery) -ne $null) {$NewOU=$NewOU.Insert(0,'OU=Laptops,')};If ($CurrentOU -ne $NewOU) {Move-ADObject -identity (Get-ADComputer $env:ComputerName).DistinguishedName -TargetPath $NewOU};$CurrentOU=((Get-ADComputer $env:ComputerName).DistinguishedName.substring((Get-ADComputer $env:ComputerName).DistinguishedName.IndexOf(',')+1));If ($CurrentOU -eq $NewOU) {Exit 0} else {Exit 1};}"  

Lastly, the third task sequence will delete the OU.txt file. There are no WMI queries that have to be done in the newly updated script as was required in the old one.

 powershell.exe -executionpolicy bypass -command "&{Remove-Item -Path c:\OU.txt -Force}"  

This is how I have it in the task sequence hierarchy:



Post a Comment