PowerShell: how to capture (or suppress) write-host

后端 未结 3 1988
清酒与你
清酒与你 2021-01-20 00:37

I have a script call \"a.ps1\":

write-host \"hello host\"
\"output object\"

I want to call the script and obtain the output object, but I a

3条回答
  •  [愿得一人]
    2021-01-20 00:45

    OK, I did a little digging over it. You can use:

    The Following Link

    And do:

    $result = .\1.ps1 | Select-WriteHost -Quiet
    $result[1]
    

    And then select the second object in the variable:

    Another explanation

    You can also change the script in a way that will not change Write-Host to Write-Output and just "remove" the Write-Host.

    Done...

    function Remove-WriteHost
    {
       [CmdletBinding(DefaultParameterSetName = 'FromPipeline')]
       param(
         [Parameter(ValueFromPipeline = $true, ParameterSetName = 'FromPipeline')]
         [object] $InputObject,
    
         [Parameter(Mandatory = $true, ParameterSetName = 'FromScriptblock', Position = 0)]
         [ScriptBlock] $ScriptBlock
       )
    
       begin
       {
         function Cleanup
         {
           # Clear out our proxy version of Write-Host
           remove-item function:\write-host -ea 0
         }
    
         function ReplaceWriteHost([string] $Scope)
         {
             Invoke-Expression "function ${scope}:Write-Host { }"
         }
    
         Cleanup
    
         # If we are running at the end of a pipeline, need to
         # immediately inject our version into global scope,
         # so that everybody else in the pipeline uses it.
         #
         # This works great, but it is dangerous if we don't
         # clean up properly.
         if($pscmdlet.ParameterSetName -eq 'FromPipeline')
         {
            ReplaceWriteHost -Scope 'global'
         }
       }
    
       process
       {
          # If a scriptblock was passed to us, then we can declare
          # our version as local scope and let the runtime take it
          # out of scope for us. It is much safer, but it won't
          # work in the pipeline scenario.
          #
          # The scriptblock will inherit our version automatically
          # as it's in a child scope.
          if($pscmdlet.ParameterSetName -eq 'FromScriptBlock')
          {
            . ReplaceWriteHost -Scope 'local'
            & $scriptblock
          }
          else
          {
             # In a pipeline scenario, just pass input along
             $InputObject
          }
       }
    
       end
       {
          Cleanup
       }
    }
    $result = .\1.ps1 | Remove-WriteHost
    

    Thanks to "latkin" for the original function :)

提交回复
热议问题