I wrote a blog post way back(2010) on how to move a computer to another OU during OS Deployment https://ccmexec.com/2010/12/move-computer-to-the-correct-ou-during-deployment/.
Could be that you want to move it when you upgrade to Windows 10 or if you reinstall a computer and it already exist in an different OU then it will not be moved automatically. The script is still being used, downloaded and commented on. So here is an updated blog post with a PowerShell script that does the move, if you don’t want to use a webservice.
The script:
# Script to move the computer object in AD to the OU supplied as a variable
# 1st Example Command line Powershell.exe -NoProfile -ExecutionPolicy bypass -file MoveToOU.ps1 "%MachineObjectOU%"
# 2nd example command line Powershell.exe -NoProfile -ExecutionPolicy bypass -file MoveToOU.ps1 "OU=Desktop,OU=Computers,OU=Test,DC=Test,DC=Local"
$OU = $args[0]
try {
$CompDN = ([ADSISEARCHER]"sAMAccountName=$($env:COMPUTERNAME)$").FindOne().Path
$CompObj = [ADSI]"$CompDN"
$CompObj.psbase.MoveTo([ADSI]"LDAP://$($OU)")
}
catch {
$_.Exception.Message ; Exit 1
}
It can be downloaded here as well: https://github.com/Ccmexec/MEMCM-OSD-Scripts
Save the script to a file in your package source folder for the script.
- Add the script to a package you replicate to all DPs
- In the Task Sequence add the following Run Command Line task (Make sure to add it after the “Setup Windows and Configuration Manager Client step”)
- Use a User Account with permission in the Active Directory to perform the task.
In this example the %MachineObjectOU% variable is used which can be set by MDT for example.
As simple as that and you are done!
NOTE: If you get an error like:
Exception calling “FindOne” with “0” argument(s): “Unknown error (0x80005000)”
Then check out this old post on an issue with the “Run this step as the following account” caused by .NET Framework 1.1.
https://docs.microsoft.com/en-us/archive/blogs/deploymentguys/run-command-line-as-domain-user-incorrect-function-error
Thanks to my colleague Johan Schrewelius for the help.
Hi Jorgan, great work. Looks to be working for me. Just one thing. In your example command line above the script, you have -Set-ExecutionPolicy not -ExecutionPolicy.
Thanks again, love your work.
Hi,
Thanks for the heads-up! Fixed it! 😀
/jörgen
Hi Jörgen, I can’t seem to get this to work in my build task sequence. The weird thing is, if I copy the relevant step into a blank custom TS and deploy once the same machine has been built, it works fine. I’ve got it inserted after setup windows and ConfigMgr. I get “Incorrect function Error Code 1”. Any ideas?
Hi,
Is the computer domain joined? the step is run after the Setup Windows and Configuration Manager step?
Regards,
Jörgen
Hi,
I’m having the exact same problem as Stewart is describing.
Error 1 if i run it in build task and if i deploy the same step in a custom TS it works just fine.
From smsts.log (build task): Exception calling “FindOne” with “0” argument(s): “Ok„nt fel (0x80005000)”
Regards,
Anders
Hi,
0 Arguments sounds like something is strange. can you paste the command line? Where in the TS are you running it?
Regards,
Jörgen
Hi,
Running in State Restore.
Command line: powershell.exe -NoProfile -ExecutionPolicy Bypass -File Move-Computer.ps1 “OU=XX,DC=XX….”
(I don´t know if this has anything to do with this but if i add a pause task right before the “move computer” task and try to run “runas /user:’domain admin account’ cmd” i get the error message “5: Access denied”.)
Regards,
Anders
Hi, I have the same problem with Exception calling FindOne with 0 arguments.. did you find a solution? I wonder if its a problem because i’m using a joindomain account, that’s restricted..
Hi,
What if you run the script manually using that same account does it work then?
Regards,
Jörgen
Hi all,
I was struggling with this ‘Access Denied’ issue as well.
For me, it works after adding the following key, before I start the move script:
REG ADD HKLM\Software\Microsoft\COM3 /v REGDBVersion /t REG_BINARY /d 010000 /f
(https://blogs.technet.microsoft.com/deploymentguys/2012/04/24/run-command-line-as-domain-user-incorrect-function-error/)
Hi,
Thanks for posting it here! That is an often used workaround and will solve it as the script works but fails in some TS: I have seen it as well when I copy steps between TS.
Regards,
Jörgen
Hi Jorgen,
Is it possible to set the OU when calling the script instead of using MDT to set the %MachineObjectOU% variable?
Particularly as we would like to use an if statement so that if the machine is a desktop, OU1 is selected and if a laptop OU2 is selected.
Kind Regards,
Jo
Hi,
Yes will work just as well as the variable.
Regards,
Jörgen
I have a similar scenario, if I want to specify an OU rather than a variable how would the script then look ? Do I set it within the script or should I set it in the command line task sequence ?
Hi,
You can set it as a Task Sequence variable or use the sample command line I added a couple of weeks ago to the Post:
example command line:
Powershell.exe -NoProfile -ExecutionPolicy bypass -file MoveToOU.ps1 “OU=Desktop,OU=Computers,OU=Test,DC=Test,DC=Local”
That will work the same way.
Regards,
Jörgen
I am attempting to use this as part of a task sequence so that I can move a computer to a different OU once the machine has been upgraded from Windows 8.1 to Windows 10. Unfortunately this doesn’t work and doesn’t give me much info in the imaging logs as to why. As such, I have run the script locally on a test machine and I get the following error:
“PS C:\WINDOWS\system32> z:\MoveToOU.ps1 “%OU=Laptops,OU=Staff 10,OU=Computer Accounts%”
Exception calling “MoveTo” with “1” argument(s): “An operations error occurred.”
When I look at $Error I get a little more info and it displays the following:
At z:\MoveToOU.ps1:10 char:5
+ $CompObj.psbase.MoveTo([ADSI]”LDAP://$($OU)”)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
PS C:\WINDOWS\system32>
I’m just stumped at this point, as from what I’ve found online the error suggests that there is an ‘access denied’ issue, however the PowerShell command window has been loaded to ask for credentials of the Active Directory account that has permission to move computer objects, so not sure what I am missing.
I’d also appreciate any info/resources on how I can send what is caught during the ‘catch’ error handling segment so that this is written to the standard smsts.log file that is generated when the task sequence runs.
Hi,
You need the full LDAP path for the move and not only the OU part, you need for example:
OU=Desktop,OU=Computers,OU=Test,DC=Test,DC=Local and the “%” are not needed either, I will update the post with that example.
Thanks
/Jörgen
Jorgen thanks for this. Much appreciated.
I got this to work when running it manually, but when it doesn’t run/work when I run it as part of the task sequence and my smsts.log doesn’t give me any info as to why it hasn’t worked.
I’m testing it with a task sequence that only executes the move before adding it to my full task sequence, but no joy there either. I’m sure I could crack it, it’s the absence of any error messages that has me stumped at this point.
Hi,
I managed to get this working in a task sequence, but it is the only thing in this test task sequence. When I add it to the main task sequence I want it to run from I get a failure:
“failed to get the linked token information. It may not be available. Error 1312”
Yet works when separate. a little frustrating bnut it feels like I am close.
Any help/advice really would be much appreciated.
Thanks & Kind Regards,
Jo
Hi, Where in the task sequence are you running it? It Should be run after the Setup Windows and Configuration Manager step.
Regards,
Jörgen
Hi,
This task sequence is a Windows 8 – Windows 10 inplace upgrade annd as such I have the following:
– Prepare for Upgrade: which removes apps that are caught by incompatibility checking and if not removed cause failure.
– Upgrade the OS followed by a restart
– Installs Applications for Windows 10
– Customisations to the OS
– OU Move: which includes the MDT Toolkit and Gather actions followed by the actual script to move depending on whether the machine is evaluated as a laptop/desktop using the variable IsLaptop, ending with a restart.
The evaluation for laptop or desktop works fine, but when running the command there appears to be an issue downloading the content for the package which holds the script, which is the same package used in my test task sequence (which works) and only includes the actions for the OU Move.
Again, thanks for all your help with this.
Kind Regards,
Jo
Hi,
I want to move new deployed computers to specific OUs by checking their IP addresses.
So, I wrote a Powershell script which reads computer IP address and match it in an external CSV file, in which I specified IP subnets with OUs in the complete form: “OU=Computers Site 1,OU=Site 1,DC=contoso,DC=com”.
So far so good: I call the “Run Command Line” task in the Task Sequence (after domain join and Setup Windows and ConfigMgr) and run the following command: powershell.exe -NoProfile -ExecutionPolicy Bypass -File MoveToOU.ps1
Both PS1 and CSV files are in the same Package and the command runs with a domain admin account.
In my log (from the script) all works but the OU moving: $CompObj.psbase.MoveTo([ADSI]”LDAP://$($OU)”)
I have an exeption: “Exception calling “MoveOU” with “1” argument(s): “An invalid dn syntax has been specified.”
Where “MoveOU” is my function to which I pass the $OU argument.
If I run the script locally it works fine. If I create a TS in which there is only this task, it works fine. So, do I’m missing something?
$username = ‘UName’
$password = ‘PWord’
$Key = ()
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username,($password | ConvertTo-SecureString -Key $Key)
#Create variable capabable of querying Task Sequence variable
$tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
#Moves Computer to Proper OU
Import-Module ActiveDirectory
Get-ADComputer $ENV:COMPUTERNAME -Credential $cred | Move-ADObject -TargetPath $tsenv.Value(“OSDDomainOUName”) -Credential $cred
The above Worked for our environment.
This part was the most important: $tsenv = New-Object -ComObject Microsoft.SMS.TSEnvironment
Hi Jörgen,
Thanks for the script. It works fine. I just don’t want to use “Run as …”.
For some reason I like to use the username and password in the script.
Can you help me please?
Thanks
Hi , I am also getting the same error while running the task to move the computer object to target OU. Does anyone have an idea on the fix? I have used the above script and i am running it with my Domain Admin access.
apologies, script worked without any issues and the error due to the typo in my OU name!
Merwin
kindly share scripts to move the workstations based on name to appropriate name automatically. if computer stats with UKD—it has to go to UKD OU