ADComputer pipeline usage

Can someone tell me why this pipeline implementation doesn’t work?

function count
{
    [CmdletBinding()]
    Param
    (
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [Alias('Name')]
        [string[]]
        $ComputerName
    )

    Begin
    {        Write-Host "Computer count: $($ComputerName.count)"    }
    Process    {    }
    End    {    }
}

The variable is null as in it’s not getting any data from the pipeline.

PS > Get-ADComputer -filter * | count
Computer count: 0

PS > (Get-ADComputer -filter *).count
117

The property name is Name, matches the alias I added above.

PS > Get-ADComputer -filter * |gm 

   TypeName: Microsoft.ActiveDirectory.Management.ADComputer

Name              MemberType            Definition                                                                                                                         
----              ----------            ----------                                                                                                                         
Contains          Method                bool Contains(string propertyName)                                                                                                 
Equals            Method                bool Equals(System.Object obj)                                                                                                     
GetEnumerator     Method                System.Collections.IDictionaryEnumerator GetEnumerator()                                                                           
GetHashCode       Method                int GetHashCode()                                                                                                                  
GetType           Method                type GetType()                                                                                                                     
ToString          Method                string ToString()                                                                                                                  
Item              ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPropertyValueCollection Item(string propertyName) {get;}                                    
DistinguishedName Property              System.String DistinguishedName {get;set;}                                                                                         
DNSHostName       Property              System.String DNSHostName {get;set;}                                                                                               
Enabled           Property              System.Boolean Enabled {get;set;}                                                                                                  
Name              Property              System.String Name {get;}                                                                                                          
ObjectClass       Property              System.String ObjectClass {get;set;}                                                                                               
ObjectGUID        Property              System.Nullable`1[[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] ObjectGUID {get;set;}
SamAccountName    Property              System.String SamAccountName {get;set;}                                                                                            
SID               Property              System.Security.Principal.SecurityIdentifier SID {get;set;}                                                                        
UserPrincipalName Property              System.String UserPrincipalName {get;set;}     

You’ve coded it wrong ;).

When objects are piped in, BEGIN{} runs first, before any objects are piped in. You’re correctly displaying zero. PROCESS{} is then given one object at a time - it will never be more than 1. Then, END{} runs. There’s no way, within an advanced function, to know how many objects are coming down the pipeline, because they’re fed in singly.

Bad example on my part. Same null issue when I put it in the process block.

My actual function doesn’t count, just using that to keep my example simple and demonstrate the issue. It’s an alias problem. As far as I can tell, the alias is implemented correctly.

function count
{
    [CmdletBinding()]
    Param
    (
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [Alias('Name')]
        [string[]]
        $ComputerName
    )

    Begin { }
    Process  
    {        Write-Host "Computer count: $($ComputerName.count)"    }
    End    {    }
}

And when I run it.

PS > Get-ADComputer -filter * | count
Computer count: 0
Computer count: 0
...
Computer count: 0
Computer count: 0

But if I change my code, remove the alias and change the variable itself to “$name” it works fine.

function count
{
    [CmdletBinding()]
    Param
    (
        [Parameter(ValueFromPipelineByPropertyName=$true)]
        [string[]]
        $Name
    )
    Begin { }
    Process  
    {        Write-Host "Computer count: $($Name.count)"    }
    End    {    }
}

And when I run it now…

PS > Get-ADComputer -filter * | count
Computer count: 1
Computer count: 1
...
Computer count: 1
Computer count: 1

I just-just found this thread linked below, can you confirm if this statement is correct?

“AD cmdlets have this issue when you pipe to non-AD cmdlets…It’s actually a problem with Get-ADComputer”

I can confirm it a issue with the object returned from get-ADComputer. At some point I had a good detailed explanation of the issue with the AD cmdlets but it escapes me at the moment.

You can use the your original code if you select the attributes you want before piping to your function

PS > Get-ADComputer -filter *|select Name | count

Thanks Jonathan, I ended up using the $Name variable instead, with Aliases for non-AD cmdlet input, so it works as desired.