EnhancedLoggingAO.psm1
#Region '.\Private\AppendCSVLog.ps1' -1 #Unique Tracking ID: 737397f0-c74e-4087-9b99-279b520b7448, Timestamp: 2024-03-20 12:25:26 function AppendCSVLog { param ( [string]$Message, [string]$CSVFilePath_1001 ) $csvData = [PSCustomObject]@{ TimeStamp = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') ComputerName = $env:COMPUTERNAME Message = $Message } $csvData | Export-Csv -Path $CSVFilePath_1001 -Append -NoTypeInformation -Force } #EndRegion '.\Private\AppendCSVLog.ps1' 17 #Region '.\Private\CreateEventSourceAndLog.ps1' -1 #Unique Tracking ID: 4362313d-3c19-4d0c-933d-99438a6da297, Timestamp: 2024-03-20 12:25:26 function CreateEventSourceAndLog { param ( [string]$LogName, [string]$EventSource ) # Validate parameters if (-not $LogName) { Write-Warning "LogName is required." return } if (-not $EventSource) { Write-Warning "Source is required." return } # Function to create event log and source function CreateEventLogSource($logName, $EventSource) { try { if ($PSVersionTable.PSVersion.Major -lt 6) { New-EventLog -LogName $logName -Source $EventSource } else { [System.Diagnostics.EventLog]::CreateEventSource($EventSource, $logName) } Write-Host "Event source '$EventSource' created in log '$logName'" -ForegroundColor Green } catch { Write-Warning "Error creating the event log. Make sure you run PowerShell as an Administrator." } } # Check if the event log exists if (-not (Get-WinEvent -ListLog $LogName -ErrorAction SilentlyContinue)) { # CreateEventLogSource $LogName $EventSource } # Check if the event source exists elseif (-not ([System.Diagnostics.EventLog]::SourceExists($EventSource))) { # Unregister the source if it's registered with a different log $existingLogName = (Get-WinEvent -ListLog * | Where-Object { $_.LogName -contains $EventSource }).LogName if ($existingLogName -ne $LogName) { Remove-EventLog -Source $EventSource -ErrorAction SilentlyContinue } # CreateEventLogSource $LogName $EventSource } else { Write-Host "Event source '$EventSource' already exists in log '$LogName'" -ForegroundColor Yellow } } # $LogName = (Get-Date -Format "HHmmss") + "_$LoggingDeploymentName" # $EventSource = (Get-Date -Format "HHmmss") + "_$LoggingDeploymentName" # Call the Create-EventSourceAndLog function # CreateEventSourceAndLog -LogName $LogName -EventSource $EventSource # Call the Write-CustomEventLog function with custom parameters and level # Write-CustomEventLog -LogName $LogName -EventSource $EventSource -EventMessage "Outlook Signature Restore completed with warnings." -EventID 1001 -Level 'WARNING' #EndRegion '.\Private\CreateEventSourceAndLog.ps1' 62 #Region '.\Private\Export-EventLog.ps1' -1 #Unique Tracking ID: c00ecaca-dd4b-4c7c-b80e-566b2f627e32, Timestamp: 2024-03-20 12:25:26 function Export-EventLog { param ( [Parameter(Mandatory = $true)] [string]$LogName, [Parameter(Mandatory = $true)] [string]$ExportPath ) try { wevtutil epl $LogName $ExportPath if (Test-Path $ExportPath) { Write-EnhancedLog -Message "Event log '$LogName' exported to '$ExportPath'" -Level "INFO" -ForegroundColor ([ConsoleColor]::Green) } else { Write-EnhancedLog -Message "Event log '$LogName' not exported: File does not exist at '$ExportPath'" -Level "WARNING" -ForegroundColor ([ConsoleColor]::Yellow) } } catch { Write-EnhancedLog -Message "Error exporting event log '$LogName': $($_.Exception.Message)" -Level "ERROR" -ForegroundColor ([ConsoleColor]::Red) } } # # Example usage # $LogName = '$LoggingDeploymentNameLog' # # $ExportPath = 'Path\to\your\exported\eventlog.evtx' # $ExportPath = "C:\code\$LoggingDeploymentName\exports\Logs\$logname.evtx" # Export-EventLog -LogName $LogName -ExportPath $ExportPath #EndRegion '.\Private\Export-EventLog.ps1' 30 #Region '.\Private\Initialize-CSVDirectory.ps1' -1 function Initialize-CSVDirectory { param ( [string]$deploymentName, [string]$computerName ) $isWindowsOS = $false if ($PSVersionTable.PSVersion.Major -ge 6) { $isWindowsOS = $isWindowsOS -or ($PSVersionTable.Platform -eq 'Win32NT') } else { $isWindowsOS = $isWindowsOS -or ($env:OS -eq 'Windows_NT') } $baseScriptPath = if ($isWindowsOS) { "C:\code" } else { "/home/code" } $scriptPath_1001 = Join-Path -Path $baseScriptPath -ChildPath $deploymentName $CSVDir_1001 = Join-Path -Path $scriptPath_1001 -ChildPath "exports/CSV" $CSVFilePath_1001 = Join-Path -Path $CSVDir_1001 -ChildPath "$computerName" try { if (-not (Test-Path $CSVFilePath_1001)) { Write-Host "Did not find CSV directory at $CSVFilePath_1001" -ForegroundColor Yellow Write-Host "Creating CSV directory at $CSVFilePath_1001" -ForegroundColor Yellow New-Item -ItemType Directory -Path $CSVFilePath_1001 -Force -ErrorAction Stop | Out-Null Write-Host "Created CSV directory at $CSVFilePath_1001" -ForegroundColor Green } return @{ CSVFilePath = $CSVFilePath_1001 } } catch { Write-Host "An error occurred while initializing CSV directory: $_" -ForegroundColor Red } } # # Example usage of Initialize-CSVDirectory # try { # $csvInitResult = Initialize-CSVDirectory -deploymentName "$LoggingDeploymentName" -computerName $env:COMPUTERNAME # Write-Host "CSV initialization successful. CSV directory path: $($csvInitResult.CSVFilePath)" -ForegroundColor Green # } catch { # Write-Host "CSV initialization failed: $_" -ForegroundColor Red # } #EndRegion '.\Private\Initialize-CSVDirectory.ps1' 42 #Region '.\Private\Write-EventLogMessage.ps1' -1 #Unique Tracking ID: 132a90f9-6ba2-49cd-878b-279deadb8e22, Timestamp: 2024-03-20 12:25:26 function Write-EventLogMessage { param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Message, [string]$LogName = "$LoggingDeploymentName", [string]$EventSource, [int]$EventID = 1000 # Default event ID ) $ErrorActionPreference = 'SilentlyContinue' $hadError = $false try { if (-not $EventSource) { throw "EventSource is required." } if ($PSVersionTable.PSVersion.Major -lt 6) { # PowerShell version is less than 6, use Write-EventLog Write-EventLog -LogName $logName -Source $EventSource -EntryType Information -EventId $EventID -Message $Message } else { # PowerShell version is 6 or greater, use System.Diagnostics.EventLog $eventLog = New-Object System.Diagnostics.EventLog($logName) $eventLog.Source = $EventSource $eventLog.WriteEntry($Message, [System.Diagnostics.EventLogEntryType]::Information, $EventID) } # Write-Host "Event log entry created: $Message" } catch { Write-Host "Error creating event log entry: $_" $hadError = $true } if (-not $hadError) { # Write-Host "Event log message writing completed successfully." } } #EndRegion '.\Private\Write-EventLogMessage.ps1' 46 #Region '.\Public\Add-Step.ps1' -1 function Add-Step { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$Description, [Parameter(Mandatory = $true)] [ScriptBlock]$Action ) Begin { Write-EnhancedLog -Message "Starting Add-Step function" -Level "INFO" Log-Params -Params @{ Description = $Description Action = $Action.ToString() } } Process { try { Write-EnhancedLog -Message "Adding step: $Description" -Level "INFO" $global:steps.Add([PSCustomObject]@{ Description = $Description; Action = $Action }) } catch { Write-EnhancedLog -Message "An error occurred while adding step: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Add-Step function" -Level "INFO" } } # Example usage # Add-Step -Description "Sample step description" -Action { Write-Output "Sample action" } #EndRegion '.\Public\Add-Step.ps1' 36 #Region '.\Public\Export-Data.ps1' -1 function Export-Data { <# .SYNOPSIS Exports data to various formats including CSV, JSON, XML, HTML, PlainText, Excel, PDF, Markdown, and YAML. .DESCRIPTION The Export-Data function exports provided data to multiple file formats based on switches provided. It supports CSV, JSON, XML, GridView (for display only), HTML, PlainText, Excel, PDF, Markdown, and YAML formats. This function is designed to work with any PSObject. .PARAMETER Data The data to be exported. This parameter accepts input of type PSObject. .PARAMETER BaseOutputPath The base path for output files without file extension. This path is used to generate filenames for each export format. .PARAMETER IncludeCSV Switch to include CSV format in the export. .PARAMETER IncludeJSON Switch to include JSON format in the export. .PARAMETER IncludeXML Switch to include XML format in the export. .PARAMETER IncludeGridView Switch to display the data in a GridView. .PARAMETER IncludeHTML Switch to include HTML format in the export. .PARAMETER IncludePlainText Switch to include PlainText format in the export. .PARAMETER IncludePDF Switch to include PDF format in the export. Requires intermediate HTML to PDF conversion. .PARAMETER IncludeExcel Switch to include Excel format in the export. .PARAMETER IncludeMarkdown Switch to include Markdown format in the export. Custom or use a module if available. .PARAMETER IncludeYAML Switch to include YAML format in the export. Requires 'powershell-yaml' module. .EXAMPLE PS> $data = Get-Process | Select-Object -First 10 PS> Export-Data -Data $data -BaseOutputPath "C:\exports\mydata" -IncludeCSV -IncludeJSON This example exports the first 10 processes to CSV and JSON formats. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [psobject]$Data, [Parameter(Mandatory = $true)] [string]$BaseOutputPath, [switch]$IncludeCSV, [switch]$IncludeJSON, [switch]$IncludeXML, [switch]$IncludeGridView, [switch]$IncludeHTML, [switch]$IncludePlainText, [switch]$IncludePDF, # Requires intermediate HTML to PDF conversion [switch]$IncludeExcel, [switch]$IncludeMarkdown, # Custom or use a module if available [switch]$IncludeYAML # Requires 'powershell-yaml' module ) Begin { # $modules = @('ImportExcel', 'powershell-yaml' , 'PSWriteHTML') # Install-MissingModules -RequiredModules $modules -Verbose # Setup the base path without extension Write-Host "BaseOutputPath before change: '$BaseOutputPath'" $basePathWithoutExtension = [System.IO.Path]::ChangeExtension($BaseOutputPath, $null) # Remove extension manually if it exists $basePathWithoutExtension = if ($BaseOutputPath -match '\.') { $BaseOutputPath.Substring(0, $BaseOutputPath.LastIndexOf('.')) } else { $BaseOutputPath } # Ensure no trailing periods $basePathWithoutExtension = $basePathWithoutExtension.TrimEnd('.') } Process { try { if ($IncludeCSV) { $csvPath = "$basePathWithoutExtension.csv" $Data | Export-Csv -Path $csvPath -NoTypeInformation } if ($IncludeJSON) { $jsonPath = "$basePathWithoutExtension.json" $Data | ConvertTo-Json -Depth 10 | Set-Content -Path $jsonPath } if ($IncludeXML) { $xmlPath = "$basePathWithoutExtension.xml" $Data | Export-Clixml -Path $xmlPath } if ($IncludeGridView) { $Data | Out-GridView -Title "Data Preview" } if ($IncludeHTML) { # Assumes $Data is the dataset you want to export to HTML # and $basePathWithoutExtension is prepared earlier in your script $htmlPath = "$basePathWithoutExtension.html" # Convert $Data to HTML using PSWriteHTML New-HTML -Title "Data Export Report" -FilePath $htmlPath -ShowHTML { New-HTMLSection -HeaderText "Data Export Details" -Content { New-HTMLTable -DataTable $Data -ScrollX -HideFooter } } Write-Host "HTML report generated: '$htmlPath'" } if ($IncludePlainText) { $txtPath = "$basePathWithoutExtension.txt" $Data | Out-String | Set-Content -Path $txtPath } if ($IncludeExcel) { $excelPath = "$basePathWithoutExtension.xlsx" $Data | Export-Excel -Path $excelPath } # Assuming $Data holds the objects you want to serialize to YAML if ($IncludeYAML) { $yamlPath = "$basePathWithoutExtension.yaml" # Check if the powershell-yaml module is loaded if (Get-Module -ListAvailable -Name powershell-yaml) { Import-Module powershell-yaml # Process $Data to handle potentially problematic properties $processedData = $Data | ForEach-Object { $originalObject = $_ $properties = $_ | Get-Member -MemberType Properties $clonedObject = New-Object -TypeName PSObject foreach ($prop in $properties) { try { $clonedObject | Add-Member -MemberType NoteProperty -Name $prop.Name -Value $originalObject.$($prop.Name) -ErrorAction Stop } catch { # Optionally handle or log the error. Skipping problematic property. $clonedObject | Add-Member -MemberType NoteProperty -Name $prop.Name -Value "Error serializing property" -ErrorAction SilentlyContinue } } return $clonedObject } # Convert the processed data to YAML and save it with UTF-16 LE encoding $processedData | ConvertTo-Yaml | Set-Content -Path $yamlPath -Encoding Unicode Write-Host "YAML export completed successfully: $yamlPath" } else { Write-Warning "The 'powershell-yaml' module is not installed. YAML export skipped." } } if ($IncludeMarkdown) { # You'll need to implement or find a ConvertTo-Markdown function or use a suitable module $markdownPath = "$basePathWithoutExtension.md" $Data | ConvertTo-Markdown | Set-Content -Path $markdownPath } if ($IncludePDF) { # Convert HTML to PDF using external tool # This is a placeholder for the process. You will need to generate HTML first and then convert it. $pdfPath = "$basePathWithoutExtension.pdf" # Assuming you have a Convert-HtmlToPdf function or a similar mechanism $htmlPath = "$basePathWithoutExtension.html" $Data | ConvertTo-Html | Convert-HtmlToPdf -OutputPath $pdfPath } } catch { Write-Error "An error occurred during export: $_" } } End { Write-Verbose "Export-Data function execution completed." } } #EndRegion '.\Public\Export-Data.ps1' 206 #Region '.\Public\Get-TranscriptFilePath.ps1' -1 function Get-TranscriptFilePath { [CmdletBinding()] param ( [string]$TranscriptsPath = "C:\Logs\Transcript", [string]$JobName = "AAD Migration" ) # Ensure the destination directory exists if (-not (Test-Path -Path $TranscriptsPath)) { New-Item -ItemType Directory -Path $TranscriptsPath -Force Write-EnhancedLog -Message "Created Transcripts directory at: $TranscriptsPath" -Level "INFO" } try { # Log the start of the function Write-EnhancedLog -Message "Starting Get-TranscriptFilePath function..." -Level "NOTICE" # Get the current username $username = if ($env:USERNAME) { $env:USERNAME } else { "UnknownUser" } Write-EnhancedLog -Message "Current username: $username" -Level "INFO" # Get the script name from $MyInvocation $scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName) if (-not $scriptName) { $scriptName = "UnknownScript" } Write-EnhancedLog -Message "Script name: $scriptName" -Level "INFO" # Check if running as SYSTEM using Test-RunningAsSystem $isSystem = Test-RunningAsSystem Write-EnhancedLog -Message "Is running as SYSTEM: $isSystem" -Level "INFO" # Get the current date for folder creation $currentDate = Get-Date -Format "yyyy-MM-dd" $hostname = $env:COMPUTERNAME $timestamp = Get-Date -Format "yyyy-MM-dd-HH-mm-ss" $logFolderPath = "$TranscriptsPath\$currentDate\$scriptName" # Ensure the log directory exists if (-not (Test-Path -Path $logFolderPath)) { New-Item -Path $logFolderPath -ItemType Directory -Force Write-EnhancedLog -Message "Created directory for log file: $logFolderPath" -Level "INFO" } # Generate log file path based on context if ($isSystem) { $logFilePath = "$logFolderPath\$hostname-$JobName-SYSTEM-$scriptName-transcript-$timestamp.log" Write-EnhancedLog -Message "Generated log file path for SYSTEM: $logFilePath" -Level "INFO" } else { $logFilePath = "$logFolderPath\$hostname-$JobName-$username-$scriptName-transcript-$timestamp.log" Write-EnhancedLog -Message "Generated log file path for non-SYSTEM: $logFilePath" -Level "INFO" } # Convert the logFilePath to a string explicitly $logFilePath = [string]$logFilePath Write-EnhancedLog -Message "Exiting Get-TranscriptFilePath function" -Level "NOTICE" return $logFilePath } catch { Write-EnhancedLog -Message "An error occurred in Get-TranscriptFilePath: $_" -Level "ERROR" Handle-Error -ErrorRecord $_ throw $_ # Re-throw the error after logging it } } #EndRegion '.\Public\Get-TranscriptFilePath.ps1' 68 #Region '.\Public\Handle-Error.ps1' -1 function Handle-Error { param ( [Parameter(Mandatory = $true)] [System.Management.Automation.ErrorRecord]$ErrorRecord ) try { if ($PSVersionTable.PSVersion.Major -ge 7) { $fullErrorDetails = Get-Error -InputObject $ErrorRecord | Out-String } else { $fullErrorDetails = $ErrorRecord.Exception | Format-List * -Force | Out-String } Write-EnhancedLog -Message "Exception Message: $($ErrorRecord.Exception.Message)" -Level "ERROR" Write-EnhancedLog -Message "Full Exception: $fullErrorDetails" -Level "ERROR" } catch { # Fallback error handling in case of an unexpected error in the try block Write-EnhancedLog -Message "An error occurred while handling another error. Original Exception: $($ErrorRecord.Exception.Message)" -Level "CRITICAL" Write-EnhancedLog -Message "Handler Exception: $($_.Exception.Message)" -Level "CRITICAL" Write-EnhancedLog -Message "Handler Full Exception: $($_ | Out-String)" -Level "CRITICAL" } } # # Example usage of Handle-Error # try { # # Intentionally cause an error for demonstration purposes # throw "This is a test error" # } catch { # Handle-Error -ErrorRecord $_ # } #EndRegion '.\Public\Handle-Error.ps1' 34 #Region '.\Public\Handle-PSFLogging.ps1' -1 function Handle-PSFLogging { [CmdletBinding()] param ( [string]$systemSourcePath = "C:\Windows\System32\config\systemprofile\AppData\Roaming\WindowsPowerShell\PSFramework\Logs\", [string]$PSFPath = "C:\Logs\PSF" ) try { # Get the current username and script name $username = if ($env:USERNAME) { $env:USERNAME } else { "UnknownUser" } $scriptName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.ScriptName) if (-not $scriptName) { $scriptName = "UnknownScript" } # Get the current date for folder creation $currentDate = Get-Date -Format "yyyy-MM-dd" $logFolderPath = "$PSFPath\$currentDate\$scriptName" # Ensure the destination directory exists if (-not (Test-Path -Path $logFolderPath)) { New-Item -ItemType Directory -Path $logFolderPath -Force Write-EnhancedLog -Message "Created destination directory at $logFolderPath" -Level "INFO" } # Copy logs from the SYSTEM profile path if (Test-Path -Path $systemSourcePath) { try { Copy-Item -Path "$systemSourcePath*" -Destination $logFolderPath -Recurse -Force -ErrorAction Stop Write-EnhancedLog -Message "SYSTEM profile log files successfully copied to $logFolderPath" -Level "INFO" } catch { Write-EnhancedLog -Message "Failed to copy SYSTEM profile logs. Error: $_" -Level "ERROR" } } else { Write-EnhancedLog -Message "SYSTEM profile log path not found: $systemSourcePath" -Level "WARNING" } # Copy logs from the user's profile path $userSourcePath = "$env:USERPROFILE\AppData\Roaming\WindowsPowerShell\PSFramework\Logs\" if (Test-Path -Path $userSourcePath) { try { Copy-Item -Path "$userSourcePath*" -Destination $logFolderPath -Recurse -Force -ErrorAction Stop Write-EnhancedLog -Message "User profile log files successfully copied to $logFolderPath" -Level "INFO" } catch { Write-EnhancedLog -Message "Failed to copy user profile logs. Error: $_" -Level "ERROR" } } else { Write-EnhancedLog -Message "User profile log path not found: $userSourcePath" -Level "WARNING" } # Verify that the files have been copied if (Test-Path -Path $logFolderPath) { Write-EnhancedLog -Message "Logs successfully processed to $logFolderPath" -Level "INFO" } else { Write-EnhancedLog -Message "Failed to process log files." -Level "ERROR" } # Remove logs from the SYSTEM profile path if (Test-Path -Path $systemSourcePath) { try { Remove-Item -Path "$systemSourcePath*" -Recurse -Force -ErrorAction Stop Write-EnhancedLog -Message "Logs successfully removed from $systemSourcePath" -Level "INFO" } catch { Write-EnhancedLog -Message "Failed to remove logs. Error: $_" -Level "ERROR" } } else { Write-EnhancedLog -Message "Log path not found: $systemSourcePath" -Level "WARNING" } #Rename SYSTEM logs in PSF to append SYSTEM to easily identify these files as they were generated in the SYSTEM context and their levels are setup to Output instead of Info Rename-LogFilesWithUsername -LogDirectoryPath $logFolderPath # Remove logs from the user profile path # if (Test-Path -Path $userSourcePath) { # try { # Remove-Item -Path "$userSourcePath*" -Recurse -Force -ErrorAction Stop # Write-EnhancedLog -Message "Logs successfully removed from $userSourcePath" -Level "INFO" # } # catch { # Write-EnhancedLog -Message "Failed to remove logs. Error: $_" -Level "ERROR" # } # } # else { # Write-EnhancedLog -Message "Log path not found: $userSourcePath" -Level "WARNING" # } } catch { Write-EnhancedLog -Message "An error occurred in Handle-PSFLogging: $_" -Level "ERROR" Handle-Error -ErrorRecord $_ throw $_ # Re-throw the error after logging it } } #usage # $HandlePSFLoggingParams = @{ # systemSourcePath = "C:\Windows\System32\config\systemprofile\AppData\Roaming\WindowsPowerShell\PSFramework\Logs\" # PSFPath = "C:\Logs\PSF" # } # Handle-PSFLogging @HandlePSFLoggingParams #EndRegion '.\Public\Handle-PSFLogging.ps1' 110 #Region '.\Public\Initialize-ScriptAndLogging.ps1' -1 $LoggingDeploymentName = $config.LoggingDeploymentName function Initialize-ScriptAndLogging { $isWindowsOS = $false if ($PSVersionTable.PSVersion.Major -ge 6) { $isWindowsOS = $isWindowsOS -or ($PSVersionTable.Platform -eq 'Win32NT') } else { $isWindowsOS = $isWindowsOS -or ($env:OS -eq 'Windows_NT') } $deploymentName = "$LoggingDeploymentName" # Replace this with your actual deployment name $baseScriptPath = if ($isWindowsOS) { "C:\code" } else { "/home/code" } $scriptPath_1001 = Join-Path -Path $baseScriptPath -ChildPath $deploymentName $computerName = if ($isWindowsOS) { $env:COMPUTERNAME } else { (hostname) } try { if (-not (Test-Path -Path $scriptPath_1001)) { New-Item -ItemType Directory -Path $scriptPath_1001 -Force | Out-Null Write-Host "Created directory: $scriptPath_1001" -ForegroundColor Green } $Filename = "$LoggingDeploymentName" $logDir = Join-Path -Path $scriptPath_1001 -ChildPath "exports/Logs/$computerName" $logPath = Join-Path -Path $logDir -ChildPath "$(Get-Date -Format 'yyyy-MM-dd-HH-mm-ss')" if (-not (Test-Path $logPath)) { Write-Host "Did not find log directory at $logPath" -ForegroundColor Yellow Write-Host "Creating log directory at $logPath" -ForegroundColor Yellow New-Item -ItemType Directory -Path $logPath -Force -ErrorAction Stop | Out-Null Write-Host "Created log directory at $logPath" -ForegroundColor Green } $logFile = Join-Path -Path $logPath -ChildPath "$Filename-Transcript.log" Start-Transcript -Path $logFile -ErrorAction Stop | Out-Null return @{ ScriptPath = $scriptPath_1001 Filename = $Filename LogPath = $logPath LogFile = $logFile } } catch { Write-Host "An error occurred while initializing script and logging: $_" -ForegroundColor Red } } # Example usage of Initialize-ScriptAndLogging # try { # $initResult = Initialize-ScriptAndLogging # Write-Host "Initialization successful. Log file path: $($initResult.LogFile)" -ForegroundColor Green # } catch { # Write-Host "Initialization failed: $_" -ForegroundColor Red # } #EndRegion '.\Public\Initialize-ScriptAndLogging.ps1' 55 #Region '.\Public\Log-And-Execute-Step.ps1' -1 function Log-And-Execute-Step { [CmdletBinding()] param () Begin { Write-EnhancedLog -Message "Starting Log-And-Execute-Step function" -Level "INFO" } Process { try { $global:currentStep++ $totalSteps = $global:steps.Count $step = $global:steps[$global:currentStep - 1] Write-EnhancedLog -Message "Step [$global:currentStep/$totalSteps]: $($step.Description)" -Level "INFO" & $step.Action } catch { Write-EnhancedLog -Message "Error in step: $($step.Description) - $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { Write-EnhancedLog -Message "Exiting Log-And-Execute-Step function" -Level "INFO" } } # Example usage # Log-And-Execute-Step #EndRegion '.\Public\Log-And-Execute-Step.ps1' 30 #Region '.\Public\Log-Params.ps1' -1 function Log-Params { <# .SYNOPSIS Logs the provided parameters and their values. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [hashtable]$Params ) Begin { # Write-EnhancedLog -Message "Starting Log-Params function" -Level "INFO" } Process { try { foreach ($key in $Params.Keys) { Write-EnhancedLog -Message "$key $($Params[$key])" -Level "INFO" } } catch { Write-EnhancedLog -Message "An error occurred while logging parameters: $($_.Exception.Message)" -Level "ERROR" Handle-Error -ErrorRecord $_ } } End { # Write-EnhancedLog -Message "Exiting Log-Params function" -Level "INFO" } } #EndRegion '.\Public\Log-Params.ps1' 31 #Region '.\Public\Rename-LogFilesWithUsername.ps1' -1 function Rename-LogFilesWithUsername { param ( [string]$LogDirectoryPath = "C:\Logs\PSF" ) Write-Host "Starting the renaming process for log files in directory: $LogDirectoryPath" # Get all log files in the specified directory $logFiles = Get-ChildItem -Path $LogDirectoryPath -Filter "*.log" if ($logFiles.Count -eq 0) { Write-Host "No log files found in the directory." -ForegroundColor Yellow return } Write-Host "Found $($logFiles.Count) log files to process." foreach ($logFile in $logFiles) { try { Write-Host "Processing file: $($logFile.FullName)" # Load the log file (assuming it can be imported as CSV for simplicity) $logEntries = Import-Csv -Path $logFile.FullName # Assume the first entry's username field for demonstration $username = $logEntries | Select-Object -First 1 | ForEach-Object { $_.Username } if (-not $username) { Write-Host "No username found in $($logFile.Name). Skipping file." -ForegroundColor Yellow continue } Write-Host "Username found in file: $username" # Sanitize the username by removing or replacing invalid characters $safeUsername = $username -replace '[\\/:*?"<>|]', '_' Write-Host "Sanitized username: $safeUsername" # Generate the new file name by appending the sanitized username $originalFileName = [System.IO.Path]::GetFileNameWithoutExtension($logFile.FullName) $fileExtension = [System.IO.Path]::GetExtension($logFile.FullName) $newFileName = "$originalFileName-$safeUsername$fileExtension" $newFilePath = [System.IO.Path]::Combine($logFile.DirectoryName, $newFileName) Write-Host "Attempting to rename to: $newFilePath" # Perform the rename operation Rename-Item -Path $logFile.FullName -NewName $newFileName -Force Write-Host "Successfully renamed $($logFile.FullName) to $newFileName" -ForegroundColor Green } catch { Write-Host "Failed to process $($logFile.FullName): $_" -ForegroundColor Red Write-Host "Possible cause: The file name or path may contain invalid characters or the file might be in use." } } Write-Host "Finished processing all log files." } # Run the function on the specified directory # Rename-LogFilesWithUsername -LogDirectoryPath "C:\Logs\PSF" #EndRegion '.\Public\Rename-LogFilesWithUsername.ps1' 60 #Region '.\Public\Write-EnhancedLog.ps1' -1 function Write-EnhancedLog { param ( [string]$Message, [string]$Level = 'INFO' ) # Get the PowerShell call stack to determine the actual calling function $callStack = Get-PSCallStack $callerFunction = if ($callStack.Count -ge 2) { $callStack[1].Command } else { '<Unknown>' } # Prepare the formatted message with the actual calling function information $formattedMessage = "[$Level] $Message" # Map custom levels to PSFramework levels $psfLevel = switch ($Level.ToUpper()) { 'DEBUG' { 'Debug' } 'INFO' { 'Host' } 'NOTICE' { 'Important' } 'WARNING' { 'Warning' } 'ERROR' { 'Error' } 'CRITICAL' { 'Critical' } 'IMPORTANT' { 'Important' } 'OUTPUT' { 'Output' } 'SIGNIFICANT' { 'Significant' } 'VERYVERBOSE' { 'VeryVerbose' } 'VERBOSE' { 'Verbose' } 'SOMEWHATVERBOSE' { 'SomewhatVerbose' } 'SYSTEM' { 'System' } 'INTERNALCOMMENT' { 'InternalComment' } default { 'Host' } } # Log the message using PSFramework with the actual calling function name Write-PSFMessage -Level $psfLevel -Message $formattedMessage -FunctionName $callerFunction } #EndRegion '.\Public\Write-EnhancedLog.ps1' 36 |