Hello all,
here i want to show you a nice and elegant method for logging, It´s only one of a various number of possible ways which you can easily extend even more.
Herefore we use a little Powershell trick that overrides the cmdlet. When Powershell tries to resolve this command it will first try to find a function in your code. Here we add our logging methods and invoke the actual function. Sounds hard? nope.
<# .NOTES ============================================================================ Created on: 14.02.2016 Created by: David das Neves Version: 0.2 Project: LogExt Filename: LogExt.ps1 ============================================================================ .DESCRIPTION Simple Logging extensions. #> # INPUT # ============================================================================ Set-Variable WriteLogFilePath -Value 'c:\temp\standard.log' -Scope Global # ============================================================================ function Out-Default { <# .Synopsis Simple Logging extension. .EXAMPLE Out-Default "logging message" #> [cmdletbinding()] [AllowEmptyCollection()] Param( [Parameter( ValueFromPipeline=$true )] [string]$Message ) if ($Message) { $FunctionName = $MyInvocation.MyCommand.Name.ToString() Write-WithLog 'Write-Output' $Message } } function Write-Host { <# .Synopsis Simple Logging extension. .EXAMPLE Write-Host"logging message" #> [cmdletbinding()] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Message ) Write-WithLog $MyInvocation.MyCommand.Name $Message } function Write-Output { <# .Synopsis Simple Logging extension. .EXAMPLE Write-Output "logging message" #> [cmdletbinding()] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Message ) Write-WithLog $MyInvocation.MyCommand.Name $Message } function Write-Warning { <# .Synopsis Simple Logging extension. .EXAMPLE Write-Warning "logging message" #> [cmdletbinding()] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Message ) Write-WithLog $MyInvocation.MyCommand.Name $Message } function Write-Verbose { <# .Synopsis Simple Logging extension. .EXAMPLE Write-Verbose "logging message" #> [cmdletbinding()] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Message ) Write-WithLog $MyInvocation.MyCommand.Name $Message } function Write-Debug { <# .Synopsis Simple Logging extension. .EXAMPLE Write-Debug "logging message" #> [cmdletbinding()] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Message ) Write-WithLog $MyInvocation.MyCommand.Name $Message } function Write-Error { <# .Synopsis Simple Logging extension. .EXAMPLE Write-Error "logging message" #> [cmdletbinding()] Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string]$Message ) Write-WithLog $MyInvocation.MyCommand.Name $Message } function Write-WithLog { [cmdletbinding()] Param( [Parameter(Mandatory=$true)] [string]$FunctionName, [Parameter(Mandatory=$true)] [string]$Message ) if($WriteLogFilePath -and $Message) { Add-Content -Path $WriteLogFilePath -Value ('{0} [{1}]: {2}' -f ` (Get-Date -Format G), ($FunctionName.Split('-')[1]), "$Message$newLine") } Invoke-Expression "Microsoft.PowerShell.Utility\$FunctionName `$Message" }
With this code you have overwritten all Write-Commands:
– Write-Host
– Write-Output
– Write-Warning
– Write-Verbose
– Write-Debug
– Write-Error
Now you can just type your outputs as by Write-anything and the logging will be done at the same time.
Write-Host a Write-Output b Write-Warning c Write-Verbose d Write-Debug e Write-Error f
To load the extension you have to import the script – you should also set the logging path. In this example the name of the variable herefore is $WriteLogFilePath.
Complete Loading:
Get-Item 'C:\PS\ExtLog\LogExt.ps1' | Import-Module $WriteLogFilePath = 'c:\Temp\test2.log'
Have fun with it!
Greetings,
Dave