I've been having a weird performance issue with some Powershell that I encountered while writing a automation script to test my application. The automation script was working fine - running the app until it crashed, zipping the logs, and going again - until I needed to capture verbose app logs (we're talking potentially gigabytes of logs after the tests are done!)
function SplitFile {
param (
[ValidateScript({Test-Path $_})]
$path = "textwriteroutput.log"
)
$file = get-item $path
$parent = Split-Path $file
$Extension = [System.IO.Path]::GetExtension($file)
$Name = [System.IO.Path]::GetFileNameWithoutExtension($file)
$dir = mkdir (Join-Path -Path $parent -ChildPath $Name)
[int]$count = 0
[int]$lines = 0
$linesplit = 20000
$reader = [System.IO.StreamReader]::new($file)
$outFilePath = Join-Path -Path $dir -ChildPath "${name}_$count.$extension"
$writer = [System.IO.StreamWriter]::new($outFilePath)
try {
while ( $line = $reader.ReadLine() ) {
$lines++
$writer.WriteLine("$line")
if ( $lines -ge $linesplit ) {
$lines = 0
$writer.Flush()
$writer.Close()
$count++
$outFilePath = Join-Path -Path $dir -ChildPath "${name}_$count.$extension"
$writer = [System.IO.StreamWriter]::new($outFilePath)
}
}
}
finally {
$writer.Close()
$reader.Close()
}
return $dir
}
I was running the automation script from a powershell console window in a VM accessed through an RDP session since some aspects of the automation require a "screen" to move mouse, click, and screenshot. When the code got to this function though to split a large log file into smaller chunks, it slowed down tremendously, to the point where it was taking about a minute per KB to break the log file down.
After many iterations on trying to figure out why the code was so slow I ended up breaking the split code into its own file, and found something odd - if I ran the same SplitFile function in a remote pssession from my laptop (e.g. enter-psssession), it ran reasonably fast. If I ran SplitFile from the VM's powershell console - just the function loaded from a file in a fresh Powershell console window- it ran slow.
I know if I want performance I should write a native app, but the PoSH-in-pssession gives good enough performance. I did end up writing an exe to split the files, but the next step in the script is Compress-Archive and that's also running slow, I presume for the same reason. What's different about a enter-pssession Powershell prompt from a remote machine that makes file I/O go so much faster than the Powershell console in the VM-RDP desktop? Is there a way from the script running with a screen to get the same I/O performance as from the pssession console?