Creating a logging framework in PowerShell – Part 3

In Part-1, we looked at why logging was important, established a set of guidelines or targets that we need to keep in mind while designing the framework and defined few variables that we will be using. 

In Part-2, we expanded on the basics created a few more variables and created a function ‘Write-Log’, which as the name suggests writes messages to the log file.

In this part we will look at managing the logs that we will generate. What I mean is, we will need a way to archive the log files. For this we need a couple of functions:

  • Add-BackSlashToPath, this function adds a backslash to a path.
  • Switch-LogFile, this function archives the log files that are created for a script.

First let us look at Add-BackSlashToPath. The reason why we need this function is because PowerShell does not always return paths with a backslash appended at the end. So, we append it to the end of the path.

Function Add-BackSlashToPath ($Path){
     Add a backslash to any given path if it is missing.
Powershell usually returns path without a backslash.
	This function takes care of that.
	We need not expose this to the environment.
Add-BackSlashToPath -Path "C:\Test-PS-1"
	Add-BackSlashToPath -Path C:\Windows\System32\
	Add-BackSlashToPath -Path \\comp1\C$\Windows\System32
	if(Test-Path -Path $Path -IsValid){
		if($Path -match "\\$"){
			$strPath = $Path
			$strPath = $Path + "\"
	} else{
		$strPath = ".\"

The second function archives the log files. The assumption is that the log file name will be scriptname.log. So, when the program finds a log with the name scriptname.log it will rename the existing log file to scriptname.001.log and then creates a new file with the scriptname.log name. This process will continue until we have as many log files as defined by the number of archives parameter. Once, this limit is reached the function will delete the last log file and update the names for all existing log files in the folder.

Function Switch-LogFile {
     Archive the log files for the script.
The number of archive files we maintain is determined by the numArch parameter.
	Log file name is ProgramName.log.
Switch-LogFile -Name "C:\Test-PS-1\First.log" -Arch 10
  Param (
		$pathToFile = [System.IO.Path]::GetDirectoryName($Name)
if ( ! (Test-Path -Path "$pathToFile")) {
$pathToFile = New-Item -Path "$pathToFile" -type directory
$pathToFile = Resolve-Path $pathToFile #Get full path for paths passed like '.\filename'
		$pathToFile = Add-BackSlashToPath $pathToFile.Path.ToString()
		$isValidPath = Test-Path -Path "$pathToFile" -IsValid
		Write-Debug $isValidPath
			$Arch = $NumOfArchives

			#Get path that can be used by Get-ChildItem (gci) and Test-Path
			$gciLogPath = $pathToFile + "*"
			$Name = $Name.Substring($Name.LastIndexOf('\') + 1)
			$logName = $Name.Substring(0,$Name.Length - 4)
			Write-Debug $gciLogPath
			#Test if the logfile exists
			$defaultLogExists = Test-Path -Path $gciLogPath -include $Name

			#If the default log i.e. "ScriptName.Log" exists
				$dirContent = Get-ChildItem $gciLogPath -Filter "$logName*.log" |Sort-Object -Property Name -Descending| Select-Object Name
				ForEach($fileName in $dirContent){
					if($fileName.Name -match "^*`.\d{3}")
						$matchVal = $Matches[0]
						if(([int]$matchVal.SubString(1,$matchVal.Length-1)) -eq ($Arch))
							Write-Debug "Deleting log file: $($fileName.Name)"
							$fileToDel = $pathToFile + "$($fileName.Name)"
							Remove-Item -LiteralPath $fileToDel
							$logNum = $matchVal.SubString(1,$matchVal.Length-1)
							$logNum = "{0:D3}" -f (([int] $logNum) + 1)
							$newName = "$logName.$logNum.log"
							$fullPath = $pathToFile + "$($fileName.Name)"
							Rename-Item -Path $fullPath -NewName "$newName"
				#we are done with all the preprocessing so we can now rename "Log.log"
				#as Log.001.log and create a new default log file.
				$fullPath = $pathToFile + $Name
				Write-Debug $fullPath
				Rename-Item -Path $fullPath -NewName "$logName.001.log"
				$newLogFile = New-Item -Path "$fullPath" -ItemType File -Force

			} else { #default log does not exist go ahead and create the log file.
				$fullPath = $pathToFile + $Name
				$newLogFile = New-Item -Path $fullPath -ItemType File -Force
	} catch{
		Write-Error $_
# End Function Switch-LogFile

We now have a way of managing log files.

In the blog posts till now we have seen how to define a set of guidelines, define our variables based on these guidlines. We also, created a function that will log the data to a log file and created functions that will help us manage the log files that are generated.

In the next part we will tie all of this together and put them in a module so that we can use this as a standard way to log script actions.


By profession, I’m a SQL Server Database Administrator. I love to poke my nose into different corners and see how stuff looks in there. I keep looking for new things to do as my mind refuses to settle on one topic.

Tagged with: , , , ,
Posted in PowerShell

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: