powershellloggingpowershell-5.1

Why does redefining Write-Progress in PowerShell breaks the command?


I'm trying to catch all output of Write-Progress to a log file using Write-PSFMessage from the module PSFramework in a way that I don't need to rewrite all my current scripts.

I've used this method successfully for Write-Verbose and Write-Host (edit: apparently not), but when applying the code below to Write-Progress, it will hang...

function Write-MyProgress {
  param (
    [Parameter(Mandatory)]
    [string]$Activity,
    [string]$Status = 'Processing'
  )

  $params = @{
    Activity = $Activity
    Status   = $Status
  }
  Write-Progress @params

  $LogMessage = "PROGRESS: $Activity - $Status"
  Write-PSFMessage -Level SomewhatVerbose -Message $LogMessage
}

Set-Alias Write-Progress -Value Write-MyProgress

Solution

  • Reference the built-in cmdlet by module-qualified name or reference to avoid calling yourself recursively once the alias takes effect:

    function Write-MyProgress {
      param (
        [Parameter(Mandatory)]
        [string]$Activity,
        [string]$Status = 'Processing'
      )
    
      $params = @{
        Activity = $Activity
        Status   = $Status
      }
    
      # module-qualified command name
      Microsoft.PowerShell.Utility\Write-Progress @params
    
      $LogMessage = "PROGRESS: $Activity - $Status"
      Write-PSFMessage -Level SomewhatVerbose -Message $LogMessage
    }
    

    Additionally, you may want to use the $PSBoundParameters automatic variable as the splatting target - this way you'll not only be passing bound -Activity and -Status arguments, but common parameter arguments too (-Debug, -OutVariable, -ProgressAction etc.):

    function Write-MyProgress {
      param (
        [Parameter(Mandatory)]
        [string]$Activity,
        [string]$Status = 'Processing'
      )
    
      # module-qualified command name
      Microsoft.PowerShell.Utility\Write-Progress @PSBoundParameters
    
      $LogMessage = "PROGRESS: $Activity - $Status"
      Write-PSFMessage -Level SomewhatVerbose -Message $LogMessage
    }