Optimizing Exchange command invocation

Welcome Forums General PowerShell Q&A Optimizing Exchange command invocation

Viewing 2 reply threads
  • Author
    Posts
    • #211842
      Participant
      Topics: 10
      Replies: 17
      Points: 15
      Rank: Member

      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?

    • #211956
      Participant
      Topics: 12
      Replies: 1615
      Points: 2,530
      Helping Hand
      Rank: Community Hero

      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
      
    • #212043
      Participant
      Topics: 10
      Replies: 17
      Points: 15
      Rank: Member

      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!

Viewing 2 reply threads
  • You must be logged in to reply to this topic.