Optimizing Exchange command invocation

Given the caveats of the default language and remoting when running Exchange commands, does anyone know a doc source that identifies the semantics on what is executed remotely versus not and therefor subject to serialization?

I need to retrieve a subset of info from every mailbox and for performance reasons, I’d like to only serialize and ship back what I know I need. Logically, I would assume (excluding the necessary parameters for brevity):

get-remotemailbox |select propertyOne,propertyTwo,propertyThree |MyScriptCmdlet

Where MyScriptCmdlet would execute locally against the psobjects that were serialized and shipped back with just three properties.

Anyone know of a good doc source on this aspect?

Typically, if the command does not have a -Properties parameter, there isn’t any control on what is produced from the command. This is normally limitations of the API that is being used or not it’s not implemented (less likely with a mainstream cmdlets like Exchange) The Select-Object is generating a new PSObject from the existing object returned from Get-RemoteMailbox, it’s actually not filtering. If there are 10 properties returned from Get-RemoteMailbox, all that Select-Object is really doing is reducing the memory in the pipeline but you are still getting all 10 properties from Get-RemoteMailbox. There may not be much you can do outside of filter users or change scope to make it more efficient, but it’s widely used so you can see if there is any examples in blogs or forums.

If you are using PropertyByvalueName in your cmdlet, it will ignore the other items passed to it:

function Test-It {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true,
        ValueFromPipelineByPropertyName=$true)]
        [string]$Property1,
        [Parameter(Mandatory=$true,
        ValueFromPipelineByPropertyName=$true)]
        [string]$Property2,
        [Parameter(Mandatory=$true,
        ValueFromPipelineByPropertyName=$true)]
        [string]$Property3
    )
    begin {}
    process {
        Write-Verbose ('Property 1 is {0}' -f $Property1)
        Write-Verbose ('Property 2 is {0}' -f $Property2)
        Write-Verbose ('Property 3 is {0}' -f $Property3)
    }
    end {}
}

$obj = @()
$obj += [pscustomobject]@{
    Property1 = 'Prop1'   
    Property2 = 'Prop2'   
    Property3 = 'Prop3'   
    Property4 = 'Prop4'   
    Property5 = 'Prop5'   
}
$obj += [pscustomobject]@{
    Property1 = 'Prop11'   
    Property2 = 'Prop22'   
    Property3 = 'Prop33'   
    Property4 = 'Prop44'   
    Property5 = 'Prop55'   
}

$obj | Test-It -Verbose

Output:

VERBOSE: Property 1 is Prop1
VERBOSE: Property 2 is Prop2
VERBOSE: Property 3 is Prop3
VERBOSE: Property 1 is Prop11
VERBOSE: Property 2 is Prop22
VERBOSE: Property 3 is Prop33

Thanks a lot for the detail and clarity, I overlooked ByPropertyName and the simplicity that can provide.

It seems that shipping one object back at a time was still so much more efficient, the memory overhead dropped by over a magnitude of order and is significantly fast.

Thanks!