PowerShell Log Files – Options


Log Files

Creating log files for auditing can be a pain to implement, but may be a boon if you are automating scripts. The oft asked detail, is indeed, how much details do we need to log for the script? Well. It Depends. How deep do you want the log to cover? Do you just need to know where the script stopped (if there were errors) OR do you need each … and every … step sent to the log for auditing and error analysis.

For this tip we’ll take a small script and then add a whole bunch of lines to create a log file. Then we’ll examine what this log file contains and possible enhancements. Key thing to remember in the output is that is it up to you, the scripter, to decide the level of detail and formatting of the log file as it will only be useful to you if it makes sense to you.

Script

First. The script. [** NOTE ** The connection method is NOT shown. ] Within this script, we are checking a few prerequisites on a system to make sure a new PowerShell module can be downloaded. In this case, we need to ensure that NuGet is the right version and that the PowerShell Gallery – PSGallery – is trusted. So here is the barest of code:
[sourcecode language=”powershell”]
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$False -Verbose
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted -ErrorAction STOP
[/sourcecode]
On most computers this will probably install just fine. However, what if there are issues or errors logged, what if a reboot is required or an update is unreachable, then what? If your script were automated, then these might fail and what log file would you review? None. So let’s create one.
[sourcecode language=”powershell”]
# Logging File
$LogPath = (Get-Item -Path ".\" -Verbose).FullName
$LogFile = "Logging.txt"
$LogDestination = $LogPath+"\"+$LogFile
[/sourcecode]
Now that we have a log file (this part is optional) we can add a header for each time we write to the log file for historical purposes:
[sourcecode language=”powershell”]
$CurrentDate = Get-Date -Format yyyymmdd-HHMMss
$Output = "" | Out-File $LogDestination -Append
$Output = "################### $CurrentDate – Start ##############################" | Out-File $LogDestination -Append
[/sourcecode]
With this header in place, we can proceed to the first prereq:
[sourcecode language=”powershell”]
Try {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -Confirm:$False -ErrorAction STOP
$Date = Get-Date
$Output = "$Date – SUCCESS – NuGet is now at a minimum version of 2.8.5.201." | Out-File $LogDestination -Append
} Catch {
$Date = Get-Date
$Output = "$Date – FAILURE – NuGet is not at the correct versions. Error:" | Out-File $LogDestination -Append
$Line = "$Date – Error message – $_.Exception.Message" | Out-File $LogDestination -Append
}
[/sourcecode]
Notice that Get-Date is used multiple times, this helps pinpoint times where there was an issue. We are also using Try {} Catch {} to catch errors. Successes and Failures are logged to the same log file. Next line of code will be treated the same:
[sourcecode language=”powershell”]
Try {
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted -ErrorAction STOP
$Date = Get-Date
$Output = "$Date – SUCCESS – PSGallery is now trusted." | Out-File $LogDestination -Append
} Catch {
$Date = Get-Date
$Output = "$Date – FAILURE – Could not change trust for PSGallery. Error:" | Out-File $LogDestination -Append
$Line = "$Date – Error message – $_.Exception.Message" | Out-File $LogDestination -Append
}
[/sourcecode]

Results

Now, if you want, and there are many operations like this, we could potential create a wrapper function to hand this. For this scenario, we are keeping it simple. Let’s review the output:


We can see that all worked as expected and we are ready to go (prereq-wise). We also see that there is a Start and End date for the log which could help with troubleshooting. If we have failures, we might see stuff like this:


With this log, we see that here were some connectivity issues, we might notice that there was an Internet issue at that time to explain it and if not, then may something more local that needs investigating.

Summary

As we see, this form of logging has its advantages (additional information) and downsides (additional time to code). The formatting that is chosen is entirely up to you the scripter. You can add more or remove lines, use different date formats and more. Entirely up to you how the log will log as it will be yours to use. Hope you enjoyed this tip. Sign up for the newsletter if you have not already!

Related Post