Start-Transcript:此主机不支持转录

时间:2011-02-17 17:03:51

标签: powershell

我想在Windows Server 2008 R2上启动脚本

Start-Transcript -path C:\Temp\test.txt
"Hello!"
Stop-Transcript

但PowerShell会返回以下错误消息:

  

Start-Transcript:此主机不支持转录。

如何激活成绩单?

7 个答案:

答案 0 :(得分:30)

Windows PowerShell v4 ISE及更低版本不支持转录。您必须使用命令行来运行命令行开关。

来自PowerShell v5,ISE本身支持Start-Transcript。

答案 1 :(得分:17)

完整答案(PowerShell ISE 2.0 / 4.0)::

今天又在另一台服务器上看到了这一点,我注意到最新的PowerShell ISE(也不允许使用Start-Transcript)没有Output窗格,而是使用新的ConsolePane。因此现在的功能如下:

Function Start-iseTranscript
{
  Param(
   [string]$logname = (Get-logNameFromDate -path "C:\fso" -postfix " $(hostname)" -Create)
  )

 $transcriptHeader = @"
**************************************
Windows PowerShell ISE Transcript Start
Start Time: $((get-date).ToString('yyyyMMddhhmmss'))
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
**************************************
Transcript started. Output file is $logname
"@
 $transcriptHeader >> $logname
 $psISE.CurrentPowerShellTab.Output.Text >> $logname

  #Keep current Prompt
  if ($Global:__promptDef -eq $null)
  {
    $Global:__promptDef =  (gci Function:Prompt).Definition
    $promptDef = (gci Function:Prompt).Definition
  } else
  {
    $promptDef = $Global:__promptDef
  }

  $newPromptDef = @'

if ($Host.Version.Major -eq 2)
{
  if ($Global:_LastText -ne $psISE.CurrentPowerShellTab.Output.Text)
  {
    Compare-Object -ReferenceObject ($Global:_LastText.Split("`n")) -DifferenceObject ($psISE.CurrentPowerShellTab.Output.Text.Split("`n"))|?{$_.SideIndicator -eq "=>"}|%{ 
$_.InputObject.TrimEnd()}|Out-File -FilePath ($Global:_DSTranscript) -Append
    $Global:_LastText = $psISE.CurrentPowerShellTab.Output.Text
  }
} elseif ($Host.Version.Major -eq 4)
{
  if ($Global:_LastText -ne $psISE.CurrentPowerShellTab.ConsolePane.Text)
  {
    Compare-Object -ReferenceObject ($Global:_LastText.Split("`n")) -DifferenceObject ($psISE.CurrentPowerShellTab.ConsolePane.Text.Split("`n"))|?{$_.SideIndicator -eq "=>"}|%{ 
$_.InputObject.TrimEnd()}|Out-File -FilePath ($Global:_DSTranscript) -Append
    $Global:_LastText = $psISE.CurrentPowerShellTab.ConsolePane.Text
  }
}

'@ + $promptDef
  $Global:_LastText = $psISE.CurrentPowerShellTab.Output.Text
  New-Item -Path Function: -Name "Global:Prompt" -Value ([ScriptBlock]::Create($newPromptDef)) -Force|Out-Null
}

接管提示对此非常有用,但保留输出缓冲区的两个副本并不理想。我还添加了TrimEnd(),因为PSISE 2.0喜欢附加空格来填充整个水平线宽。不确定PSISE 4.0是否也这样做,但现在无论如何都没问题。

NEW ANSWER(PowerShell ISE 2.0)::

我刚刚回到这个问题,并且有一种方法可以强制PowerShell ISE中的每个更新在执行命令时注销。这依赖于保存在名为_DSTranscript的全局变量中的日志路径。该变量传递给Start-iseTranscript函数。然后我劫持了Prompt函数来执行_LastText和hostUI输出文本之间的比较,并将差异追加到日志中。它现在有效。

Function Start-iseTranscript
{
  Param(
   [string]$logname = (Get-logNameFromDate -path "C:\fso" -postfix " $(hostname)" -Create)
  )
  $transcriptHeader = @"
**************************************
Windows PowerShell ISE Transcript Start
Start Time: $(get-date)
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
**************************************
Transcript started. Output file is $logname
"@
 $transcriptHeader >> $logname
 $psISE.CurrentPowerShellTab.Output.Text >> $logname

  #Keep current Prompt
  if ($__promptDef -eq $null)
  {
    $__promptDef =  (gci Function:Prompt).Definition
    $promptDef = (gci Function:Prompt).Definition
  } else
  {
    $promptDef = $__promptDef
  }

  $newPromptDef = @'
if ($global:_LastText -ne $psISE.CurrentPowerShellTab.Output.Text)
{
  Compare-Object -ReferenceObject $global:_LastText.Split("`n") -DifferenceObject $psISE.CurrentPowerShellTab.Output.Text.Split("`n")|?{$_.SideIndicator -eq "=>"}|%{ $_.InputObject.TrimEnd()}|Out-File -FilePath ($Global:_DSTranscript) -Append
  $global:_LastText = $psISE.CurrentPowerShellTab.Output.Text
}
'@ + $promptDef

  New-Item -Path Function: -Name "Global:Prompt" -Value ([ScriptBlock]::Create($newPromptDef)) -Force|Out-Null
}

原始答案::

PowerShell ISE不 原生 支持转录。有一个脚本专家blog about how to achieve this.不幸的是,这需要是在脚本中运行的最后一件事。这意味着您需要记住在关闭窗口之前运行它。我希望这更好用,或者有办法迫使它在关闭窗口时运行。

这是与Start-Transcript功能产生接近相同结果的函数:

Function Start-iseTranscript
{
  Param(
    [string]$logname = (Get-logNameFromDate -path "C:\fso" -name "log" -Create)
  )
  $transcriptHeader = @"
**************************************
Windows PowerShell ISE Transcript Start
Start Time: $(get-date)
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
**************************************
Transcript started. Output file is $logname
"@
  $transcriptHeader >> $logname
  $psISE.CurrentPowerShellTab.Output.Text >> $logname
} #end function start-iseTranscript

答案 2 :(得分:1)

要么接受你不能,要么使用支持成绩单的主机(如控制台主机:PowerShell.exe)。

答案 3 :(得分:0)

如果写入日志文件时出现问题,powershell.exe也会生成此错误。例如,如果日志文件是由管理员创建的,并且用户没有权限覆盖日志。

Start-Transcript : The host is not currently transcribing.
At D:\Test1.ps1:9 char:1
+ Start-Transcript -Path "$Source\logs\Test.txt"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (:) [Start-Transcript], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.StartTranscriptCommand

一个好的解决方案是尝试使用-Append或通过生成日期/时间戳使日志文件唯一。

Start-Transcript -Path "$Source\logs\Test.txt" -Append

这样就会生成正确的错误消息。

Access to the path 'D:\Test\logs\Test.txt' is denied.

-Force-Append具有相同的效果,并会生成权限错误。

答案 4 :(得分:0)

根据@richard here的提示,我创建了一个允许在需要时使用事务日志的代码段(计划任务),因此我在Windows 2008R2中结束了以下可以从PowerShell ISE运行的代码或作为一个独立的脚本。

  • 在ISE中运行时,日志信息将打印在屏幕上
  • 作为脚本运行时,日志信息将保存到文件
if ($Host.Name -eq "Windows PowerShell ISE Host") {
    $ISE=$true
} else {
    $ISE=$false
}


if (-Not $ISE) {
    $Date = Get-Date -f HHmmss_ddyyyy
    Start-Transcript -Path "C:\Temp\$Date.log"
}

//////////
code here ...
//////////

if (-Not $ISE) {
    Stop-Transcript
}

答案 5 :(得分:0)

标记@dwarfsoft的惊人答案和工作:     

if ($Host.Name -match 'ISE' -and $Host.version.Major -lt 4)
{
    #Start-Transcript will not work here. Use Start-iseTranscript by @dwarfsoft above
    Start-iseTranscript
}
else
{
    #Start Transcript Will work here
    Start-Transcript
}

答案 6 :(得分:0)

除了ISE(我注意到原始海报LaPhi甚至没有提到)外,导致此错误的另一件事是,如果您尝试在Invoke-Command脚本块中使用Start-Transcript。例如,如果您正在客户端计算机上运行脚本,然后通过Invoke-Command连接到Windows Server 2008 R2,则Start-Transcript将输出到服务器。

在本地会话中运行时,Start-Transcript可以按预期工作,但是,在使用Invoke-Command时,该脚本在该计算机上的远程会话中运行,并且远程会话具有某些限制,其中之一不支持转录。 / p>