title: How to Pass Multiple Objects via the Pipeline Between Two Functions in Powershell
body: <p>I am attempting to pass a list of objects from one function to another, one by one.</p>
  
  <p><strong>First function</strong>: generate a list of users (objects) near expiry;
     <strong>Second function</strong>: send an email to each user (object)</p>
  
  <p>The first function works fine and outputs a group of objects (or so it would seem) and the second function will accept input and email a single user without issue. </p>
  
  <p>Issues arise only when multiple objects are passed from the first function to the second.</p>
  
  <p><strong>Relevant code snippets are below:</strong></p>
  
  <p>The First function creates a custom object for each located user and adds it to an array, which is then outputted in the end block. Below is an extremely simplified snippet of the code with the essential object creation step:</p>
  
  <pre><code>Function 01
  {
      #param block goes here etc...
  
      Foreach ($user in $users)
      {
          $userOutput = @()
  
          $userTable = New-Object PSObject -Property @{
              name = $User.Name
              SamAccountName = $User.SamAccountName
              emailAddress = $User.EmailAddress
              expired = $user.PasswordExpired
              expiryDate = $ExpiryDate.ToShortDateString()
              daysTillExpiry = $daysTillExpiry
              smtpRecipientAddress = $User.EmailAddress
              smtpRecipientName = $User.Name
          }
  
          $userOutput += $userTable
      }
  
      Write-Output $userOutput
  }
  </code></pre>
  
  <p>I have also tried writing each custom object ($userTable) straight to the console within each iteration of the Foreach (users) loop.</p>
  
  <p>The Second function accepts pipeline input for a number of matching parameters from the first function, e.g:</p>
  
  <pre><code>[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)][string]$smtpRecipientName
  </code></pre>
  
  <p>The second function also calls a third function designed specifically to send smtp mail and contains no loops, it just takes the current object from the pipeline and deals with it.</p>
  
  <p>I haven't included the full code for either mail function because it is largely irrelevant. I just want to know whether the objects outputted from the first function can be dealt with one-by-one by the second. </p>
  
  <p>At present, the mail function deals with the first object passed to it, and no others.</p>
  
  <p><strong>Update:</strong></p>
  
  <p>This is what I have in mind (but the second function only deals with the last object that was piped in:</p>
  
  <pre><code>Function Test-UserExp
  {
      $iteration = 0
  
      For ($i=0;$i -le 9;$i++)
      {
          $iteration ++
          $userTable = New-Object PSObject -Property @{
              expiryDate = "TestExpDate_$iteration"
              daysTillExpiry = "TestDaysTillExpiry_$iteration"
              smtpRecipientAddress = "TestSMTPRecipientAddress_$iteration"
              smtpRecipientName = "TestSMTPRecipientName_$iteration"
          }
  
          $userTable
      }
  }
  
  Function Test-MailSend
  {
      Param
      (
          [Parameter(ValueFromPipelineByPropertyName=$true)][string]$expiryDate,
          [Parameter(ValueFromPipelineByPropertyName=$true)][string]$daysTillExpiry,
          [Parameter(ValueFromPipelineByPropertyName=$true)][string]$smtpRecipientAddress,
          [Parameter(ValueFromPipelineByPropertyName=$true)][string]$smtpRecipientName
      )
  
      Write-Host 'Output from Test-MailSend:'
  
      $expiryDate
      $daysTillExpiry
      $smtpRecipientAddress  
      $smtpRecipientName
  
  
  }
  </code></pre>