I am a great fan of the KISS method, while KISS stands for Keep It Simple Stupid.
Fortunately, there are two built-in cmdlets in PowerShell to make it easy to create log files: Start-Transcript and Stop-Transcript.
However, keep in mind that you must use a maximum of your script content with the Verbose parameter.
Furthermore, you can also use the Write-Output
cmdlet to write your personal messages to the log file.
Otherwise, your log file will just be empty, or only contain error messages…
You must also think about where you want to store your log file(s) and how many of them you want to keep.
Here are three use cases
Unique log file
You want only one log file which is overwritten each time the script is executed.
In the case of one log file, my preference is to keep it in the same folder as the script. Thus you immediately see the script and the log together
I use an automatic variable named MyInvocation to find the path to my running script and replace the .ps1
extension with the .log extension via the Replace
method and a regular expression to build the path to the log file.
$Logfile = $MyInvocation.MyCommand.Path -replace '\.ps1$', '.log' Start-Transcript -Path $Logfile #Doing some stuff with the Verbose parameter Get-ChildItem -Verbose Get-Service -Verbose Get-Process -Verbose Write-Output 'Writing some text to the log file' Stop-Transcript
Two log files
You want two log files: the last run and the run before.
In the case of two log files, my preference is to keep them in the same folder as the script. If you have a folder with several scripts and two log files for each script, it is still readable and clear.
First I remove the old log file, then I rename the current one to .old and finally, I can create a new one named .log
$OldLogfile = $MyInvocation.MyCommand.Path -replace '\.ps1$', '.log.old' $NewLogfile = $MyInvocation.MyCommand.Path -replace '\.ps1$', '.log' #Removing the .log.old file If(Test-Path -Path $OldLogfile) {Remove-Item -Path $OldLogfile} #Renaming the .log to .log.old If(Test-Path -Path $NewLogfile) {Rename-Item -Path $NewLogfile -NewName $OldLogfile} #Starting with a fresh .log file Start-Transcript -Path $NewLogfile #Doing some stuff with the Verbose parameter Get-ChildItem -Verbose Get-Service -Verbose Get-Process -Verbose Write-Output 'Writing some text to the log file' Stop-Transcript
Multiple log files
You want a longer history than only the last run and the former one.
In this case, my preference is to keep them in a subfolder named Logs or whatever you want.
However, you must also keep in mind that you will have plenty of logs and that you must think to a way for removing unnecessary history.
And in this case, the beginning of the script will be a bit more complicated…
Without explaining every detail, here is what it does
- Every log file has a time stamp to make it unique in the folder
- Every time the script runs it keeps only the latest log files and removes the older ones
$CurrentPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent $LogPath = Join-Path -Path $CurrentPath -ChildPath 'Logs' $LogRootName = (Split-Path -Path $MyInvocation.MyCommand.Path -Leaf) -replace '\.ps1' $TimeStamp = Get-Date -Format yyyyMMdd_HHmmss $LogFileName = '{0}_{1}.log' -f $LogRootName, $TimeStamp $LogFile = Join-Path -Path $LogPath -ChildPath $LogFileName #Change this value to how many log files you want to keep $NumberOfLogsToKeep = 10 If(Test-Path -Path $LogPath){ #Make some cleanup and keep only the most recent ones $Filter = '{0}_????????_??????.log' -f (Join-Path -Path $LogPath -ChildPath $LogRootName) Get-ChildItem -Path $Filter | Sort-Object -Property LastWriteTime -Descending | Select-Object -Skip $NumberOfLogsToKeep | Remove-Item -Verbose } Else{ #No logs to clean but create the Logs folder New-Item -Path $LogPath -ItemType Directory -Verbose } Start-Transcript -Path $Logfile #Doing some stuff with the Verbose parameter Get-ChildItem -Verbose Get-Service -Verbose Get-Process -Verbose Write-Output 'Writing some text to the log file' Stop-TranscriptMore about