【问题标题】:How can I redirect PowerShell output when run from Task Scheduler?从任务计划程序运行时如何重定向 PowerShell 输出?
【发布时间】:2012-11-26 21:19:16
【问题描述】:

从任务计划程序运行简单的 PowerShell 脚本时,我想将输出重定向到文件。

关于这个话题here 有一个很长的帖子,但不清楚他们最终是否找到了最合适的解决方案。我很想知道 StackOverflow 上是否有人也解决了这个问题,他们是如何解决的?

【问题讨论】:

    标签: powershell scheduled-tasks line-endings


    【解决方案1】:

    我使用转录功能来帮助解决这个问题。只需将其包含在您的代码中,它就会将所有(可能是)屏幕内容输出到日志文件中。

    Start-Transcript -path $LogFile -append
    
    <Body of the script>
    
    Stop-Transcript
    

    【讨论】:

    • 当我启动命令表单任务计划程序(作为 powershell.exe 的参数)时,我看到脚本的不同行为。具体来说,对 Write-Host 的调用似乎将我的文本发送到脚本没有捕获的地方,尽管重定向到 Out-Host 似乎有效。如果这很重要,我正在 Windows Server 2012 R2 上运行 PowerShell 4.0。
    • 我不得不使用 Write-Output 而不是 Write-Host。
    • @JayCarlton 你不应该使用 write-host 而是 write-output,因为 powershell 的创建者说:jsnover.com/blog/2013/12/07/write-host-considered-harmful 说,我还没有测试它是否会对你的日志产生影响,但它应该.
    • 酷,我的 powershell 脚本似乎也没有在任务计划程序的注册表中做任何事情(由于权限),或者它可以在启用上述日志记录的情况下写入磁盘。以我的用户身份运行,无论是否有“以最大?功能?权限运行?”
    • 我看到的一个问题是,如果我试图在管道中的 foreach 对象期间捕获写入主机输出,我无法将其切换为写入输出,否则它会写入成功输出流
    【解决方案2】:

    这是对我有用的命令。我不喜欢在脚本中重定向输出的想法,因为这会使手动运行变得困难。

    powershell -windowstyle minimized -c "powershell -c .\myscript.ps1 -verbose >> \\server\myscript.log 2>&1"
    

    【讨论】:

    • 您可能还想使用 -Noninteractive 以避免任何提示。
    • 如何给这个添加时间戳?
    • 如果有人知道如何使用文件路径中的空格来执行此操作,我很想知道如何。我无法让解析器正确解析双引号、单引号或转义引号。
    • 这看起来像是从 powershell 中调用 powershell?
    • 是的,就像@JamieHanrahan 注意到的那样,两次调用 powershell 的目的是什么?
    【解决方案3】:

    以下内容适用于 Windows 7:

     powershell -command c:\temp\pscript.ps1 2>&1 > c:/temp/apickles.log
    

    在 Windows 7 任务计划程序 GUI 中:

     program = "Powershell"
     arguments = "-command c:\temp\pscript.ps1 2>&1 > c:/temp/apickles.log"
    

    请注意,“-file”不起作用,因为文件名之后的所有参数都被解释为文件的参数。 请注意,“2>&1”也将错误输出重定向到日志文件。更高版本的 PowerShell 以稍微不同的方式执行此操作。

    【讨论】:

    • 感谢您对 Windows 7 任务计划程序 GUI“参数”的评论 - 我想这是放置输出重定向选项的正确位置。其他答案都没有提到这一点。
    • -1 用于 win10。它在 Windows 10 中对我不起作用。这篇文章有同样的问题。 social.technet.microsoft.com/Forums/windowsserver/en-US/…
    • “-Command”的一个缺点是它会被解释,因此 ps1 文件路径中的空格或任何可解释的东西都会把它变成一个错误。所以最好单独设置工作目录,只为-Command使用(非特殊字符)文件名。
    • 在 GUI 中,不要将引号放在输入字段中,只在它们之间添加引号(上图)。使用工作目录而不是日志文件的路径。
    【解决方案4】:

    之前所有答案的组合确实帮助了我......

    我的问题是我需要在 WinRM 上执行一个 PowerShell 脚本作为 Packer 配置程序的一部分,并且由于权限问题而一直失败。解决此问题的方法是作为计划任务执行,但我需要将参数传递给脚本并获取输出以确认所有内容已通过。

    这个 sn-p 对我很有效:

    # Generate a unique ID for this execution
    $guid = [guid]::NewGuid()
    $logFile = "C:\Windows\Temp\$guid.log"
    
    $argument = "-NoProfile -ExecutionPolicy unrestricted -Command ""& {""$ScriptPath"" $ScriptArgs} 2>&1 > $logFile"""
    
    $a = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $argument
    Register-ScheduledTask -TaskName $TaskName  -RunLevel Highest -User $username -Password $password -Action $a | Start-ScheduledTask
    do {
        Start-Sleep -Seconds 30
        $task = Get-ScheduledTask -TaskName $TaskName
    } while ($task.State -eq 4)
    

    完整的脚本可以在这里找到:

    https://gist.github.com/dev-rowbot/fa8b8dadf1b3731067a93065db3e1bba

    【讨论】:

      【解决方案5】:

      我愿意:
      创建一个函数来调用您的脚本并重定向此函数的输出,如下所示:

      .ps1:

      function test{
          # Your simple script commands
          ls c:\temp -Filter *.JPG
          ls z:\ # Non-existent directory
      }
      
      test *> c:\temp\log.txt
      

      这是日志文件:

          Répertoire : C:\temp
      
      
      Mode                LastWriteTime     Length Name
      ----                -------------     ------ ----
      -a---        07/06/2008     11:06     176275 HPIM1427.JPG
      -a---        07/06/2008     11:06      69091 HPIM1428.JPG
      -a---        07/06/2008     11:06     174661 HPIM1429.JPG
      
      
      ls : Lecteur introuvable. Il n'existe aucun lecteur nommé « z ».
      Au caractère C:\temp\test.ps1:14 : 1
      + ls z:\ #non existent dir
      + ~~~~~~
          + CategoryInfo          : ObjectNotFound: (z:String) [Get-ChildItem], Driv
         eNotFoundException
          + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetC
         hildItemCommand
      

      您可以使用新的 V3 重定向运算符控制要输出的内容:

      Do-Something 3> warning.txt  # Writes warning output to warning.txt
      Do-Something 4>> verbose.txt # Appends verbose.txt with the verbose output
      Do-Something 5>&1            # Writes debug output to the output stream
      Do-Something *> out.txt      # Redirects all streams (output, error, warning, verbose, and debug) to out.txt
      

      【讨论】:

      • 但是 *> 从计划任务运行时有效吗?因为这个问题暗示它没有。
      【解决方案6】:

      使用Start-Transcript 直接登录到文件可能更容易:

      # Get script name
      $ScriptFullPath = $MyInvocation.MyCommand.Path
      # Start logging stdout and stderr to file
      Start-Transcript -Path "$ScriptFullPath.log" -Append
      
      [Some PowerShell commands]
      
      # Stop logging to file
      Stop-Transcript
      

      日志文件将与脚本位于同一目录中。

      【讨论】:

        【解决方案7】:

        我在 Windows Server 2016 上测试了以下内容,只调用了一次 powershell。这样您就可以使用带空格的文件夹名称:

        Powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle minimized "scriptName.ps1 *>> '\\servername\sharename\folder name with space\logfilename.log'"
        

        【讨论】:

          【解决方案8】:

          我受到来自 Anders 的评论问题(如何添加时间戳?)以及调用 PowerShell 两次的多个回复的启发来写这个答案,我认为这不是必需的。任务调度程序显然是“powershell.exe”,对于参数我建议简单:

          -noninteractive -c "scriptpath.ps1 *>>logpath.txt"
          

          要每天保存一个文件,那么:

          -noninteractive -c "scriptpath.ps1 *>>logpath-$((get-date).ToString('yyyy-MM-dd')).txt"
          

          如果您确实想要一个带有时间戳的日志文件,您可以删除第二个“>”(两个表示附加到任何现有文件)并扩展时间格式:

          -noninteractive -c "scriptpath.ps1 *>logpath-$((get-date).ToString('yyyy-MM-dd_HH-mm-ss-fff')).txt"
          

          【讨论】:

            【解决方案9】:

            PowerShell 3 及更高版本允许重定向单个流(out、verbose 和 error)。但是,任务计划程序不理解它们。执行重定向的是 PowerShell。

            @cmcginty's solution 中途工作,因为 PowerShell 正在调用 PowerShell。它只支持标准流(错误和输出)。如果你想使用你需要使用的所有流:

            程序或脚本:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

            参数:-windowstyle minimized –NonInteractive –NoProfile -c "powershell -c path_to_ps1.ps1 4&gt;&gt;verbose.log 5&gt;&gt;debug.log"

            开始于:path_to_ps1

            【讨论】:

              【解决方案10】:

              下面将详细输出发送到屏幕并将其记录到文件中。

              something you're doing -Verbose 4>&1 | Tee-Object "C:\logs\verb.log" -Append
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-08-07
                • 1970-01-01
                • 2019-10-31
                • 2017-05-28
                • 1970-01-01
                • 2017-07-07
                • 1970-01-01
                • 2017-08-22
                相关资源
                最近更新 更多