I'm using powershell to write and read log files.
One script is generating a log file with Add-Content. Another script is tailing the log file, using Get-Content -Wait. This seems like it should be pretty reliable.
However, the writer is frequently unable to write, and the reader is frequently unable to read and gives up. I can only assume these two commands aren't opening the file with the appropriate access flags, and so they're fighting each other.
Here's a nasty little script that demonstrates the problem with two jobs in the same process, although the same happens between different powershell processes:
$writer = start-job -ScriptBlock {
foreach($i in 1..500)
{
"$i" | Add-Content "c:\temp\blah.txt"
Sleep -Milliseconds 10
}
}
$reader = start-job -ScriptBlock {
Get-Content "c:\temp\blah.txt" -wait
}
while($writer.State -eq "Running")
{
Sleep 1
}
Sleep 2
"Checking writer"
receive-job $writer
"Checking reader"
receive-job $reader
remove-job $writer -force
remove-job $reader -force
On my Windows 7 x64 machine with powershell 3 ISE, I typically get lots of write errors:
Checking writer
The process cannot access the file 'C:\temp\blah.txt' because it is being used by another process.
+ CategoryInfo : ReadError: (C:\temp\blah.txt:String) [Get-Content], IOException
+ FullyQualifiedErrorId : GetContentReaderIOError,Microsoft.PowerShell.Commands.GetContentCommand
+ PSComputerName : localhost
And then the file being read has gaps in it:
Checking reader
...
23
24
25
54
55
56
...
NB this is a different problem to the one discussed here: Get-Content -wait not working as described in the documentation and here: https://social.technet.microsoft.com/Forums/windowsserver/en-US/e8ed4036-d822-43d3-9ee5-dd03df3d9bfc/why-doesnt-wait-work-and-why-doesnt-anyone-seem-to-care?forum=winserverpowershell which are about tailing a file which isn't being closed in between writes.
Is there any way of using Get-Content and Add-Content like this, or should I give up, and use something else to read and write my log files?
Try using Out-File instead of Add-Content
Replace
With:
You need to specify encoding as ascii with Out-File if that's what you want, since it's the default for add-content but not the default for out-file. You also need to to use -append and/or -noclobber to avoid overwriting existing file content.