PS – An easy way to log

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

standardlog

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

Advertisement