Как создать файл журнала в power shell script

What are the PowerShell logs being collected?

In Windows, there are a few default PowerShell EventLogs available:

  • Windows PowerShell
  • PowerShellCore/Operational
  • Microsoft-Windows-PowerShell/Admin
  • Microsoft-Windows-PowerShell/Operational
  • Microsoft-Windows-PowerShell-DesiredStateConfiguration-FileDownloadManager/Operational
  • Microsoft-Windows-WinRM/Operational

How does the script work?

You can start the script and specify these parameters:

  • -Computername You can specify one (W2K22DC, for example) or multiple separated by a comma (“W2K22DC, W2K22Member”, for example). If not specified, it will be your local system.
  • -Filename You can specify the location of the Excel sheet in which the results will be saved. C:\Temp\Events.xlsx, for example. The FileName parameter is Mandatory.
  • -PowerShellEventLogOnly When specified, the script will only export events from the EventLogs and not from the PSReadLine history.
  • -PSReadLineHistoryOnly When specified, the script will only export the command lines found in the PSReadLine history files, not the EventLogs data.

The data is being saved to an Excel file in two tabs, one for the EventLog data and one for the PSReadline history. When you run it against multiple computers, you can filter those on the ComputerName column.

The script also checks if the specified Excel file is already present and will append data to it if that’s the case. Both tabs have a time and date suffix, including the time you ran it so that it won’t insert the same date twice.

If the script can’t access something, it will show that on screen as a warning message. Green lines are good, and grey ones are information (That it couldn’t find events in a certain log, for example)

Running the script

Below is the screen status output when I ran the script on my Windows Server 2022 Domain Controller and specified (using the -ComputerName parameter) to scan that and the Windows 2022 member server. The output is saved to c:\temp\events.csv (Using the -Filename parameter).

Как создать файл журнала в power shell script

Screen output of the script

Example Excel file

Based on the two scanned servers above, the Excel file looks like this:

Как создать файл журнала в power shell script

The PowerShell Eventlogs

Some of the messages are very long. To view it in the cell, you can double-click it or use the Wrap Text button to let it expand for you:

Как создать файл журнала в power shell script

An expanded cell to view its contents

You can use the Filter on the ComputerName, for example, to display only a specific machine or to filter for a specific keyword:

Как создать файл журнала в power shell script

Filtering computers or text

Below is a screenshot of the PSReadLine history; as you can see, it shows all your history. 🙂 (This is dangerous if you have credentials, API keys in it, etc.)

Как создать файл журнала в power shell script

The script

Below are the contents of the Get-PowerShellLogs script. Save it somewhere (c:\scripts\Get-PowerShellLogs.ps1, for example) and run it with the abovementioned parameters. For example:

C:\Scripts\Get-PowerShellLogs.ps1 -ComputerName w2k22member -Filename C:\Temp\events.xlsx -PowerShellEventlogOnly
#Requires -RunAsAdministrator
[CmdletBinding(DefaultparameterSetname = 'All')]
param( [parameter(Mandatory = $false)][string[]]$ComputerName = $env:COMPUTERNAME, [parameter(Mandatory = $true)][string]$Filename, [parameter(Mandatory = $false, parameterSetname = "EventLog")][switch]$PowerShellEventlogOnly, [parameter(Mandatory = $false, parameterSetname = "History")][switch]$PSReadLineHistoryOnly
)
#Validate output $filename
if (-not ($Filename.EndsWith('.xlsx'))) { Write-Warning ("Specified {0} filename does not end with .xlsx, exiting..." -f $Filename) return
}
#Check access to the path, and if the file already exists, append if it does or test the creation of a new one
if (-not (Test-Path -Path $Filename)) { try { New-Item -Path $Filename -ItemType File -Force:$true -Confirm:$false -ErrorAction Stop | Out-Null Remove-Item -Path $Filename -Force:$true -Confirm:$false | Out-Null Write-Host ("Specified {0} filename is correct, and the path is accessible, continuing..." -f $Filename) -ForegroundColor Green } catch { Write-Warning ("Path to specified {0} filename is not accessible, correct or file is in use, exiting..." -f $Filename) return }
}
else { Write-Warning ("Specified file {0} already exists, appending data to it..." -f $Filename)
}
#Check if the ImportExcel module is installed. Install it if not
if (-not (Get-Module -ListAvailable -Name ImportExcel)) { Write-Warning ("The ImportExcel module was not found on the system, installing now...") try { Install-Module -Name ImportExcel -SkipPublisherCheck -Force:$true -Confirm:$false -Scope CurrentUser -ErrorAction Stop Import-Module -Name ImportExcel -Scope Local -ErrorAction Stop Write-Host ("Successfully installed the ImportExcel module, continuing..") -ForegroundColor Green } catch { Write-Warning ("Could not install the ImportExcel module, exiting...") return }
}
else { try { Import-Module -Name ImportExcel -Scope Local -ErrorAction Stop Write-Host ("The ImportExcel module was found on the system, continuing...") -ForegroundColor Green } catch { Write-Warning ("Error importing the ImportExcel module, exiting...") return }
}
#List of PowerShell event logs to search in
$Eventlogs = @( 'Windows PowerShell' 'PowerShellCore/Operational' 'Microsoft-Windows-PowerShell/Admin' 'Microsoft-Windows-PowerShell/Operational' 'Microsoft-Windows-PowerShell-DesiredStateConfiguration-FileDownloadManager/Operational' 'Microsoft-Windows-WinRM/Operational'
)
#Set dateformat for the Excel tabs
$date = Get-Date -Format ddMMyyhhmm
#Loop through all computers specified in $ComputerName. If not specified, it will use your local computer
foreach ($computer in $ComputerName | Sort-Object) { #Check if the computer is reachable if (Test-Path -Path "\\$($computer)\c$" -ErrorAction SilentlyContinue) { Write-Host ("`nComputer {0} is accessible, continuing..." -f $computer) -ForegroundColor Green #Eventlogs if (-not $PSReadLineHistoryOnly) { #Search all EventLogs specified in the $eventlogs variable $TotalEventLogs = foreach ($Eventlog in $Eventlogs) { $events = Get-WinEvent -LogName $Eventlog -ComputerName $computer -ErrorAction SilentlyContinue if ($events.count -gt 0) { Write-Host ("- Exporting {0} events from the {1} EventLog" -f $events.count, $Eventlog) -ForegroundColor Green foreach ($event in $events) { [PSCustomObject]@{ ComputerName = $computer EventlogName = $Eventlog TimeCreated = $event.TimeCreated EventID = $event.Id Message = $event.Message } } } else { Write-Host ("- No events found in the {0} Eventlog" -f $Eventlog) -ForegroundColor Gray } } #Create an Excel file and add an Eventlog tab containing the events for the computer if ($TotalEventLogs.count -gt 0) { try { $TotalEventLogs | Export-Excel -Path $Filename -WorksheetName "PowerShell_EventLog_$($date)" -AutoFilter -AutoSize -Append Write-Host ("Exported Eventlog data to {0}" -f $Filename) -ForegroundColor Green } catch { Write-Warning ("Error exporting Eventlog data to {0} (File in use?), exiting..." -f $Filename) return } } } #PSreadLineHistory if (-not $EventlogOnly) { #Search for all PSReadLine history files in all Windows User profiles on the system if (-not $PowerShellEventlogOnly) { Write-Host ("Checking for Users/Documents and Settings folder on {0}" -f $computer) -ForegroundColor Green try { if (Test-Path "\\$($computer)\c$\Users") { $UsersFolder = "\\$($computer)\c$\Users" } else { $UsersFolder = "\\$($computer)\c$\Documents and Settings" } } catch { Write-Warning ("Error finding Users/Documents and Settings folder on {0}. Exiting..." -f $computer) return } Write-Host ("Scanning for PSReadLine History files in {0}" -f $UsersFolder) -ForegroundColor Green $HistoryFiles = foreach ($UserProfileFolder in Get-ChildItem -Path $UsersFolder -Directory) { $list = Get-ChildItem -Path "$($UserProfileFolder.FullName)\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\*.txt" -ErrorAction SilentlyContinue if ($list.count -gt 0) { Write-Host ("- {0} PSReadLine history file(s) found in {1}" -f $list.count, $UserProfileFolder.FullName) -ForegroundColor Green foreach ($file in $list) { [PSCustomObject]@{ HistoryFileName = $file.FullName } } } else { Write-Host ("- No PSReadLine history file(s) found in {0}" -f $UserProfileFolder.FullName) -ForegroundColor Gray } } #Get the contents of the found PSReadLine history files on the system $TotalHistoryLogs = foreach ($file in $HistoryFiles) { $HistoryData = Get-Content -Path $file.HistoryFileName -ErrorAction SilentlyContinue if ($HistoryData.count -gt 0) { Write-Host ("- Exporting {0} PSReadLine History events from the {1} file" -f $HistoryData.count, $file.HistoryFileName) -ForegroundColor Green foreach ($line in $HistoryData) { if ($line.Length -gt 0) { [PSCustomObject]@{ ComputerName = $computer FileName = $File.HistoryFileName Command = $line } } } } else { Write-Warning ("No PSReadLine history found in the {0} file" -f $Log) } } #Create an Excel file and add the PSReadLineHistory tab containing PowerShell history if ($TotalHistoryLogs.count -gt 0) { try { $TotalHistoryLogs | Export-Excel -Path $Filename -WorksheetName "PSReadLine_History_$($date)" -AutoFilter -AutoSize -Append Write-Host ("Exported PSReadLine history to {0}" -f $Filename) -ForegroundColor Green } catch { Write-Warning ("Error exporting PSReadLine history data to {0} (File in use?), exiting..." -f $Filename) return } } } } } else { Write-Warning ("Specified computer {0} is not accessible, check permissions and network settings. Skipping..." -f $computer) continue }
}

Download the script(s) from GitHub here

:/>  Как отключить Защитник Windows 10 навсегда: 6 эффективных способов

You can use simple text log files to control running and track all of the activities in your PowerShell scripts. This is useful when debugging errors or auditing script actions. In this article, we’ll show some ways to use logging in PowerShell scripts by writing output to text log files.

In all cases, the commands add a new line to a TXT file with the text you have specified.

If you want to overwrite the log file contents each time, use the Set-Content cmdlet.

Log PowerShell output to a text file

The main drawback of this method is that you cannot figure out when an entry was written to the log (an event occurred). You can add the current timestamp to the log file. It will help to identify the time when the script was run and a specific event occurred.

To make it more convenient, you can create a separate function in your PowerShell script that will write the data it receives to a log file and add the timestamp for each event.

You can create a function as shown below:

Then call the WriteLog function if you want to log something.

Now you can see the time of each entry in the log file.

powershell create log file with timestamp

You can replace Write-Host calls with LogWrite ones in your script.

PowerShell has a built-in transcript feature to save all commands and outputs shown in the PS console to a text log file.

To log your current PowerShell session, the Start-Transcript cmdlet is used.

Transcript started, output file is C:\Users\user\Documents\PowerShell_transcript.DESKTOP-P2FHTKQ.+IzDgZiN.20210908163729.txt

Start-Transcript -Append C:\PS\Logs\PSScriptLog.txt

The –Append option indicates that new sessions will be logged to the end of the file (without overwriting it).

Run some PowerShell commands that output the results to the console. For example, let’s display a list of running processes, services, and the AD replication status:

Stop logging for the current PowerShell session:

Then open the transcript log file.

PowerShell_transcript log file - record a session to a text file

As you can see, the log shows the entire history of the PowerShell commands that were run in the console and all the output.

All errors and warnings are also logged, and it is extremely convenient when debugging complex PowerShell scripts.

You can use Start-Transcript and Stop-Transcript cmdlets in your PowerShell scripts to natively log all actions and outputs.

I have a PowerShell Script that is importing a module and I am calling this module. However, this module has lots of useful output that I am not capturing and I would like to write it to a file. What is the best way to do this?

Write-Host "Loading modules.." -ForegroundColor Cyan
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\cleanupFile.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Get-FullFilePath.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Initialize-DiskPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Initialize-VHDPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\MountVHDandRunBlock.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\New-TemporaryDirectory.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Run-Executable.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Set-DiskPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Set-VHDPartition.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\Wim2VhdClass.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\private\cleanupFile.ps1
Import-Module C:\Users\Dev1\Downloads\WimConvertTest\WindowsImageTools\Public\Convert-Wim2VHD.ps1
try
{ Write-Host "========================== Creating VHDX ================================== " Convert-WIM2VHD -Path ".\os_1.vhdx" -SourcePath ".\os_1.wim" -Size 16GB -force -DiskLayout UEFI # How to send output from imported module to a "_Convert-WIM2VHD.log" # Example: powershell -Command "Start-Process 'powershell.exe' -Wait -ArgumentList '-ExecutionPolicy Bypass -Command \"...?
}
catch
{ Write-Host $Error[0] Write-Host $Error[0].Exception.GetType().FullName

What is the best way to get all the output from Convert-WIM2VHD to _Convert-WIM2VHD.log?

asked Nov 3, 2023 at 20:44

Kris's user avatar

How to send output from imported module to a “_Convert-WIM2VHD.log”

From inside PowerShell:

  • To capture output only in a file, use a redirection: to capture output from all PowerShell output streams, use *>

    Convert-WIM2VHD ... *> _Convert-WIM2VHD.log
  • Convert-WIM2VHD ... *>&1 | Tee-Object -FilePath _Convert-WIM2VHD.log
  • To also capture output from an entire script or session, use Start-Transcript and Stop-Transcript:

    Start-Transcript _Convert-WIM2VHD.log
    # ... commands or script calls whose output to capture
    # You can also build these calls into your script.
    Stop-Transcript
  • In a Start-Process call, the only way to capture any output is in files, namely via -RedirectStandardOutput and -RedirectStandardError, but note:


From outside PowerShell, when calling the the PowerShell CLI (powershell.exe for Windows PowerShell, pwsh for PowerShell (Core) 7+):

  • Because the PowerShell CLI sends all its output streams to stdout – including the error stream – a simple > redirection from a calling shell (e.g. cmd.exe, Bash) is sufficient; e.g.:

    powershell -NoProfile -ExecutionPolicy Bypass -Command '...' > _Convert-WIM2VHD.log
    • However, if you request a (separate) stderr redirection (2>), PowerShell’s error stream is sent to stderr (but none of the other non-sucesss streams).
  • Note: While this send-everything-to-stdout-by-default behavior happens to be convenient for this use case, it is generally problematic: arguably, all streams other than the success output stream should be sent to stderr – see GitHub issue #7989.


Character-encoding considerations, i.e. what character encoding is used in the output files:

  • From inside PowerShell:

    • >, as an effective alias of Out-File, uses the latter’s default encoding:

      • UTF-16LE (“Unicode”) in Windows PowerShell.
      • BOM-less UTF-8 in PowerShell (Core) 7+ (BOM-less UTF-8 is the consistent default there).
      • To choose a different encoding, use Out-File explicitly, with its -Encoding parameter (but then you cannot combine it with Tee-Object).
    • Tee-Object with -FilePath uses:

      • UTF-16LE (“Unicode”), invariably in Windows PowerShell
      • BOM-less UTF-8 in PowerShell (Core) 7+ by default; in v7.3+, the -Encoding parameter can be used to change that.
    • Start-Object with -RedirectStandardOutput and -RedirectStandardOutput:

      • Invariably uses the console window’s output code page (see below).
  • From outside PowerShell:

    • On Windows, the PowerShell CLI (in both editions) uses the console window’s output code page (as reported by chcp), which defaults to the system’s active legacy OEM code page, such as 437 on US-English systems.

      • This means that for full Unicode support you’ll have to switch the calling console window to UTF-8 first (chcp 65001); since Windows 10 it is also possible to configure a system to use UTF-8 system-wide, in which case both the OEM and the ANSI code page are set to 65001 (UTF-8). However, this has far-reaching consequences in that it can change the behavior of existing console applications and PowerShell scripts; see this answer for details as well as a PowerShell-only alternative.
    • Un Unix-like systems, the PowerShell CLI (pwsh, the PowerShell (Core) CLI) invariably outputs (BOM-less) UTF-8-encoded text.

:/>  Находим IP адрес принтера в Windows 10 за 5 минут | Сеть без проблем

answered Nov 6, 2023 at 16:59

mklement0's user avatar

67 gold badges673 silver badges862 bronze badges

Requirement: Generate a log file and add messages to it to track the execution of a PowerShell script.

When creating PowerShell scripts, it’s often helpful to generate log files to track the progress of the script and diagnose any issues that may arise. Sometimes, we may need to log messages to help us troubleshoot where and what went wrong during the script’s execution or for tracking purposes. This post will discuss how to create a log file in a PowerShell script.

The simplest way to generate log files by adding content to a text file is:

Function Log-Message([String]$Message)
{ Add-Content -Path C:\Temp\Log.txt $Message
}
Log-Message "Beginning exeuction of the script:"
Log-Message "Exeucting of the script..."
Log-Message "Completed exeuction of the script!"

How about adding a timestamp to the log file along with the log message?

function Write-Log { param( [string]$Message ) $timestamp = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") "$timestamp - $Message" | Out-File -FilePath C:\logs\script.log -Append
}

Case 1: Create a Log File from Time Stamp in the Current Directory

Keeping track of events, errors, and other important information is crucial for effective monitoring, troubleshooting, and auditing in PowerShell scripts. Let’s create a log file based on the current timestamp and log messages prepending time stamps to it.

Function Log-Message()
{ param ( [Parameter(Mandatory=$true)] [string] $Message ) Try { #Get the current date $LogDate = (Get-Date).tostring("yyyyMMdd") #Get the Location of the script If ($psise) { $CurrentDir = Split-Path $psise.CurrentFile.FullPath } Else { $CurrentDir = $Global:PSScriptRoot } #Frame Log File with Current Directory and date $LogFile = $CurrentDir+ "\" + $LogDate + ".txt" #Add Content to the Log File $TimeStamp = (Get-Date).toString("dd/MM/yyyy HH:mm:ss:fff tt") $Line = "$TimeStamp - $Message" Add-content -Path $Logfile -Value $Line Write-host "Message: '$Message' Has been Logged to File: $LogFile" } Catch { Write-host -f Red "Error:" $_.Exception.Message }
}
#Call the function to Log messages
Log-Message "Script Execution Started"
Log-Message "Script is being Executed"
Log-Message "Script Execution Completed"

and the result of PowerShell logging:

powershell generate log file

Case 2: Create a Log File in Given Location

Logging is an essential practice in PowerShell scripting, as it allows you to capture valuable information about the execution of your scripts, including success messages, warnings, errors, and other relevant details. This time, let’s create a log file for the given location.

Function Log-Message()
{ param ( [Parameter(Mandatory=$true)] [string] $Message, [Parameter(Mandatory=$true)] [string] $LogFilePath ) Try { #Add Content to the Log File Add-content -Path $LogFilePath -Value $Message Write-host "Message: '$Message' Has been Logged to File: $LogFilePath" -f Yellow } Catch { Write-host -f Red "Error:" $_.Exception.Message }
}
#Set Location for Log File
$LogFilePath = "C:\Temp\AppLog.txt"
#Ensure the Parent Folder for Log File
$FolderPath= Split-Path $LogFilePath
If(!(Test-Path -path $FolderPath))
{ New-Item -ItemType directory -Path $FolderPath | Out-Null
}
#Delete the Log file if exists
If(Test-Path $LogFilePath)
{ Remove-Item $LogFilePath
}
#Log Start Time of the Script
$StartTime = (Get-Date)
Log-Message "Script Started at: $(Get-date -format 'dd/MM/yyy hh:mm:ss tt')" -LogFilePath $LogFilePath
#Pause for 2 Seconds
Sleep 2
#Log End Time
$EndTime = (Get-Date)
Log-Message "Script Ended at: $(Get-date -format 'dd/MM/yyy hh:mm:ss tt')" -LogFilePath $LogFilePath
#Get Elapsed Time
$ElapsedTime = ($EndTime - $StartTime).Seconds
Log-Message "Script Execution Time: $ElapsedTime Seconds" -LogFilePath $LogFilePath

Here is another simplified approach: By default, PowerShell commands’ output is sent to the console. Using the Out-File cmdlet, you can redirect it to a text file.

#Function to Add Content to Log File
Function Write-Log { [CmdletBinding()] Param ([Parameter(Mandatory=$true)][string]$LogFilePath, [Parameter(Mandatory=$true)][string]$Message) Process{ #Add Message to Log File with timestamp "$([datetime]::Now) : $Message" | Out-File -FilePath $LogFilePath -append; #Write the log message to the screen Write-host $([datetime]::Now) $Message }
}
#Usage
Write-Log "C:\Temp\Log.txt" "Script execution started..."
Sleep(5)
Write-Log "C:\Temp\Log.txt" "Script is being executed..."
Sleep(5)
Write-Log "C:\Temp\Log.txt" "Script execution Completed..."

The “-Append” switch is used to append output to an existing file. You can also use the redirect operator > allows you to write and >> to append. Another form of logging messages to text files:

#Set the Log File Location
$LogFile = "C:\temp\$($env:computername)_AppLog.log"
#Function to Create a Log File
Function Write-Log { param( [Parameter(Mandatory = $true)][string] $message, [Parameter(Mandatory = $false)] [ValidateSet("INFO","WARNING","ERROR")] [string] $level = "INFO" ) $Timestamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss") Add-Content -Path $LogFile -Value "$timestamp [$level] - $message"
}
#Call the Function to Log a Message
Write-Log -level ERROR -message "String Operation failed"

Start-Transcript / Stop-Transcript in PowerShell

The Start-Transcript and Stop-Transcript cmdlets in PowerShell are used to record and save a transcript of your PowerShell session to a file. This is particularly useful for logging and documenting your PowerShell activities, troubleshooting, or creating a record of your commands and their output.

Here’s how you can use these cmdlets:

Start-Transcript:

Start-Transcript -Path "C:\Transcripts\Session.log"

This command will start recording your PowerShell session and save the transcript to the specified file.

Stop-Transcript:

To stop recording your PowerShell session, use the Stop-Transcript cmdlet. Example:

This command will stop the recording and save the transcript file.

Here’s an example that demonstrates the usage of Start-Transcript and Stop-Transcript:

# Start the transcript
Start-Transcript -Path "C:\Transcripts\Session.log" -Verbose
# Perform some PowerShell commands
Get-Date
Get-Service| Where-Object { $_.Status -eq "Running" }
Write-Host "This is a sample message."
# Stop the transcript
Stop-Transcript

In this example:

  1. The Start-Transcript cmdlet is used to start recording the PowerShell session and save the transcript to the file “C:\Transcripts\Session.log”.
  2. Various PowerShell commands are executed, such as Get-Date, Get-Service, and Write-Host.
  3. The Stop-Transcript cmdlet is used to stop the recording and save the transcript file.

After running these commands, you will find a file named “Session.log” in the specified location (“C:\Transcripts\”). This file will contain a record of the commands executed and their output during the PowerShell session.

Best practices for writing to log files in PowerShell

Here are some best practices for writing to log files in PowerShell, include:

  • Use meaningful and descriptive log messages.
  • Include relevant information such as timestamps, script names, and error details.
  • Use appropriate log levels (e.g., informational, warning, error) to categorize log entries.
  • Implement proper error handling and logging of exceptions.
  • Regularly rotate or archive log files to prevent them from growing too large.
  • Secure access to log files to protect sensitive information.
:/>  tftp(1) — tftp-hpa — Debian testing — Debian Manpages

Conclusion

Creating a log file in a PowerShell script can be very useful for tracking the progress of the script, and for debugging any issues that may arise. Using the built-in “Out-File” or “Add-Content” cmdlets makes it easy to create a log file and write output to it. The log file can be configured to append new information to the end of the file each time the script is run. It’s essential to test the log file to ensure it works as expected and contains the information you need. Overall, using log files can greatly improve the maintainability and troubleshooting of your PowerShell scripts.

Refer to this related post on sending PowerShell Output: How to send PowerShell cmdlet output to a File using the Out-File cmdlet?

What is the purpose of logging in PowerShell scripts?

Logging in PowerShell scripts helps track the progress of the script, diagnose issues, and troubleshoot errors that may occur during execution.

How can I create a log file in a PowerShell script?

How can I handle errors and log them in PowerShell scripts?

How can I enable PowerShell logging for all commands executed?

How do I log messages from within a script?

You can use the Add-Content cmdlet to write custom messages to a log file from within a script:
$logfile = "C:\Logs\scriptlog.txt"
Add-Content -Path $logfile -Value "Script started at $(Get-Date)"
#Your script code here
Add-Content -Path $logfile -Value "Script ended at $(Get-Date)"

How can I include timestamps in my PowerShell log file entries?

How can I create a new log file for each PowerShell session?

How do I clear a log file before writing new data?

To clear a log file before writing new data, you can use the Clear-Content cmdlet: Clear-Content -Path "C:\Logs\mylog.txt"

How can I append messages to an existing log file?

What is the difference between Out-File and Add-Content cmdlets?

The Out-File cmdlet is used to write output to a file, replacing its content if it already exists (Use the Append switch to add content to the end). The Add-Content cmdlet, on the other hand, appends the output to the end of the file, preserving its existing content.

Why Logging Matters in PowerShell

Logging is the process of recording events and data to a file or other output streams. In PowerShell, logging is vital for debugging purposes, monitoring script execution, and ensuring that you have a record of what actions were taken and when.

There are various ways you can create a log file in PowerShell.

Method 1: Start-Transcript and Stop-Transcript

PowerShell offers a built-in cmdlet called Start-Transcript to log a PowerShell session. This cmdlet starts recording all interactions with the console and saves them to a specified file. To stop recording, use the Stop-Transcript cmdlet.

Here is an example.

Start-Transcript -Path "C:\Logs\PowerShell_Log.txt"
# Your script commands here
Stop-Transcript

Once you execute the above PowerShell script, it will create a log file and write the particular text in the above specified path.

Method 2: Out-File Cmdlet

The Out-File cmdlet in PowerShell is another way to write output directly to a log file. You can use it to append or overwrite data in a log file.

Here is a complete example:

"Information: Logging started." | Out-File -FilePath "C:\Logs\ScriptLog.txt" -Append
# Your script commands here
"Information: Logging completed." | Out-File -FilePath "C:\Logs\ScriptLog.txt" -Append

This method allows you to selectively log information to your file, providing more control over what gets logged.

Method 3: Add-Content Cmdlet

Add-Content is a cmdlet in PowerShell that lets you append content to a log file without overwriting the existing content. This is useful for adding log entries as your script runs.

Here is a complete example.

Add-Content -Path "C:\Logs\ScriptLog.txt" -Value "Script has started at $(Get-Date)"
# Your script commands here
Add-Content -Path "C:\Logs\ScriptLog.txt" -Value "Script has finished at $(Get-Date)"

This cmdlet is similar to Out-File -Append, but it’s specifically designed for adding text to files, making it ideal for logging purposes.

Method 4: Custom Logging Function

You can create a custom function to handle logging in PowerShell. This function can include parameters for the log message, log file path, and other options like timestamping.

Here’s a simple function that writes log entries to a specified file:

function Write-Log { Param ( [string]$LogString, [string]$LogFile ) Add-Content -Path $LogFile -Value $LogString
}
# Usage
$LogFile = "C:\MyFolder\script.log"
Write-Log "This is a log entry" -LogFile $LogFile

This function uses the Add-Content cmdlet to append the log string to the specified log file.

You can see the output in the screenshot below after I executed the PowerShell script using VS code.

Create Log File In PowerShell
function Write-Log { param ( [string]$LogPath, [string]$Message ) $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $logEntry = "$timestamp - $Message" Add-Content -Path $LogPath -Value $logEntry
}
$LogPath = "C:\MyFolder\CustomLog.txt"
Write-Log -LogPath $LogPath -Message "Script started"
# Your script commands here
Write-Log -LogPath $LogPath -Message "Script ended"

This will prepend the current date and time to each log entry, formatted as YYYY-MM-DD HH:MM:SS.

Method 5: PSFramework

Here is a complete example.

Import-Module PSFramework
Set-PSFLoggingProvider -Name logfile -Enabled $true -LogPath "C:\Logs\PSFrameworkLog.txt"
Write-PSFMessage "Script started" -Level Important
# Your script commands here
Write-PSFMessage "Script ended" -Level Important

This method requires the installation of the PSFramework module but offers a professional logging setup that can be essential for enterprise-level scripts.

Best Practices for PowerShell Logging

  1. Consistency: Use a consistent log file naming convention to make it easier to locate and analyze logs.
  2. Timestamps: Include timestamps in your logs to provide context for when events occurred.
  3. Log Levels: Implement log levels (e.g., DEBUG, INFO, WARN, ERROR) to categorize the importance of log messages.
  4. Error Handling: Include logging within try/catch blocks to capture exceptions and errors.
  5. Log Rotation: Implement log rotation to prevent log files from becoming too large and unmanageable.
  6. Sensitive Data: Be cautious about logging sensitive information. Always sanitize logs if they may contain passwords, PII, or other sensitive data.

Conclusion

I hope that now, from this tutorial, you can create and write a log file in PowerShell using the above-mentioned methods.

You may also like: