PowerShell is often used to automate and script certain tasks and run it in background on specific time or based on specific action. complex scripts might also have more chance of breaking (services may not respond, machine configurations may have changed) no matter where you are running the script (laptop, az automation, az functions, vm) and how you are running script (interactive / non-interactive).

Without logging, it’s hard to know if scripts ran fine or if something went wrong. If something went wrong, logging will help us find out where and why it did.

Logging options:

Standalone script / Script with Schedule task – if you are preparing script which will be executed by schedule task or timer on the windows VM then its recommended to store the log ot text/log file in readable format. on each line you can add the timestamp + log type (error/warning/info) + log content. you can use logging modules available in PS gallery or you can create your own function to write logs in specific format. Please refer Write-Log function section for sample code

Azure Automation runbook – Azure automation account is capable to store the runbook output /log for 30 days and also we can specify logging level on each runbook. by default the automation account will store all the logs in output so if you use write-output command in the runbbok then it will get store in runbook job logs.

Write-Log – This function can help to write log to file or eventviewer or output (usefull for Az automation runbooks /functions)


<#PSScriptInfo
.SYNOPSIS
    Log a message with the specified log level in output or eventlog or log file.

.VERSION 1.1.1

.AUTHOR Arun sabale

.DESCRIPTION 
 Log a message with the specified log level and additional detail like date+time, line number and message in output console or eventlog or log file. 

.EXAMPLE
            #write to log file
            Write-Log -Message 'My Warning Msg' -Level Warning -Path C:\tmp\temp.log
            #write log to eventlog
            Write-Log -Message "my info msg" -Level Information -Eventlog 
            #write log to output screen
            Write-Log -Message "my info msg" -Level Information -output
#> 

function Write-Log
{
    param
    (
        [Parameter(Mandatory=$false,ParameterSetName='output')]
        [parameter(Mandatory=$false,ParameterSetName = 'Eventlog')]
        [Parameter(Position=0,Mandatory=$true,ParameterSetName='path')]
        [String] $Message,

        [Parameter(Mandatory=$false,ParameterSetName='output')]
        [parameter(Mandatory=$false,ParameterSetName = 'Eventlog')]
        [Parameter(Mandatory=$false,ParameterSetName='path')]
        [ValidateSet('Verbose', 'Information', 'Warning', 'Error')]
        [String] $Level="Information",

        [Parameter(Mandatory=$false,ParameterSetName='output')]
        [Switch] $output,
        
        [Parameter(Mandatory=$false,ParameterSetName='path')]
        [string] $path,

        [Parameter(Mandatory=$false,ParameterSetName='Eventlog')]
        [Switch] $Eventlog
    )


    [string]$MessageTimeStamp = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
    $Message1 = "$MessageTimeStamp -[Line $($MyInvocation.ScriptLineNumber)] $Message"
            # Output to log file
            if ($path)
            {
                $Line = $env:ComputerName +", "+ $Env:Username+", "+ $Level+", "+ $Message1
                $Line | Out-File -FilePath $Path -Append 
            }
            # Output to event log
            if ($Eventlog -eq $true)
            {
                if ($Level -eq 'Verbose')
                {
                    $EntryType = 'Information'
                }
                else
                {
                    $EntryType = $Level
                }                
                Write-EventLog -LogName 'Windows PowerShell' -Source 'PowerShell' -EventId 0 -Category 0 -EntryType $EntryType -Message $Message1
            }

            # Output to console
            if((!$path) -and $Eventlog -eq $false) 
            {
                switch ($Level)
                {
                    'Verbose'     { Write-Verbose -Message $Message1 }
                    'Information' { try { Write-Output  $Message1 } catch { Write-Host $Message1 } }
                    'Warning'     { Write-Warning -Message $Message1 }
                    'Error'       { Write-Error -Message $Message1 }
                    
                }
            }
            }


Log Levels in PowerShell – Debug, Information, and Warning

The DebugInformation, and Warning log levels work a little different than we’re used to from traditional logging frameworks in other languages. Let’s add some extra statements first:

Write-Debug "debug statement"
Write-Information "info statement"
Write-Warning "warning statement"

Avoid:

When you write your logging statements, make sure you leave out sensitive or personal data. Examples include:

  • passwords, access tokens
  • credit card numbers , bank account numbers, social security numbers
  • encryption keys

(Visited 1,205 times, 1 visits today)

By Arun Sabale

Arun is a Solution Architect on enterprise client management with more than 14 years of experience in IT. Arun Sabale is Blogger and tech enthusiast. His main focus is on Azure cloud infra, Cloud automation with powershell, python, ARM terraform and all cloud infra services like compute, storage, network, automation, function api etc... LinkedIN - https://www.linkedin.com/in/arun-sabale/