This module improves on the functionality of the Script Logging module I posted at by directly intercepting all text displayed by the PowerShell UI, rather than forcing a script author to make sure all screen output is funnelled through functions like Write-HostLog, etc.

However, this extra functionality comes with a disclaimer:  It is accomplished by using Reflection to access private implementation details of the PowerShell host.  Microsoft may make changes to those classes at any time, at which point it may be necessary to also patch the PowerShellLogging module as well.  The current version has been successfully tested on PowerShell 2.0 through 4.0.

This module's functionality is based on the HostInterceptor class, as originally posted by Mike Walker in Technet Forum thread  Source code for the module is available at

Example usage for the module in its most basic form is shown below.  More detailed description of available options can be found in the about_PowerShellLogging help file, and help files for each of the Cmdlets in the module:  Enable-LogFile, Get-LogFile, Disable-LogFile, Enable-OutputSubscriber, Get-OutputSubscriber, Disable-OutputSubscriber, Suspend-Logging, and Resume-Logging.

4-Apr-2014 Note:  I've just observed some odd behavior related to module auto-loading.  If I type a cmdlet name from the PSLogging module and use tab completion on a parameter name, the module loads, but somehow fails to attach the IO interceptor to the PowerShell host.  You can execute cmdlets, but no logging takes place.  This only happens if the module is loaded as a result of tab completion / IntelliSense; it isn't a problem for scripts that are launched in a clean PowerShell session.  Not sure what's causing this, and I'm looking into a couple of ways I might work around it.

13-Apr-2014 Update:  Version 1.1 released, which addresses the issue noted on 4-Apr.  Host binding is now delayed until the Add-LogFile or Add-OutputSubscriber cmdlet is actually executed, instead of being done at module load time.  This avoids whatever was causing it to fail if the module was loaded due to tab completion, while still intercepting the host output just in time to be useful.

6-May-2014 Update:  The dll, psm1 and psd1 files in the attached zip file are now signed with code-signing certificate thumbprint A2E6B086AC438B5480365B2D5E48BB25F9BE69B3 (cert issued, and signature timestamped by DigiCert.)  For people who don't want to go through the process of downloading the dll's source code from GitHub, reviewing and compiling it, this adds some confidence that you're executing the code that I originally wrote, without any (potentially malicious) modifications.

7-May-2014 Update:  I've changed the name of the module from PSLogging to PowerShellLogging, to avoid stepping on the PS prefix as per recent Microsoft guidelines.  I've also renamed the Add-LogFile and Add-OutputSubscriber commands to Enable-LogFile and Enable-OutputSubscriber, so the verbs pair more nicely with the two Disable-* commands.  Please note that there is no reason you need to download the latest version and update your code, if you're using the original and are happy with it as-is.  This was just some cleanup on my part, to fit in better with other publicly shared modules.

12-May-2016 Update:  Timestamps were previously in local time (even though the string format said GMT).  Should actually report GMT time now.

Import-Module PowerShellLogging 
$LogFile = Enable-LogFile -Path $env:temp\test.log 
# Note - it is necessary to save the result of Enable-LogFile to a variable in order to keep the object alive.  As soon as the $LogFile variable is reassigned or falls out of scope, the LogFile object becomes eligible for garbage collection. 
$VerbosePreference = 'Continue' 
$DebugPreference = 'Continue' 
Write-Host "Write-Host test." 
"Out-Default test." 
Write-Verbose "Write-Verbose test." 
Write-Debug "Write-Debug test." 
Write-Warning "Write-Warning test." 
Write-Error "Write-Error test." 
Write-Host ""   # To display a blank line in the file and on screen. 
Write-Host "Multi`r`nLine`r`n`r`nOutput"  # To display behavior when strings have embedded newlines. 
# Disable logging before the script exits (good practice, but the LogFile will be garbage collected so long as this variable was not in the Global Scope, as a backup in case the script crashes or you somehow forget to call Disable-LogFile). 
$LogFile | Disable-LogFile 
Sample contents of log file: 
Sun, 04 Aug 2013 14:04:15 GMT - Write-Host test. 
Sun, 04 Aug 2013 14:04:15 GMT - Out-Default test. 
Sun, 04 Aug 2013 14:04:15 GMT - [V] Write-Verbose test. 
Sun, 04 Aug 2013 14:04:15 GMT - [D] Write-Debug test. 
Sun, 04 Aug 2013 14:04:15 GMT - [W] Write-Warning test. 
Sun, 04 Aug 2013 14:04:15 GMT - [E] C:\Users\Dave\Source\Temp\Test.ps1 : Write-Error test. 
Sun, 04 Aug 2013 14:04:15 GMT - [E]     + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException 
Sun, 04 Aug 2013 14:04:15 GMT - [E]     + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test.ps1 
Sun, 04 Aug 2013 14:04:15 GMT - Multi 
Sun, 04 Aug 2013 14:04:15 GMT - Line 
Sun, 04 Aug 2013 14:04:15 GMT - Output