I wrote a script that moves computer from one OU to a different OU in Active Directory. The script works fine on my computer because I have Active Directory installed on my computer, but the problem is that when I run the script on a computer that doesn’t have AD installed, of course it fails.
I understand there’s a way to remote into a computer or server that have AD, how would I do that?
That’s called “implicit remoting,” and it’s discussed in “Secrets of PowerShell Remoting,” which is on our Ebooks menu. There can be some security constraints, especially with AD, but read up on the basics (and the Import-Module command, which is the basis of it all), and come back if you have questions from there!
Off the top of my head. I don’t have a Windows PC handy at the moment, so -PSSession might be -Session, I forget and they’re a little inconsistent across cmdlets. The commands will seem to exist locally once you do this, and will remain so long as that session is open and usable. The the machine in question is a DC, it should work fine.
I have a server 2012 running Active Directory Web Services, but getting the warning below, apparently it’s caused by the firewall blocking TCP port 9389, I’m checking with our security team to verify.
PS C:\Windows\system32> \\hqfs1\users\tantony\PowerShell\MovetoADOU\remote.ps1
WARNING: Error initializing default drive: 'Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running.'.
I’m now able to access Active Directory module by remoting into a DC.
# creating session to DC5 for AD module
Enter-PSSession -ComputerName DC5
Get branch number, move workstation to correct OU in AD
# Exiting DC5 session
Exit-PSSession
Now the issue is that, if I run my script from a workstation that doesn’t have Active Directory, I can remote to DC but it says “Get-ADOrganizationalUnit : The term ‘Get-ADOrganizationalUnit’ is not recognized as the name of a cmdlet, function…”
I’m not sure if there’s a way to post screenshots in this forum so it’s easier.
Enter- establishes an ad box session to the machine, similar to the way ssh works. You’re “on” the remote machine. When you exit, you’re “back” to the local machine, where the commands don’t exist.
You want to use New-PSSession to create an open session while remaining on your local machine. Capture that session in a variable. Then use Import-Module, specify the module name and the session variable. This is what I’d already typed, above. Have you tried that?
This is my updated script to create a new pssession
$session = New-PSSession -computer DC5
Import-Module ActiveDirectory -PSSession $session
# Gets computer serial number
$Computer = $env:COMPUTERNAME
# Requesting user input
$GetOU = Read-Host "Please enter branch number search AD OU "
# Gets the desired OU
$MoveToOU = Get-ADOrganizationalUnit -Filter "Name -like `"*$GetOU*`""
# Moves computer to branch name \ Workstations OU in AD
Get-ADComputer $Computer | Move-ADObject -TargetPath "OU=Workstations,$MoveToOU"
Write-host "Moved " $Computer " to " $MoveToOU.DistinguishedName -ForegroundColor Green
# Exiting DC5 session
Exit-PSSession
Now, I can see that it is loading the AD module, and it says it moved the workstation to my desired OU, but it didn’t actually move i. It says “The input object cannot be bound to any parameters for the command either because the command does not take pipeline input…”
This is a common problem with implicit remoting. Since your commands are running on a remote machine the data and objects are serialized when being sent and deserialized when they are returned to your local console. With many modules this breaks pipeline interoperability between cmdlets that would normally work with locally loaded modules.
You can see this comparison by running:
Get-ADComputer | Get-Member
Locally on your DC then running it in your console with the module imported through your implicit remoting session. You’ll notice the object type is different that when you run this with the imported AD module you’ll see the word “deserialized” added somewhere in the middle of the “ADComputer” object type name.
This breaks parameter binding as typically in your scenario you’d be piping ADComputer objects to the Move-ADObject cmdlet, not a deserialized ADComputer object.
In this instance the only workaround is to iterate through your returned objects and explicitly pass the object properties to the appropriate parameters on the receiving cmdlet. In your case you’ll want to use: