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
