Powershell: Logging to file

Powershell: Logging to file

Often I have situations when my scripts are running as Scheduled Tasks and I need to know status of each execution – specially when error occurred.

It can be solved in many ways with different logging schemes and I will show you one of them. Just take a look for example of log file content:

Pic. 1 Log file content example

In this scenario you can notice that content contains three parts: datetime, type and message string. It should be enough to catch most basic script execution errors.

Lets create function with parameters that will allow us to get our goal. To get there we need to specify: type ($Type), message string ($String) and $Path (if we don’t want to store log files in default directory) – timestamp will be generated automatically and will be explained later.

function Write-LogFile{
    param(
        [Parameter(Mandatory,Position=0)]        
        [ValidateSet('Info','Error','Warning')]
        [string]$Type,
        [Parameter(Mandatory=$true,Position=1)]
        [string[]]$String,
        [string]$Path
    )
}

Now working directory should be changed to script location just to be sure log files and directories will be stored in proper place. So lets add proper line under function parameters declaration.

cd $PSScriptRoot

To prevent situation when log files will be created at script root directory $Path variable should be validated and set default value if it is NULL or not exist and make sure that directory exist in working directory.

if($Path -eq '' -or !$Path){
    # set default value if null or not exist
    $Path='.\logs'
}

if(!(test-path $Path)){
    # create log directory if not exist
    New-Item $Path -ItemType Directory | Out-Null
}

Log file will be created with scheme: <DATE>_<SCRIPT_FILE_NAME>.log

Log entry will be created with scheme: <DATETIME>TAB<TYPE>TAB<STRING>

So lets add this lines:

# date will be use as a part of each log file 
$Date = Get-Date

# script name will be used as a part of each log file
$ScriptName=(Split-Path $MyInvocation.InvocationName -Leaf).split('.')[0]

# set log file path
$FilePath="$Path\$($Date.ToString('yyyyMMdd'))_$($ScriptName).log"
    
# set log string and append it to file
"$($Date.ToString('yyyy.MM.dd HH:mm:ss'))`t$($Type.ToUpper())`t$String" | Out-File $FilePath -Append

And that all that is required to register informations at log files.

To test function just call it with proper parameters:

Write-LogFile -Type Info -String "This is info log entry test"
Start-Sleep 1
Write-LogFile -Type Warning -String "This is warning log entry test"
start-sleep 1
Write-LogFile -Type Error -String "This is error log entry test"

After that new directory will appear at our script root directory. It can be default like this example or any other specified with $Path parameter.

Pic. 2 Result of 'ls’ command at script root directory

Now lets check 'logs’ directory.

Pic. 3 Result of 'ls’ command at 'logs’ directory

And last but not least, lets check log file content.

Pic. 4 Result of 'gc’ command at log file

Full code with comments and Comment-Based Help for function:

function Write-LogFile{
    <#
    .SYNOPSIS
    Storing log strings in a file.

    .DESCRIPTION
    Function allow to create log string with timestamp at beginning in log files. 
    New log files will be created each day with proper timestamp at beginning 
    of file name. 
    New entries will be append to existing files.

    .EXAMPLE
    PS> Write-LogFile -Type Info -String "This is info log entry test"

    .EXAMPLE
    PS> Write-LogFile -Type Warning -String "This is warning log entry test"

    .EXAMPLE
    PS> Write-LogFile -Type Error -String "This is error log entry test"
    
    .PARAMETER Type
    Specified what kind of entry it is: Info, Error or Warning

    .PARAMETER String
    Set string which describes log entry:
    Generic message, error description etc.

    .PARAMETER Path
    Defines log files directory

    #>
    param(
        [Parameter(Mandatory,Position=0)]        
        [ValidateSet('Info','Error','Warning')]
        [string]$Type,
        [Parameter(Mandatory=$true,Position=1)]
        [string[]]$String,
        [string]$Path
    )
    # set working directory
    cd $PSScriptRoot

    if($Path -eq '' -or !$Path){
        # set default value if null or not exist
        $Path='.\logs'
    }

    if(!(test-path $Path)){
        # create log directory if not exist
        New-Item $Path -ItemType Directory | Out-Null
    }

    # date will be use as a part of each log file 
    $Date = Get-Date

     # script name will be used as a part of each log file
    $ScriptName=(Split-Path $MyInvocation.InvocationName -Leaf).split('.')[0]

    # set log file path
    $FilePath="$Path\$($Date.ToString('yyyyMMdd'))_$($ScriptName).log"
    
    # set log string and append it to file
    "$($Date.ToString('yyyy.MM.dd HH:mm:ss'))`t$($Type.ToUpper())`t$String" | Out-File $FilePath -Append
}


Write-LogFile -Type Info -String "This is info log entry test"
Start-Sleep 1
Write-LogFile -Type Warning -String "This is warning log entry test"
start-sleep 1
Write-LogFile -Type Error -String "This is error log entry test"

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.

*