Make PowerShell think an object is not enumerable

Check out the Write-Output replacement http://poshcode.org/2300 which has a -AsCollection parameter that lets you avoid unrolling. But basically, if you're writing a function that outputs a collection, and you don't want that collection unrolled, you need to use CmdletBinding and PSCmdlet:

function Get-Array {
    [CmdletBinding()]
    Param([Switch]$AsCollection) 

    [String[]]$data = "one","two","three","four"
    if($AsCollection) {
        $PSCmdlet.WriteObject($data,$false)
    } else {
        Write-Output $data
    }
}

If you call that with -AsCollection you'll get very different results, although they'll LOOK THE SAME in the console.

C:\PS> Get-Array 

one
two
three
four

C:\PS> Get-Array -AsCollection

one
two
three
four

C:\PS> Get-Array -AsCollection| % { $_.GetType() }


IsPublic IsSerial Name       BaseType                             
-------- -------- ----       --------                             
True     True     String[]   System.Array                         



C:\PS> Get-Array | % { $_.GetType() }


IsPublic IsSerial Name       BaseType                             
-------- -------- ----       --------                             
True     True     String     System.Object                        
True     True     String     System.Object                        
True     True     String     System.Object                        
True     True     String     System.Object   

Wrapping in a PSObject is probably the best way.

You could also explicitly wrap it in another collection—PowerShell only unwraps one level.

Also when writing a cmdlet in C#/VB/... when you call WriteObject use the overload that takes a second parameter: if false then PowerShell will not enumerate the object passed as the first parameter.

Tags:

Powershell