tags:

views:

39

answers:

2

I've been working on some PowerShell functions to manage objects implemented in an assembly we have created. One of the classes I have been working with implements IEnumerable. Unfortunatly, this causes PowerShell to unroll the object at every opportunity. (I can't change the fact that the class implements IEnumerable.)

I've worked around the problem by creating a PSObject and copying the properties of our custom object to the PSObject, then returning that instead of the custom object. But I'd really rather return our custom object.

Is there some way, presumably using my types.ps1xml file, to hide the GetEnumerator() method of this class from PowerShell (or otherwise tell PowerShell to never unroll it).

+4  A: 
Richard
+2  A: 

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   
Jaykul
The problem is that I want to avoid having it unrolled EVER. I can return the object from my function without unrolling it by using the return-as-array trick (or what you describe). But eventually I'll end up unrolling it by accident.
OldFart
Simply put: I know of no way to do that, but please don't try :) ... If you DO find a way you'll just end up causing a bunch of bug reports from people unable to figure out why your collection doesn't have anything in it even though .Count reports a nice big number.
Jaykul