title: Stream output from external command from inside a powershell function
body: <p>Consider the following command:</p>
  
  <pre><code>7z.exe a -t7z folder.7z folder
  </code></pre>
  
  <p>I have the following two stripped down powershell scripts</p>
  
  <p>File 1: common.ps1</p>
  
  <pre><code>function Archive-Folder ($src, $dest_path, $archive_name) {
  
      $script_dir = split-path $script:MyInvocation.MyCommand.Path
  
      if ((test-path $src) -eq $false) {
          write-error "$src is not a valid source directory"
          #return
          return $false
      }
  
      if ((test-path $dest_path) -eq $false) {
          write-error "$dest_path is not a valid destination directory"
          #return
          return $false
      }
  
      if ([string]::IsNullOrWhiteSpace($archive_name) -eq $true) {
          write-error "$archive_name is not a valid archive name"
          #return
          return $false
      }
  
      write-verbose "archiving the folder"
  
      $archive_command = "$script_dir\7z.exe a -t7z $dest_path\$archive_name $src"
  
      $exe = "$script_dir\7z.exe"
      $arguments = @('a', '-t7z', "$dest_path\$archive_name", "$src")
  
      iex $archive_command
  
      # this doesn't stream the output. it prints it all at once.
      # &amp; $exe $arguments | write-verbose
  
      return $true
  }
  </code></pre>
  
  <p>File 2: script.ps1</p>
  
  <pre><code>$script_dir = split-path $script:MyInvocation.MyCommand.Path
  . "$script_dir\common.ps1"
  
  $VerbosePreference = "Continue"
  
  $src = 'C:\some\source'
  $backup_path = 'C:\some\destination'
  $date_format = 'yyyy_MM_dd_HHmm'
  $date = get-date
  $date_str = $date.tostring($date_format)
  $date_ticks = $date.ticks
  $archive_name = "backup-$date_str-$date_ticks.7z"
  
  # this prints the output streamed. The output ends with `True`
  archive-folder $src $backup_path $archive_name 
  
  # the following however doesn't output anything. in order to separate the command output from my function output, 
  # i was printing the command output using write-verbose
  $isSuccess = archive-folder $src $backup_path $archive_name
  if ($isSuccess -eq $true) {
      #proceed with the rest of the code
  }
  </code></pre>
  
  <p>With inputs from @Christian &amp; @zdan, I was able to isolate the issue to the capturing of the return value. Similar to <code>archive-folder</code>, I have other functions that execute some commandline tool. I was thinking that each of these functions can return a true or false depending on whether the function was called with the right operations and the commandline tool executed properly.</p>
  
  <p>However, if I capture the return value of my <code>archive-folder</code> function, then the output of the command doesn't get printed to the console. Also, my return value doesn't consist of a true or false value. It consists of the entire output of the command.</p>
  
  <p>My first attempt at solving this was to write the command execution statement as <code>iex $archive_command | write-verbose</code>, but this did not stream the output.</p>
  
  <p>I suppose I can check for side effects the commandline tool has in case of success (like presence of the archive file) to determine whether my function executed successfully, but am not sure if I will be able to do this for all functions that I may end up creating.</p>
  
  <p>Is there a way to return a value and also stream the output of a commandline tool?</p>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>With regards to why am I diving the code into two separate files/functions, my actual use scenario is as follows</p>
  
  <blockquote>
    <p>The <code>script.ps1</code> will be coordinating this flow. Backup the database (mongodb generates files for each collection of the db). Archive the database backup. Upload the archive to S3. Each of these steps will be done by a separate function in <code>common.ps1</code>. The <code>script.ps1</code> will only contain the glue code. Posting all this might have complicated the question and I felt wasn't needed to understand the issue am facing</p>
  </blockquote>
  
  <p><strong>EDIT 1</strong></p>
  
  <p>If the folder being compressed has 5 files, 7zip will first output the copyright. Then it will output the text <code>Scanning</code>. Then it will output a line <code>Creating archive at some location</code>. Then it will process each file, outputting the progress for each file, one by one. This way, we get constant feedback about the progress of the operation.</p>
  
  <p>If I execute the powershell function, then I see no output for the duration of the operation and then all the output at once. I get no feedback from 7zip. I would like to simulate the behaviour that 7zip shows when ran as a standalone exe. </p>