Skip to content

Commit

Permalink
Initial upload
Browse files Browse the repository at this point in the history
- PS-Logger module
- README with usage and examples
  • Loading branch information
AssafMiron committed Aug 16, 2020
1 parent 66463d5 commit 23a4f39
Show file tree
Hide file tree
Showing 3 changed files with 344 additions and 1 deletion.
Binary file added PS-Logger/PS-Logger.psd1
Binary file not shown.
216 changes: 216 additions & 0 deletions PS-Logger/PS-Logger.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@

# Get Debug / Verbose parameters for Script
$global:_InDebug = $False
$global:_InVerbose = $False
Function Set-DebugLogging
{
param($ScriptBoundParameters)

$global:_InDebug = $ScriptBoundParameters.Debug.IsPresent
$global:_InVerbose = $ScriptBoundParameters.Verbose.IsPresent

if($_InDebug) { Write-LogMessage -Type Debug -MSG "Running in Debug Mode" -LogFile $LOG_FILE_PATH }
if($_InVerbose) { Write-LogMessage -Type Verbose -MSG "Running in Verbose Mode" -LogFile $LOG_FILE_PATH }
}
Export-ModuleMember -Function Set-DebugLogging

# ------ SET Files and Folders Paths ------
# Set Log file path
$global:LOG_FILE_PATH = $MyInvocation.ScriptName.Replace(".ps1",".log")
# @FUNCTION@ ======================================================================================================================
# Name...........: Set-LogFilePath
# Description....: Sets the log file name and path
# Parameters.....: New Log File path
# Return Values..: The Newly set Log file path
# =================================================================================================================================
Function Set-LogFilePath
{
<#
.SYNOPSIS
Method to set the log file name and path
.PARAMETER LogFilePath
#>
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[ValidateNotNullOrEmpty()]
[Alias("Path")]
[String]$LogFilePath
)
Set-Variable -Scope Global -Name LOG_FILE_PATH -Value $LogFilePath

return $LOG_FILE_PATH
}
Export-ModuleMember -Function Set-LogFilePath

# @FUNCTION@ ======================================================================================================================
# Name...........: Get-LogFilePath
# Description....: Gets the log file name and path
# Parameters.....: None
# Return Values..: The Log file path
# =================================================================================================================================
Function Get-LogFilePath
{
<#
.SYNOPSIS
Method to get the log file name and path
#>
param(
)

return $LOG_FILE_PATH
}
Export-ModuleMember -Function Get-LogFilePath

# @FUNCTION@ ======================================================================================================================
# Name...........: Write-LogMessage
# Description....: Writes the message to log and screen
# Parameters.....: LogFile, MSG, (Switch)Header, (Switch)SubHeader, (Switch)Footer, Type
# Return Values..: None
# =================================================================================================================================
Function Write-LogMessage
{
<#
.SYNOPSIS
Method to log a message on screen and in a log file
.DESCRIPTION
Logging The input Message to the Screen and the Log File.
The Message Type is presented in colours on the screen based on the type
.PARAMETER LogFile
The Log File to write to. By default using the LOG_FILE_PATH
.PARAMETER MSG
The message to log
.PARAMETER Header
Adding a header line before the message
.PARAMETER SubHeader
Adding a Sub header line before the message
.PARAMETER Footer
Adding a footer line after the message
.PARAMETER Type
The type of the message to log (Info, Warning, Error, Debug)
.EXAMPLE
Write-LogMessage -Type Info -Msg "Hello World!" -Header
Write-LogMessage -Type Info -Msg "How are you?" -SubHeader
Write-LogMessage -Type Info -Msg "I'm fine :)"
Write-LogMessage -Type Warning -Msg "Wait, something is happening..."
Write-LogMessage -Type Error -Msg "World! Something went wrong!"
Write-LogMessage -Type Debug -Msg "Something happened, this is the reason..."
Write-LogMessage -Type Info -Msg "Goodbye!" -Footer
#>
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[AllowEmptyString()]
[String]$MSG,
[Parameter(Mandatory=$false)]
[Switch]$Header,
[Parameter(Mandatory=$false)]
[Switch]$SubHeader,
[Parameter(Mandatory=$false)]
[Switch]$Footer,
[Parameter(Mandatory=$false)]
[ValidateSet("Info","Warning","Error","Debug","Verbose")]
[String]$type = "Info",
[Parameter(Mandatory=$false)]
[String]$LogFile = $LOG_FILE_PATH
)
Try{
If ($Header) {
"=======================================" | Out-File -Append -FilePath $LogFile
Write-Host "======================================="
}
ElseIf($SubHeader) {
"------------------------------------" | Out-File -Append -FilePath $LogFile
Write-Host "------------------------------------"
}

$msgToWrite = "[$(Get-Date -Format "yyyy-MM-dd hh:mm:ss")]`t"
$writeToFile = $true
# Replace empty message with 'N/A'
if([string]::IsNullOrEmpty($Msg)) { $Msg = "N/A" }

# Mask Passwords
if($Msg -match '((?:"password":|password=|"secret":|"NewCredentials":|"credentials":)\s{0,}["]{0,})(?=([\w`~!@#$%^&*()-_\=\+\\\/|;:\.,\[\]{}]+))')
{
$Msg = $Msg.Replace($Matches[2],"****")
}
# Check the message type
switch ($type)
{
"Info" {
Write-Host $MSG.ToString()
$msgToWrite += "[INFO]`t$Msg"
}
"Warning" {
Write-Host $MSG.ToString() -ForegroundColor DarkYellow
$msgToWrite += "[WARNING]`t$Msg"
}
"Error" {
Write-Host $MSG.ToString() -ForegroundColor Red
$msgToWrite += "[ERROR]`t$Msg"
}
"Debug" {
if($_InDebug -or $_InVerbose)
{
Write-Debug $MSG
$msgToWrite += "[DEBUG]`t$Msg"
}
else { $writeToFile = $False }
}
"Verbose" {
if($_InVerbose)
{
Write-Verbose -Msg $MSG
$msgToWrite += "[VERBOSE]`t$Msg"
}
else { $writeToFile = $False }
}
}

If($writeToFile) { $msgToWrite | Out-File -Append -FilePath $LogFile }
If ($Footer) {
"=======================================" | Out-File -Append -FilePath $LogFile
Write-Host "======================================="
}
}
catch{
Throw $(New-Object System.Exception ("Cannot write message"),$_.Exception)
}
}
Export-ModuleMember -Function Write-LogMessage

# @FUNCTION@ ======================================================================================================================
# Name...........: Join-ExceptionMessage
# Description....: Formats exception messages
# Parameters.....: Exception
# Return Values..: Formatted String of Exception messages
# =================================================================================================================================
Function Join-ExceptionMessage
{
<#
.SYNOPSIS
Formats exception messages
.DESCRIPTION
Formats exception messages
.PARAMETER Exception
The Exception object to format
#>
param(
[Exception]$e
)

Begin {
}
Process {
$msg = "Source:{0}; Message: {1}" -f $e.Source, $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n`t->Source:{0}; Message: {1}" -f $e.Source, $e.Message
}
return $msg
}
End {
}
}
Export-ModuleMember -Function Join-ExceptionMessage
129 changes: 128 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,129 @@
# PS-Logger
A Powershell module for logging any Powershell script
A Powershell module for logging any Powershell script
Simply import this module at the beginning of any of your Powershell scripts and use the methods to log anything easily.

## Main abilities
- Print a nice Header, Sub header and Footer lines
- Capture Debug and Verbose messages
- Capture Exception messages (even chained exceptions caused by other methods)

## Available Methods
- Set-DebugLogging
* Set the debug Logging from the Script parameters
- Get-LogFilePath
* Get the current Log File Path
* By default, using the Script name (with '.log' extension)
- Set-LogFilePath
* Set the Log File Path
- Write-LogMessage
* Write a log message in different Logging Types (Info, Warning, Error, Debug, Verbose)
- Join-ExceptionMessage
* In case of an exception, use this method to capture all exceptions that happened in that call

## Usage Examples
### Write Info and Debug messages
Script example:
```powershell
[CmdletBinding(DefaultParameterSetName="")]
param
()
# Import the PS-Logger to the script
Import-Module .\PS-Logger -Debug:$False -Verbose:$False
# Set the debug logging (if needed)
Set-DebugLogging -ScriptBoundParameters $PSBoundParameters
# Script Version
$ScriptVersion = "1.0"
Write-LogMessage -Type Info -MSG "Starting script (v$ScriptVersion)" -Header
Write-LogMessage -Type Debug -MSG "Running PowerShell version $($PSVersionTable.PSVersion.Major) compatible of versions $($PSVersionTable.PSCompatibleVersions -join ", ")" -LogFile $LOG_FILE_PATH
$machineName = $ENV:ComputerName
Write-LogMessage -Type Debug -MSG "Machine Name: $machineName"
$revMachineName = $machineName.ToCharArray()
[array]::Reverse($revMachineName)
$revMachineName = -Join($revMachineName)
Write-LogMessage -Type Debug -MSG "Reverse Machine Name: $revMachineName"
Write-LogMessage -Type Warning -MSG "Reversing Machine name ($machineName)..."
Write-LogMessage -Type Info -MSG "Reverse Machine name: $revMachineName"
Write-LogMessage -Type Info -MSG "Script ended" -Footer
Remove-Module PS-Logger -Debug:$False -Verbose:$False
```

On screen:
```batch
PS C:\Temp> .\temp.ps1 -Debug -Verbose
=======================================
Starting script (v1.0)
Reversing Machine name (AMPM-A9B0F407)...
Reverse Machine name: 704F0B9A-MPMA
Script ended
=======================================
```

Log file:
```text
[2020-08-16 01:58:25] [DEBUG] Running in Debug Mode
[2020-08-16 01:58:25] [VERBOSE] Running in Verbose Mode
=======================================
[2020-08-16 01:58:25] [INFO] Starting script (v1.0)
[2020-08-16 01:58:25] [DEBUG] Running PowerShell version 5 compatible of versions 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14393.1944
[2020-08-16 01:58:25] [DEBUG] Machine Name: AMPM-A9B0F407
[2020-08-16 01:58:25] [DEBUG] Reverse Machine Name: 704F0B9A-MPMA
[2020-08-16 01:58:25] [WARNING] Reversing Machine name (AMPM-A9B0F407)...
[2020-08-16 01:58:25] [INFO] Reverse Machine name: 704F0B9A-MPMA
[2020-08-16 01:58:25] [INFO] Script ended
=======================================
```

### Write Errors
Script example:
```powershell
[CmdletBinding(DefaultParameterSetName="")]
param
()
# Import the PS-Logger to the script
Import-Module .\PS-Logger
Set-DebugLogging -ScriptBoundParameters $PSBoundParameters
try{
try{
Write-LogMessage -Type Info "Starting to throw errors..."
Throw "This is the first Error!"
}
catch{
Throw $(New-Object System.Exception ("Throwing a second error with the previous exception"),$_.Exception)
}
}
catch{
Write-LogMessage -Type Error -Msg "There was a script error.`nError Details:`n $(Join-ExceptionMessage $_.Exception)"
}
Write-LogMessage -Type Info -MSG "Script ended" -Footer
Remove-Module PS-Logger
```

On screen:
```batch
PS C:\Temp> .\temp.ps1
Starting to throw errors...
There was a script error.
Error Details:
Source:; Message: Throwing a second error with the previous exception
->Source:; Message: This is the first Error!
Script ended
=======================================
```

Log file:
```text
[2020-08-16 03:04:38] [INFO] Starting to throw errors...
[2020-08-16 03:04:38] [ERROR] There was a script error.
Error Details:
Source:; Message: Throwing a second error with the previous exception
->Source:; Message: This is the first Error!
[2020-08-16 03:04:38] [INFO] Script ended
=======================================
```

0 comments on commit 23a4f39

Please sign in to comment.