Перенаправить операторы Write-Host в файл - PullRequest
16 голосов
/ 08 апреля 2011

У меня есть сценарий powershell, который я отлаживаю и хочу перенаправить все операторы write-host в файл.Есть ли простой способ сделать это?

Ответы [ 12 ]

16 голосов
/ 22 апреля 2011

До PowerShell 4.0, Write-Host отправляет объекты на хост. Он не возвращает никаких объектов.

Начиная с PowerShell 5.0 и новее, Write-Host - это оболочка для Write-Information, которая позволяет выводить в поток информации и перенаправлять его с помощью 6>> file_name.

http://technet.microsoft.com/en-us/library/hh849877.aspx

Однако, если у вас много операторов Write-Host, замените их все на Write-Log, что позволяет вам решать, выводить ли в консоль, файл или журнал событий, или все три.

Проверьте также:

14 голосов
/ 20 августа 2012

Вы можете создать прокси-функцию для Write-Host, которая отправляет объекты в стандартный поток вывода, а не просто печатает их.Я написал ниже командлет только для этой цели.Он создаст прокси на лету, который длится только на время текущего конвейера.

Полная запись в моем блоге здесь , но я включил код ниже.Используйте переключатель -Quiet для подавления записи консоли.

Использование:

PS> .\SomeScriptWithWriteHost.ps1 | Select-WriteHost | out-file .\data.log  # pipeline usage
PS> Select-WriteHost { .\SomeScriptWithWriteHost.ps1 } | out-file .\data.log  # scriptblock usage (safer)

function Select-WriteHost
{
   [CmdletBinding(DefaultParameterSetName = 'FromPipeline')]
   param(
     [Parameter(ValueFromPipeline = $true, ParameterSetName = 'FromPipeline')]
     [object] $InputObject,

     [Parameter(Mandatory = $true, ParameterSetName = 'FromScriptblock', Position = 0)]
     [ScriptBlock] $ScriptBlock,

     [switch] $Quiet
   )

   begin
   {
     function Cleanup
     {
       # clear out our proxy version of write-host
       remove-item function:\write-host -ea 0
     }

     function ReplaceWriteHost([switch] $Quiet, [string] $Scope)
     {
         # create a proxy for write-host
         $metaData = New-Object System.Management.Automation.CommandMetaData (Get-Command 'Microsoft.PowerShell.Utility\Write-Host')
         $proxy = [System.Management.Automation.ProxyCommand]::create($metaData)

         # change its behavior
         $content = if($quiet)
                    {
                       # in quiet mode, whack the entire function body, simply pass input directly to the pipeline
                       $proxy -replace '(?s)\bbegin\b.+', '$Object' 
                    }
                    else
                    {
                       # in noisy mode, pass input to the pipeline, but allow real write-host to process as well
                       $proxy -replace '(\$steppablePipeline\.Process)', '$Object; $1'
                    }  

         # load our version into the specified scope
         Invoke-Expression "function ${scope}:Write-Host { $content }"
     }

     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 dangerous if we don't clean up properly.
     if($pscmdlet.ParameterSetName -eq 'FromPipeline')
     {
        ReplaceWriteHost -Quiet:$quiet -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.  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 -Quiet:$quiet -Scope 'local'
        & $scriptblock
      }
      else
      {
         # in pipeline scenario, just pass input along
         $InputObject
      }
   }

   end
   {
      Cleanup
   }  
}
7 голосов
/ 23 декабря 2011

Использование перенаправления приведет к зависанию Write-Host.Это связано с тем, что Write-Host имеет дело с различными проблемами форматирования, которые характерны для текущего используемого терминала.Если вы просто хотите, чтобы ваш скрипт имел гибкость для вывода в обычном режиме (по умолчанию для оболочки, с возможностью>, 2> и т. Д.), Используйте Write-Output.

В противном случае, если вы действительно хотите уловить особенноститекущего терминала, Start-Transcript - хорошее место для старта.В противном случае вам придется пройти тестирование вручную или написать несколько сложных наборов тестов.

5 голосов
/ 24 февраля 2016

Вы можете запустить свой скрипт во вторичной оболочке PowerShell и записать вывод следующим образом:

powershell -File 'Your-Script.ps1' > output.log

Это сработало для меня.

3 голосов
/ 10 октября 2014

Это сработало для меня в моем первом скрипте powershell, который я написал несколько дней назад

function logMsg($msg)
{
    write-output $msg
    write-host $msg 
}

использование в скрипте:

logMsg("My Error Msg")
logMsg("My Info Msg")

вызов выполнения сценария powershell:

ps> .\myFirstScript.ps1 >> testOutputFile.txt

Это не совсем ответ на этот вопрос, но он может помочь кому-то, пытающемуся добиться как регистрации в консоли, так и вывода в некоторый файл журнала, делая то, что я достиг здесь:)

2 голосов
/ 08 апреля 2011

Определить функцию под названием Write-Host. Пусть это записать в файл. У вас могут возникнуть проблемы, если в некоторых вызовах используется странный набор аргументов. Кроме того, это будет работать только для вызовов, которые не квалифицированы Snapin.

1 голос
/ 08 апреля 2011

Только что добавили Start-Transcript вверху скрипта и Stop-Transcript внизу. Выходной файл должен был называться <folder where script resides>-<datestamp>.rtf, но по какой-то причине файл трассировки был помещен туда, где я этого не ожидал & mdash; рабочий стол!.

0 голосов
/ 13 марта 2019

Если у вас всего несколько операторов Write-Host, вы можете использовать оператор перенаправления "6>>" в файл:

Write-Host "Your message." 6>> file_path_or_file_name

Это «Пример 5: Подавить вывод от Write-Host» , предоставленный Microsoft, измененный соответственно на about_Operators .

0 голосов
/ 24 февраля 2017

Попробуйте использовать запись-вывод вместо write-host.

Вывод идет по конвейеру, но если это конец конвейера, он отправляется на консоль.

>write-output "test"
test
>write-output "test" > foo.txt
>get-content foo.txt
test
0 голосов
/ 03 февраля 2017

Используйте Write-Output вместо Write-Host и перенаправьте его в файл, подобный этому:

Deploy.ps1> mylog.log или Write-Output "Hello World!"> mylog.log

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...