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:

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.

Now lets check 'logs’ directory.

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

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