I was recently looking at streaming output to a log file synchronously in a powershell session to write numerous events for invoking several cmdlets in a script operation. In order to achieve this I was able to leverage the FileStream and StreamWriter classes as well as creating a log function to both write the event to the console and log file.
Firstly, we will start with creating the FileStream and StreamWriter objects in order to write the event to the log file, where the filename will combine an output directory and generated filename to which in this example contain the timestamp converted to the string ‘dd-MM-yyyy’.
We will specify these as follows:
$Output = "C:\Output" $File = ([guid]::NewGuid() + "-example-" + (Get-Date).toString('dd-MM-yyyy') + ".log")
To generate the log filename we will combine these values using the System.IO Path class.
$Path = [System.IO.Path]::Combine($Output,$File)
In order to synchronously write to the file, we need to specify how the operating system should open the file by seeking to the end of the file (FileMode Enumeration) if this exists which requires the FileAccess.Write permission and to allow for subsequent opening of the file for reading using the File (FileShare Enumeration).
$FileMode = [System.IO.FileMode]::Append $FileAccess = [System.IO.FileAccess]::Write $FileShare = [IO.FileShare]::Read
Now we have determined how the operating system will open the file we need to create the FileStream and StreamWriter objects and invoke the above configuration.
$FileStream = New-Object IO.FileStream($Path, $FileMode, $FileAccess, $FileShare) $StreamWriter = New-Object System.IO.StreamWriter($FileStream)
At this point we can now write to the log file, so we will create a Function to write events to the console by invoking the Write-Host cmdlet and log file by invoking the StreamWriter.WriteLine method.
Function Log($Event) { Write-Host $Event $StreamWriter.WriteLine($Event) }
For Example, if I was to output an information message to notify of the current date and time as ‘SortableDateTimePattern’ format.
Log (Get-Date -Format s)
Once the script operation is complete we now want to dispose of the StreamWriter and FileStream Dispose methods to close the underlying stream and release the file.
$StreamWriter.Dispose() $FileStream.Dispose()
2 thoughts on “Exposing a stream around a log file for synchronous writes using Powershell”