I want to start a transcript on a Windows Server 2008 R2
Start-Transcript -path C:\\Temp\\test.txt
\"Hello!\"
Stop-Transcript
But PowerShe
In addition to the ISE (which I note the original poster LaPhi doesn't even mention), the other thing that can cause this error is if you're trying to use Start-Transcript within an Invoke-Command scriptblock. For instance if you're running the script on your client machine, and then connecting to the Windows Server 2008 R2 box via Invoke-Command so Start-Transcript outputs to the server.
When run in the local session Start-Transcript works as expected, however when using Invoke-Command the script is run within a remote session on that computer, and remote sessions have certain limitations, one of which is not supporting transcription.
COMPLETE ANSWER (PowerShell ISE 2.0/4.0)::
Having yet another look at this today on another server, I noticed that the latest PowerShell ISE (which also does not allow Start-Transcript) does not have an Output pane, and instead uses the new ConsolePane. Thus the function now is as follows:
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
}
Taking over the prompt is incredibly useful for this, however keeping two copies of the Output buffer is not ideal. I've also added in TrimEnd() as PSISE 2.0 likes to append spaces to fill the entire horizontal line width. Not sure if PSISE 4.0 does this too, but it's no problem now anyway.
NEW ANSWER (PowerShell ISE 2.0)::
I have just recently returned to this problem, and there is a way of forcing every update in PowerShell ISE to log out as a command is executed. This relies on the log path being saved in a Global Variable called _DSTranscript. This variable is passed to the Start-iseTranscript function. I have then Hijacked the Prompt function to execute a compare between _LastText and the hostUI Output Text, and append the differences out to the log. It now works a treat.
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
}
ORIGINAL ANSWER::
PowerShell ISE does not natively support Transcription. There is a Scripting Guy blog about how to achieve this. Unfortunately this needs to be the last thing that is run in the script. This means that you need to remember to run it before closing the window. I wish this worked better, or there was a way to force it to run on window closure.
This is the function that produces close to the same result as the Start-Transcript feature:
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
The powershell.exe
will also generate this error if there is a problem writing to the log file. For example, if the log file was created by an administrator and the user doesn't have permissions to overwrite the log.
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
A good solution is to try using -Append
or to make the log file unique by generating a date/time stamp.
Start-Transcript -Path "$Source\logs\Test.txt" -Append
This way a proper error message is generated.
Access to the path 'D:\Test\logs\Test.txt' is denied.
-Force
has the same effect as -Append
and will generate a permissions error.
Tagging on to the amazing answer and work by @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
}
Either accept you can't, or use a host that does support transcripts (like the console host: PowerShell.exe
).
Windows PowerShell v4 ISE and lower do not support transcription. You must use the command line to run the commandlet.
From PowerShell v5 Start-Transcript is supported natively in ISE.