Public/Write-CustomLog.ps1

Function Write-CustomLog{
    <#
        .SYNOPSIS
        Show log message (with usefull information) on console or store it in a file with append format. (Logging)
 
        .DESCRIPTION
        Note: This function is desined to be call in any script and path $MyInvocation parameter to it.
        This function receives a messages as an input, and show it on screen or save it as a log format.
        If you do noe define severity level, information will be choosen as default.
        If you do not define a path, this function will create 'Logs' folder in C:\ and stores report in this location.
        If you want to store report in a file, -SaveLog switch should be set.
        If -Verbose is used on either this command or parent script, message will be shown as verbose message on console.
 
        .EXAMPLE
        PS> Write-CustomLog -Message "Target node was removed !" -InvocInfo $MyInvocation -SaveLog
 
        Output in file:
 
        "Timestamp","Level","Source","User","Message"
        "5/28/2024 5:07:42 PM","Information","Remove-Node","User01","Target node was removed !"
    #>

    [Cmdletbinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [System.Management.Automation.InvocationInfo]$InvocInfo,

        [Parameter(Mandatory = $true)]
        [string]$Message,

        [string]$Path,

        [ValidateSet("Critical","Debug","Error","Information","Warning")]
        [string]$LogLevel = "Information" ,

        [switch]$SaveLog
    )

    $logFolder = $null
    $logFile = $null
    $source = $InvocInfo.MyCommand.Name.Split(".")[0]

    if($SaveLog.IsPresent){
        if ($PSBoundParameters.ContainsKey('Path')){
            $logFolder = $Path
        }
        else{
            $logFolder = "C:\Logs"
        }

        $filename = ($InvocInfo.MyCommand.Name.Split(".")[0]) + ".log"
        $logFile = Join-Path -Path $logFolder -ChildPath $filename
    }

    $timeZoneId = (Get-TimeZone).Id

    $log = [Parmis.Common.Log]::new()
    $log.Timestamp = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetime]::UtcNow, $timeZoneId)
    $log.Level = $LogLevel
    $log.Source = $source
    $log.Message = $Message
    $log.User = ($env:USERNAME)

    if($InvocInfo.BoundParameters.ContainsKey('Verbose') -or $MyInvocation.BoundParameters.ContainsKey('Verbose')){
        $msg = $log | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1
        Write-Verbose -Message $msg -Verbose
    }

    if($SaveLog.IsPresent){
        if(!(Test-Path -Path $logFolder)){
            New-Item -Path $scriptPath -Name "Logs" -ItemType Directory -Force | Out-Null
        }
        $log | Export-Csv -Path $logFile -Append  -NoTypeInformation
    }
}