我想在Windows Server 2008 R2上启动脚本
Start-Transcript -path C:\Temp\test.txt
"Hello!"
Stop-Transcript
但PowerShell会返回以下错误消息:
Start-Transcript:此主机不支持转录。
如何激活成绩单?
答案 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运行的代码或作为一个独立的脚本。
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>