Here I present a PowerShell script which I find useful.

Of course, PowerShell is a Microsoft Windows based object orientated script / programming language. It has its own command line interface.

Normally I would prefer a platform independent language like Python. But within a Windows environment you can do almost anything with PowerShell. And sometimes I just do not like to perform all tasks with Excel / VBA. PowerShell can perform tasks in background mode, at a scheduled time, etc.

A first useful function is in my opinion Write-Log. It offers logging functionality.

Please read my Disclaimer

Write-Log -Message [string] -Severity EVER|INFO|WARN|FATAL
This script/function enables logging within PowerShell scripts.
Global variables which control features of this script are:
[string]$global:LogFilePath - The text file into which all messages are getting written
[string]$global:SubName - The name of the script calling this Log script
[int]$global:LogLevel - The log levels:
1 logs everything,
2 omits INFOs,
3 omits INFOs and WARNings,
4 only logs severity EVER messages
[bool]$global:WriteToHost - $FALSE = Only write into logfile; $TRUE = Also write to Host
Write-Log writes into a logfile with name [string]$global:LogFilePath.
if the user has not given this, the standard filename "$PSScriptRoot\Logs\LogFile.txt" is used.
The contents of a log file will look like:
INFO: BERND-PC\Bernd 2020-02-16 12:19:36 [zip_and_copy.ps1] - Log started
INFO: BERND-PC\Bernd 2020-02-16 12:19:36 [zip_and_copy.ps1] - Log finished
In case the user has set [bool]$global:WriteToHost to $TRUE, WRite-Log also repeats all log
messages on screen (Host).
The message you want to log.
The severity of the message. This can be 'INFO', 'WARN', 'FATAL', or 'EVER'.
If global variable LogLevel is 1 then messages with all severities will be logged.
If LogLevel is 2 then INFO messages will not be logged.
If LogLevel is 3 then INFO and WARN messages will not be logged.
If LogLevel is 4 then INFO, WARN and FATAL messages will not be logged.
# Initialize global logging variables and make log script known
$global:SubName = $MyInvocation.MyCommand.Name
$global:LogLevel = 1
$global:LogFilePath = "$PSScriptRoot\Logs\LogFile_" + $SubName + "_" +
(Get-Date -UFormat "%Y%m%d") + ".txt"
$global:WriteToHost = $TRUE
. "$PSScriptRoot\Write-Log.ps1"
# How to call
Write-Log -Message 'Log started' -Severity INFO
If(-Not (Test-path $ArchiveFile)) {Write-Log -Message "$ArchiveFile was not created" -Severity FATAL}
Version Date Who What
1.0 16-Feb-2020 Bernd Plumhoff Initial Version
1.1 16-Jul-2020 Bernd Plumhoff EVER instead of ALWAYS, and optional Write-Host
#Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser -Force
#Requires -Version 4
Set-StrictMode -Version Latest
function Write-Log {
[string]$Severity = 'INFO'
switch ($Severity)
'INFO' { If ([int]$global:LogLevel -gt 1) {Exit} }
'WARN' { If ([int]$global:LogLevel -gt 2) {Exit} }
'FATAL' { If ([int]$global:LogLevel -gt 3) {Exit} }
'EVER' { <# Will always be logged! #> }
if (-Not (Test-Path -IsValid $global:LogFilePath)) { $global:LogFilePath = "$PSScriptRoot\Logs\LogFile.txt" }
[string]$Output = $Severity + ": " + [System.Security.Principal.WindowsIdentity]::GetCurrent().Name +
" " + (Get-Date -UFormat "%Y-%m-%d %T") + " [" + $global:SubName + "] - " + $Message
Write-Output $Output | Out-File -append $global:LogFilePath
If (Test-Path variable:global:WriteToHost) {
If ($global:WriteToHost) { Write-Host $Output }