Skip to content

Instantly share code, notes, and snippets.

@9to5IT
Last active March 20, 2023 00:47
Show Gist options
  • Star 37 You must be signed in to star a gist
  • Fork 28 You must be signed in to fork a gist
  • Save 9to5IT/9620565 to your computer and use it in GitHub Desktop.
Save 9to5IT/9620565 to your computer and use it in GitHub Desktop.
PowerShell: Logging Functions
Function Log-Start{
<#
.SYNOPSIS
Creates log file
.DESCRIPTION
Creates log file with path and name that is passed. Checks if log file exists, and if it does deletes it and creates a new one.
Once created, writes initial logging data
.PARAMETER LogPath
Mandatory. Path of where log is to be created. Example: C:\Windows\Temp
.PARAMETER LogName
Mandatory. Name of log file to be created. Example: Test_Script.log
.PARAMETER ScriptVersion
Mandatory. Version of the running script which will be written in the log. Example: 1.5
.INPUTS
Parameters above
.OUTPUTS
Log file created
.NOTES
Version: 1.0
Author: Luca Sturlese
Creation Date: 10/05/12
Purpose/Change: Initial function development
Version: 1.1
Author: Luca Sturlese
Creation Date: 19/05/12
Purpose/Change: Added debug mode support
.EXAMPLE
Log-Start -LogPath "C:\Windows\Temp" -LogName "Test_Script.log" -ScriptVersion "1.5"
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$true)][string]$LogPath, [Parameter(Mandatory=$true)][string]$LogName, [Parameter(Mandatory=$true)][string]$ScriptVersion)
Process{
$sFullPath = $LogPath + "\" + $LogName
#Check if file exists and delete if it does
If((Test-Path -Path $sFullPath)){
Remove-Item -Path $sFullPath -Force
}
#Create file and start logging
New-Item -Path $LogPath -Value $LogName -ItemType File
Add-Content -Path $sFullPath -Value "***************************************************************************************************"
Add-Content -Path $sFullPath -Value "Started processing at [$([DateTime]::Now)]."
Add-Content -Path $sFullPath -Value "***************************************************************************************************"
Add-Content -Path $sFullPath -Value ""
Add-Content -Path $sFullPath -Value "Running script version [$ScriptVersion]."
Add-Content -Path $sFullPath -Value ""
Add-Content -Path $sFullPath -Value "***************************************************************************************************"
Add-Content -Path $sFullPath -Value ""
#Write to screen for debug mode
Write-Debug "***************************************************************************************************"
Write-Debug "Started processing at [$([DateTime]::Now)]."
Write-Debug "***************************************************************************************************"
Write-Debug ""
Write-Debug "Running script version [$ScriptVersion]."
Write-Debug ""
Write-Debug "***************************************************************************************************"
Write-Debug ""
}
}
Function Log-Write{
<#
.SYNOPSIS
Writes to a log file
.DESCRIPTION
Appends a new line to the end of the specified log file
.PARAMETER LogPath
Mandatory. Full path of the log file you want to write to. Example: C:\Windows\Temp\Test_Script.log
.PARAMETER LineValue
Mandatory. The string that you want to write to the log
.INPUTS
Parameters above
.OUTPUTS
None
.NOTES
Version: 1.0
Author: Luca Sturlese
Creation Date: 10/05/12
Purpose/Change: Initial function development
Version: 1.1
Author: Luca Sturlese
Creation Date: 19/05/12
Purpose/Change: Added debug mode support
.EXAMPLE
Log-Write -LogPath "C:\Windows\Temp\Test_Script.log" -LineValue "This is a new line which I am appending to the end of the log file."
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$true)][string]$LogPath, [Parameter(Mandatory=$true)][string]$LineValue)
Process{
Add-Content -Path $LogPath -Value $LineValue
#Write to screen for debug mode
Write-Debug $LineValue
}
}
Function Log-Error{
<#
.SYNOPSIS
Writes an error to a log file
.DESCRIPTION
Writes the passed error to a new line at the end of the specified log file
.PARAMETER LogPath
Mandatory. Full path of the log file you want to write to. Example: C:\Windows\Temp\Test_Script.log
.PARAMETER ErrorDesc
Mandatory. The description of the error you want to pass (use $_.Exception)
.PARAMETER ExitGracefully
Mandatory. Boolean. If set to True, runs Log-Finish and then exits script
.INPUTS
Parameters above
.OUTPUTS
None
.NOTES
Version: 1.0
Author: Luca Sturlese
Creation Date: 10/05/12
Purpose/Change: Initial function development
Version: 1.1
Author: Luca Sturlese
Creation Date: 19/05/12
Purpose/Change: Added debug mode support. Added -ExitGracefully parameter functionality
.EXAMPLE
Log-Error -LogPath "C:\Windows\Temp\Test_Script.log" -ErrorDesc $_.Exception -ExitGracefully $True
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$true)][string]$LogPath, [Parameter(Mandatory=$true)][string]$ErrorDesc, [Parameter(Mandatory=$true)][boolean]$ExitGracefully)
Process{
Add-Content -Path $LogPath -Value "Error: An error has occurred [$ErrorDesc]."
#Write to screen for debug mode
Write-Debug "Error: An error has occurred [$ErrorDesc]."
#If $ExitGracefully = True then run Log-Finish and exit script
If ($ExitGracefully -eq $True){
Log-Finish -LogPath $LogPath
Break
}
}
}
Function Log-Finish{
<#
.SYNOPSIS
Write closing logging data & exit
.DESCRIPTION
Writes finishing logging data to specified log and then exits the calling script
.PARAMETER LogPath
Mandatory. Full path of the log file you want to write finishing data to. Example: C:\Windows\Temp\Test_Script.log
.PARAMETER NoExit
Optional. If this is set to True, then the function will not exit the calling script, so that further execution can occur
.INPUTS
Parameters above
.OUTPUTS
None
.NOTES
Version: 1.0
Author: Luca Sturlese
Creation Date: 10/05/12
Purpose/Change: Initial function development
Version: 1.1
Author: Luca Sturlese
Creation Date: 19/05/12
Purpose/Change: Added debug mode support
Version: 1.2
Author: Luca Sturlese
Creation Date: 01/08/12
Purpose/Change: Added option to not exit calling script if required (via optional parameter)
.EXAMPLE
Log-Finish -LogPath "C:\Windows\Temp\Test_Script.log"
.EXAMPLE
Log-Finish -LogPath "C:\Windows\Temp\Test_Script.log" -NoExit $True
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$true)][string]$LogPath, [Parameter(Mandatory=$false)][string]$NoExit)
Process{
Add-Content -Path $LogPath -Value ""
Add-Content -Path $LogPath -Value "***************************************************************************************************"
Add-Content -Path $LogPath -Value "Finished processing at [$([DateTime]::Now)]."
Add-Content -Path $LogPath -Value "***************************************************************************************************"
#Write to screen for debug mode
Write-Debug ""
Write-Debug "***************************************************************************************************"
Write-Debug "Finished processing at [$([DateTime]::Now)]."
Write-Debug "***************************************************************************************************"
#Exit calling script if NoExit has not been specified or is set to False
If(!($NoExit) -or ($NoExit -eq $False)){
Exit
}
}
}
Function Log-Email{
<#
.SYNOPSIS
Emails log file to list of recipients
.DESCRIPTION
Emails the contents of the specified log file to a list of recipients
.PARAMETER LogPath
Mandatory. Full path of the log file you want to email. Example: C:\Windows\Temp\Test_Script.log
.PARAMETER EmailFrom
Mandatory. The email addresses of who you want to send the email from. Example: "admin@9to5IT.com"
.PARAMETER EmailTo
Mandatory. The email addresses of where to send the email to. Seperate multiple emails by ",". Example: "admin@9to5IT.com, test@test.com"
.PARAMETER EmailSubject
Mandatory. The subject of the email you want to send. Example: "Cool Script - [" + (Get-Date).ToShortDateString() + "]"
.INPUTS
Parameters above
.OUTPUTS
Email sent to the list of addresses specified
.NOTES
Version: 1.0
Author: Luca Sturlese
Creation Date: 05.10.12
Purpose/Change: Initial function development
.EXAMPLE
Log-Email -LogPath "C:\Windows\Temp\Test_Script.log" -EmailFrom "admin@9to5IT.com" -EmailTo "admin@9to5IT.com, test@test.com" -EmailSubject "Cool Script - [" + (Get-Date).ToShortDateString() + "]"
#>
[CmdletBinding()]
Param ([Parameter(Mandatory=$true)][string]$LogPath, [Parameter(Mandatory=$true)][string]$EmailFrom, [Parameter(Mandatory=$true)][string]$EmailTo, [Parameter(Mandatory=$true)][string]$EmailSubject)
Process{
Try{
$sBody = (Get-Content $LogPath | out-string)
#Create SMTP object and send email
$sSmtpServer = "smtp.yourserver"
$oSmtp = new-object Net.Mail.SmtpClient($sSmtpServer)
$oSmtp.Send($EmailFrom, $EmailTo, $EmailSubject, $sBody)
Exit 0
}
Catch{
Exit 1
}
}
}
@elfim
Copy link

elfim commented Mar 27, 2014

Line 53 is incorrect. Instead of this line: New-Item -Path $LogPath -Value $LogName –ItemType File
it should be this one: New-Item -Path $LogPath -Name $LogName –ItemType File
and
Line 174 there is a typo: Break is correct

Apart from these little things - your script is great! Thanks a lot Luca!

@animetauren
Copy link

As @elfim mentioned in the earlier comment, Line 53 still needs to be fixed. The value for line 53 is still New-Item -Path $LogPath -Value $LogName –ItemType File and it should be New-Item -Path $LogPath -Name $LogName –ItemType File

@westerdaled
Copy link

Thanks to @elfim and @animetauren .. for identifying that typo
For those who are new to PowerShell .. you can simply reference you functions.ps1 in your script and then use it as normal.
$directorypath = Split-Path $MyInvocation.MyCommand.Path
$incFunctions = $directorypath + "\Logging_Functions.ps1"
logfile = $directorypath + "\myoutput.log"

use the . syntax to include the functions file

. $incFunctions

Log-Write -LogPath $logfile -LineValue "Why is everyone obsessed with hybrid! "

@Daniel-Beardsmore
Copy link

As a note, when exiting due to failure, a nonzero exit code should be issued.

@aljfoster
Copy link

How would I invoke the Log-write function with a Copy-item command?

@rfsales
Copy link

rfsales commented Apr 27, 2016

I'm getting a diferent error:

New-Item : The Access to the path 'C: \ scripts \ compacta_sql \ logs ' was denied.
No C:\scripts\functions\Logging_Functions.ps1:45 caractere:5

  • New-Item -Path $LogPath -Value $LogName -ItemType File
    
  • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : PermissionDenied: (C:\scripts\compacta_sql\logs:String) [New-Item], UnauthorizedAccessException
    • FullyQualifiedErrorId : NewItemUnauthorizedAccessError,Microsoft.PowerShell.Commands.NewItemCommand

@bharatgowdar
Copy link

Hello,

Add-Content -Path $sFullPath -Value "***************************************************************************************************"

why am not able to write content to file again..its not giving any error and not writing content to file/
?

@spxie85
Copy link

spxie85 commented Mar 6, 2017

It'd be much better if a function to perform log rotation is included here

@dwcullop
Copy link

Thank you for this. I appreciate you sharing your work. Some suggestions for improvement:

  1. When adding a bunch of lines at once, such as in Log-Start, consider using a Dot Net's StringBuilder:
    $sb = [System.Text.StringBuilder]::new()
    $sb.AppendLine(...)
    $text = $sb.ToString()
    Add-Content -Path $LogPath -Value $text' Write-Debug $text`

    Then you can emit the same text in two places without having to repeat yourself.

  2. Consider using Join-Path when concatenating strings to form a path. It saves all the trouble with where to put what kind of separator

Just some ideas. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment