Reputation:
I have a script that when I run locally on my domain controller it works fine without issues (using Import-Module ActiveDirectory
locally instead of a remote PSSession). However, when I run it remotely it fails with the following error:
The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. + CategoryInfo : InvalidArgument: (CN=Test User ...,DC=domain,DC=com:PSObject) [Get-ADUser], ParameterBindingException + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.ActiveDirectory.Management.Commands.GetADUser + PSComputerName : van-dc03.vand1.oppy.com
The code I am running is:
$ADSession = New-PSsession -ComputerName ourdcserver -Credential $(Get-Credential)
Invoke-Command -Command {
Import-Module ActiveDirectory,AdSync -Cmdlet Get-ADUser, Search-ADAccount
} -Session $ADSession
Import-PSSession -Session $ADSession -AllowClobber -Module ActiveDirectory
Search-ADAccount -UsersOnly -AccountInactive -SearchBase "OU=test,DC=our,DC=domain,DC=com" -Timespan 30.00:00:00 |
Where-Object { $_.Enabled -eq $true } |
Get-ADUser -Properties Name, sAMAccountName, WhenCreated, lastLogonTimestamp |
Select Name, sAMAccountName, WhenCreated,
@{n="LastLogonTimeStamp";e={[DateTime]::FromFileTime($_.LastLogonTimestamp)}} |
Sort-Object LastLogonTimeStamp |
Export-CSV $CurrentWorkfile -NoTypeInformation -Encoding ASCII
I found a similar thread on this Technet forums thread however I am not very familiar with PowerShell. Anyone able to give me a hand re-writing this code (or an example) so that the piping works?
Upvotes: 2
Views: 11987
Reputation: 3606
The implicit remoting, that you are using in your script is a tricky thing. The cmdlets you are importing with the ActiveDirectory module from the remote session feel as if they are local, but they really are not. They run remotely and the objects they return will go through a process of serialisation and deserialisation, when they are send from the remote session to your local session.
That means the objects you are receiving from your implicitly remote Search-ADAccount
are slightly different then the ones, that you would get, if you run the command locally. Pipe a local command and its implicitly remote version to Get-Member
and compare the result, you will see what I mean. Just as an example you will find the property PSComputer
with any object that is returned from a remote session (even if implicit).
The error that you get says, that Get-ADUser
cannot handle the input object from the pipeline, because it cannot figure out to which parameter it should be bound. The likely reason is, that after being send back and forth between sessions the object cannot be cast to anything that Get-ADUser
would understand.
Now what you can do is to avoid implicit remoting. Put your ActiveDirectory cmdlets in a script block and return only what you need to process locally.
$ADSession = New-PSsession -ComputerName ourdcserver -Credential $(Get-Credential)
$scriptBlock = {
param( $SearchBase )
Search-ADAccount -UsersOnly -AccountInactive -SearchBase $SearchBase -Timespan 30.00:00:00 |
Where-Object { $_.Enabled -eq $true } |
Get-ADUser -Properties Name, sAMAccountName, WhenCreated, lastLogonTimestamp |
Select Name, sAMAccountName, WhenCreated,
@{n="LastLogonTimeStamp";e={[DateTime]::FromFileTime($_.LastLogonTimestamp)}} |
Sort-Object LastLogonTimeStamp
}
Invoke-Command -Session $ADSession -ScriptBlock $scriptBlock -ArgumentList "OU=test,DC=our,DC=domain,DC=com" |
Select-Object Name,sAMAccountName,WhenCreated,LastLogonTimeStamp |
Export-CSV $CurrentWorkfile -NoTypeInformation -Encoding ASCII
Upvotes: 3