问题
I have a PowerShell script, but some of the output gets cut at an arbitrary point before continuing on the next line. This is incredibly annoying.
For example, I can use Write-Host
and the line will continue on as long as I want it (note, that is running in Team City and Team City adds some prefix information - however the same effect can be observed piping the output to a file):
[10:04:45] [Step 5/7] - Found Windows Service at G:\TeamCityData\TeamCityBuildAgent-1\work\282b8abc9094651e\Artefacts\windows-services\WindowsService.Dummy\WindowsService.DummyService.exe
Other times, the output will seem to artificially truncate at an arbitrary point, like it was wrapping within a window (which isn't there).
So, this line:
Copy-Item -Path $fullSourcePath -Destination $destPath -Recurse -Verbose -ErrorAction Stop
Produces this output in Team City (which adds some prefix information):
[10:04:46] [Step 5/7] VERBOSE: Performing the operation "Copy File" on target "Item:
[10:04:46] [Step 5/7] G:\TeamCityData\TeamCityBuildAgent-1\work\282b8abc9094651e\Artefacts\windows-services\WindowsService.Dummy\WindowsServi
[10:04:46] [Step 5/7] ce.DummyService.exe Destination:
[10:04:46] [Step 5/7] \\SERVER001\scheduled-tasks\ProductFolder\Dev\DummyWindowsService\WindowsService.DummyService.exe".
[10:04:46] [Step 5/7] VERBOSE: Performing the operation "Copy File" on target "Item:
[10:04:46] [Step 5/7] G:\TeamCityData\TeamCityBuildAgent-1\work\282b8abc9094651e\Artefacts\windows-services\WindowsService.Dummy\WindowsServi
[10:04:46] [Step 5/7] ce.DummyService.exe.config Destination:
[10:04:46] [Step 5/7] \\SERVER001\scheduled-tasks\ProductFolder\Dev\DummyWindowsService\WindowsService.DummyService.exe.config".
How do I stop this absurdity? I want the output to render line breaks correctly at the end of the line, not in the middle of a filename.
UPDATE
A comment below suggested this was an issue with the way TeamCity was capturing the output. However, the same issue happens if I do a similar command directly in a PowerShell console and pipe the output to a file.
The command:
copy-item -Path F:\logs -Destination .\ -Recurse -Verbose *> F:\logs\copy-item-output-1.txt
Produces output like this:
Performing the operation "Copy File" on target "Item: F:\logs\20161103-140649-ProductName.Program.log
Destination: F:\Destination\1234567890abcdefghijklmnopqrstuvwxyz\this-is-a-long-path-name-to-show-wrapping-issues-with-copy-it
em\logs\20161103-140649-ProductName.Program.log".
As you can see, it also splits the file path across lines, even although it is being sent to a file, not the console window.
回答1:
The following solution (more than 10 years old so there might exist a smarter way recently?) works in both PowerShell and PowerShell ISE:
$pshost = get-host
$pswindow = $pshost.ui.rawui
$newsize = $pswindow.buffersize
### do not change $newsize.height
$newsize.width = 3000 ### [int] type; max. value unknown at present
$pswindow.buffersize = $newsize
回答2:
You can redirect other stream to output stream to provide custom handling for verbose and other types of output:
& {
#Script code here
Copy-Item -Path $fullSourcePath -Destination $destPath -Recurse -Verbose -ErrorAction Stop
} *>&1 | % {
function IsStreamType {
param($Object, $Type)
$Property = $_.PSObject.Properties[$Type]
$null -ne $Property -and $Property.Value -is [bool] -and $Property.Value
}
} {
switch(,$_) {
{
$_ -is [System.Management.Automation.DebugRecord] -and
(IsStreamType $_ WriteDebugStream)
} {
"Debug message: $($_.Message)"
}
{
$_ -is [System.Management.Automation.VerboseRecord] -and
(IsStreamType $_ WriteVerboseStream)
} {
"Verbose message: $($_.Message)"
}
{
$_ -is [System.Management.Automation.WarningRecord] -and
(IsStreamType $_ WriteWarningStream)
} {
"Warning message: $($_.Message)"
}
default { ,$_ }
}
}
I use ,$_
instead of plain $_
as precaution to prevent PowerShell unrolling behavior in case $_
happens to be collection object.
来源:https://stackoverflow.com/questions/41504786/powershell-putting-linebreaks-inappropriate-places-in-output