Last active
September 10, 2018 21:49
-
-
Save Geogboe/77fc7828595e386127586f1f83de9832 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Write-LogMessage { | |
<# | |
.SYNOPSIS | |
Console logging helper function. | |
.DESCRIPTION | |
For a given set of parameters, will create a standardized log message that can be written to any of | |
the various output streams. | |
For more documentation on the available output streams see this: | |
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-6 | |
.EXAMPLE | |
PS C:\> Write-LogMessage -Message "Test Message Numbers: {0},{1}" -Values "Test1","Test2" -Type "output" | |
LOG: 6/4/2018 4:21 PM - MSG: Test Message Numbers: Test1,Test2 | |
In this example a string is printed that substitutes the {} placeholder for the values in the list, in order. | |
.EXAMPLE | |
PS C:\> Write-LogMessage -Values "Test1","Test2" -Type "output" | |
LOG: 6/4/2018 4:22 PM - MSG: Test1,Test2 | |
In this example the message paramter is ommited so the values in the values list are joined together with a comma | |
.EXAMPLE | |
PS C:\> Write-LogMessage -InputHashtable @{ prop1 = "value1"; prop2 = "value2" } -Type "output" | |
LOG: 6/4/2018 4:23 PM - MSG: Hashtable object enumeration: | |
prop2:value2 | |
prop1:value1 | |
In this example the InputHashtable parameter is used an automatically prints the values and values of the hashtable | |
This is useful for debugging. | |
.EXAMPLE | |
PS C:\> Write-LogMessage -Message "Test: {0}" -IncludeDetails -Type Output | |
LOG: 6/4/2018 4:19 PM - MSG: Test: - Invocation Details: <No file> | |
In the above example we can add the arg -IncludeDetails which appends the script and command and lin number that | |
Invoke write log message. This can be useful for debugging. | |
.INPUTS | |
None | |
.OUTPUTS | |
None | |
.NOTES | |
General notes | |
v0.0.2 - George | |
Roadmap | |
- Add writing to text files and event logs | |
#> | |
[CmdletBinding( PositionalBinding, DefaultParameterSetName = "NormalInput" )] | |
param ( | |
# String text that needs to be displayed | |
# You can insert variable values using {} placeholders | |
# By default this will just join all your values | |
[Parameter( ParameterSetName = "NormalInput", Position = 0 )] | |
[string] | |
$Message = ( $Values -join $SeperatorChar ), | |
# A list of values that will replaces the {} placeholders in the message. | |
# If the message field isn't specified, these values will just be joined together. | |
# using the default join operator. | |
[Parameter( ParameterSetName = "NormalInput", Position = 1)] | |
[string[]] | |
$Values, | |
# Why type of message stream to write to. | |
# Defaults to host stream which, on PS5 is the equivalent to | |
# info with informationaction = Continue | |
[Parameter( Position = 2)] | |
[ValidateSet( "Info", "Verbose", "Debug", "Host", "Error", "Warning", "Throw", "Output")] | |
[Alias("Type")] | |
[string] | |
$OutputStream = "Host", | |
# Will indicate that a banner will be printed marking the start of the curently running function | |
[Parameter( Mandatory = $false, ParameterSetName = "PrintFunctionHeaderBanner" )] | |
[switch] | |
$PrintFunctionHeaderBanner, | |
# Will indicate that a banner will be printed marking the end of the curently running function | |
[Parameter( Mandatory = $false, ParameterSetName = "PrintFunctionFooterBanner" )] | |
[switch] | |
$PrintFunctionFooterBanner, | |
# Specifies a hashtable that is printed inline | |
# The hashtable keys and properties will be printed and join using | |
# the seperatator listed below | |
[Parameter( Mandatory = $false, ParameterSetName = "InputHashtableSet" )] | |
[hashtable] | |
$InputHashtable, | |
# If values are being joined, this will be used as the separator. | |
# This defaults to a comma | |
[Parameter( ParameterSetName = "InputHashtableSet" )] | |
[string] | |
$SeperatorChar = ",", | |
# Include additional details about the invocation. | |
[Parameter( Mandatory = $false )] | |
[switch] | |
$IncludeDetails = $false, | |
# Determines whether or not the date will be printed | |
[Parameter( Mandatory = $false )] | |
[switch] | |
$ExcludeDate = $false, | |
# Prefix to use at the begining of the message string. | |
[Parameter( DontShow )] | |
[string] | |
$MessagePrefix = "LOG: ", | |
# The date | |
[Parameter( DontShow )] | |
[string] | |
$LogDate = ( Get-Date -Format g ).ToString() | |
) | |
begin { | |
$ErrorActionPreference = "Stop" | |
Set-StrictMode -Version 2.0 | |
} | |
process { | |
# Put all our values in an object for organization | |
$Log = [PSCustomObject]@{ | |
CallingFunctionName = ( Get-PSCallStack ).Location[1] # ( Get-PSCallStack )[1].Command | |
PrintCallingFunction = $IncludeDetails | |
OutputString = [string] | |
Prefix = $MessagePrefix | |
Suffix = $null | |
ExcludeDate = $ExcludeDate | |
Date = $LogDate + ": " | |
Strings = @() | |
InnerText = $null | |
} | |
# Add the date to the log if not excluded then update the prefix to include the date | |
if ( $ExcludeDate -eq $false ) { $Log.Prefix += $Log.Date } | |
# Set the message content to the keys and values of the provided hashtable | |
if ( $PSCmdlet.ParameterSetName -eq "InputHashtableSet" ) { | |
$Log.InnerText += Invoke-HashtableEnumeration -Hashtable $InputHashtable -StringSeparator $SeperatorChar | |
} | |
# Display a banner indicating the function header | |
if ( $PSCmdlet.ParameterSetName -eq "PrintFunctionHeaderBanner" ) { | |
$Log.InnerText = "------------- Entering Function: " + $Log.CallingFunctionName | |
$OutputStream = "Debug" | |
} | |
# Display a banner indicating the function footer | |
if ( $PSCmdlet.ParameterSetName -eq "PrintFunctionFooterBanner" ) { | |
$Log.InnerText = "------------- Exiting Function: " + $Log.CallingFunctionName | |
$OutputStream = "Debug" | |
} | |
# If a message has been provided create that | |
if ( $PSCmdlet.ParameterSetName -eq "NormalInput" ) { | |
$Log.InnerText = ( $Message -f $Values ) | |
} | |
# Print the calling function and line if debug is the output stream | |
if ( | |
$OutputStream -eq "Debug" -OR | |
$Log.PrintCallingFunction -AND | |
!( | |
$PSCmdlet.ParameterSetName -eq "PrintFunctionHeaderBanner" -OR | |
$PSCmdlet.ParameterSetName -eq "PrintFunctionFooterBanner" | |
) | |
) { | |
$Log.Suffix += "[ " + $Log.CallingFunctionName + " ]" | |
} | |
# Build the log string array | |
$Log.Strings += $Log.Prefix | |
$Log.Strings += $Log.InnerText | |
$Log.Strings += $Log.Suffix | |
$Log.OutputString = $Log.Strings -join '' | |
switch ( $OutputStream ) { | |
"Info" { Write-Information $Log.OutputString } | |
"Output" { Write-Output $Log.OutputString } | |
"Host" { Write-Host $Log.OutputString } | |
"Verbose" { Write-Verbose $Log.OutputString } | |
"Debug" { Write-Debug $Log.OutputString } | |
"Error" { Write-Error $Log.OutputString } | |
"Warning" { Write-Warning $Log.OutputString } | |
"Throw" { throw $Log.OutputString } | |
} | |
} | |
} | |
function Invoke-HashtableEnumeration { | |
<# | |
.SYNOPSIS | |
Enumerates the keys and values of a hashtable into a single string | |
.DESCRIPTION | |
Loops through the keys and values of a given | |
hashtable and joined these keys and values into a string | |
separated by the provided string separator. | |
This is especially useful for debugging | |
#> | |
[CmdletBinding()] | |
param ( | |
[hashtable] | |
$Hashtable, | |
[string] | |
$StringSeparator | |
) | |
$OutputString = "Hashtable object enumeration:`n" | |
$InputHashtable.GetEnumerator() | ForEach-Object { | |
$KeyValuePair = " - " + $_.Name + ": " + $_.Value + "`n" | |
$OutputString += $KeyValuePair | |
} | |
return $OutputString | |
} | |
<# | |
Poor Mans Pester Tests | |
Import-Module <Module> -Force | |
InModuleScope <Module> { | |
Describe "Write-LogMessage" { | |
$DebugPreference = "Continue" | |
$VerbosePreference = "Continue" | |
It "Writes a function header to the debug stream" { | |
Write-LogMessage -PrintFunctionHeaderBanner | |
} | |
It "Writes a function footer the debug stream" { | |
Write-LogMessage -PrintFunctionFooterBanner | |
} | |
It "Writes a string to the host stream" { | |
Write-LogMessage -Message "Hello World" | |
} | |
It "Writes a string with value substitutions the host stream" { | |
Write-LogMessage -Message "Value 1: {0}, Value 2: {1}" -Values "Hello", "World" | |
} | |
It "Write the enumerated values of a hastable to the verbose stream" { | |
Write-LogMessage -InputHashtable @{ Hello = "World" } -OutputStream Verbose | |
} | |
It "Writes a message to throw a terminating error" { | |
{ Write-LogMessage -Message "Hello World" -OutputStream throw } | Should -Throw | |
} | |
} | |
} | |
#> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment