Writing Logfile in a script

Hey guys,

I’m new to Powershell and just got the task to write a code which generates a Logfile. The Problem is there are a few things I need to consider. The Logfile should only show the commands which didn’t occur an error. And the Logfile needs to complete within writing the code, so it need to be one file and not a lot of files.

I already tried to do it with the commands “set-content”, “add-content”, but I didn’t reached my goal

I’m from Germany, hope you understand my English.
Thanks for upcoming answers :slight_smile:

I found this online some years back.

function LogWrite($string, $color)
{
$Currentdate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
if ($Color -eq $null) {$color = "Green"}
write-host "$Currentdate :: $string" -foregroundcolor $color
"$Currentdate :: $string" | out-file -Filepath FileSystem::$logfile -append
}

In my scripts I’ll use it like this

LogWrite "Opening SSH Session to $lweb"

Hmm, this isn’t working.
I want to save the Logs on my own disk.
Not on a host, but this was kind of useful anyway.
Do you know any options to make the Logs save automatically and extend the Logfiles instead of overwrite it?
I think this would solve my problem.

You would want to look at Start-Transcript cmdlet

Here’s the function I wrote and use for mine. It’s based on code from here.

Function LogWrite
{
   	Param (
		[Parameter(Mandatory=$true)][string]$LogFile,
   		[Parameter(Mandatory=$true)][string]$LogString,
		[Parameter(Mandatory=$true)][int]$Severity = 0
	)
	
	switch ($Severity)
	{
		0
		{
			$severityStr = "INFO"
		}
		1
		{
			$severityStr = "WARNING"
		}
		2
		{
			$severityStr = "ERROR"
		}
		3
		{
			$severityStr = "CRITICAL"
		}
	}
	
	$logEntry = "{0} - {1}: {2}" -f (Get-Date -Format u), $severityStr, $LogString

	Add-content $LogFile -value $logEntry 
}

To use it,

  • I pass the folder path I want to create the log file in.
  • Verify the path exists.
  • Name the log file. (If you want to append to an existing file, just make sure that use a filename that already exists)
  • Start writing logs
function Get-Foo {
	Param(
		[string]$LogfilePath = "C:\Scripts\Logs\Foobar"
	)

	Import-Module ModuleWithLogWrite
	
	# Create log file folder if it doesn't already exist
	if(!(Test-Path -Path $LogfilePath -PathType Container))
	{
		New-Item -ItemType Directory -Path $LogfilePath
	}

	# Set up variables
        $filenameDate = Get-Date -Format yyyyMMdd
	$LogFileName = "$($LogfilePath)`\$($filenameDate)_Foobar.log"

        # Write log entries		
	$logString = "Message to write in log with variables, etc."
	LogWrite -LogFile $LogFilename -LogString $logString -Severity 0

	$logString = "Error Message to write in log"
	LogWrite -LogFile $LogFilename -LogString $logString -Severity 2
}

Example of log file:

2019-10-08 04:15:02Z - INFO: ----- Processing started by user1 -----
2019-10-08 04:15:02Z - INFO: Using date in Modified AD property
2019-10-08 04:15:02Z - INFO: -- Processing Server1 --
2019-10-08 04:15:02Z - INFO: Date in Modified AD property: 07/23/2019 10:07:08

You should answer a few questions for us to better help you:

  1. Are you working with PowerShell for Windows, or PowerShell Core (for a non-Windows platform such as Red Hat Linux)? If you are not on Windows it may change the behavior of some command-lets.
  2. What version of PowerShell are you working with? As kvprasoon recommends, Start-Transcript may be the easiest solution for you (more usage information here) but if you are using an older version of PowerShell (e.g., version 5 or lower) it may not behave as expected.
  3. Are the log files you intend to write to .txt files, or are you using a different file format? and what encoding are you setting the target file to? The easiest way to store output from a PowerShell script is to use redirection, specifically '>>' allows you to append text to an existing file. However, there are some encoding decisions that you have to make. Generally, .txt files created in Windows will use ANSI encoding, but PowerShell's output will be in Unicode which will create differences in how the characters are interpreted. For cross-platform compatibility, Unicode is recommended over ANSI.
Once the system details are accounted for, you basically have two options for logging:
  1. Automatic - if Start-Transcript gives you all of the output that you need in your log files (and none of the output that you don't want) then you can set that for the scripts that need to produce logs. Setting it once at the beginning of the script should be enough. You will also need to add some code to establish a naming convention for new log files as they are created so that you can keep them organized, a routine to detect if a log file already exists and decide whether to append data to it or start a new log file (e.g. do you want a log file for each day, a log file that reaches a certain number of lines, or a new log file for each time the script is run?), and possibly some automation for deleting log files when they get too old, or when the directory containing logs reaches a certain size.
  2. Manual - if Start-Transcript doesn't handle your needs with enough specificity, you will need to add lines to the scripts that redirect the specific output that you want logged. That is, every single command whose output you want to log will need to have a line of code that redirects the output to the log file. Charles D's method basically makes this as easy as it can possibly be. It has some drawbacks. In the first place, if the scripts that produce the logs are particularly long then adding all of the log output statements will be tedious and difficult to do without mistakes. Secondly, it is not flexible - if the scripts that produce the logs are modified in the future, you will have to go back and add more lines for log output to them to account for the changes.
Also, based on your original description, you may need to distinguish between error and non-error output. It will probably be worth your time to learn about error handling in PowerShell. For instance, if you are implementing an automatic log solution that sends all output to the log, you may be able to use the "-ErrorAction" parameter to prevent commands from sending error output to the log.
  1. I work with PowerShell for Windows
  2. I actually don't know which version I'm using, "but start-transcript" seems to work well so far
  3. Yes, i wanted to write it in .txt files, u prefer other ways?I already solved the problem with the errorhandling, but I still got the problem , the logfile overwrites the older one instead of extending it.
Thanks for your help @everyone! :)

[quote quote=181845]

  1. I actually don't know which version I'm using, "but start-transcript" seems to work well so far
[/quote] You could have tried to figure that out by yourself. You are allowed to use search engine from time to time to do your own research.

Simply validate the automatic variable

$PSVersionTable

BTW: If you like … there are German Powershell forums as well. For example Microsoft Technet Forum Windows Powershell. Sometimes it’s easier to ask questions or to explain complex szenarios in your native language. :wink:

[quote quote=181845]

  1. I actually don't know which version I'm using, "but start-transcript" seems to work well so far
[/quote] You could have tried to figure that out by yourself. You are allowed to use a search engine from time to time to do your own research.

Simply validate the automatic variable

$PSVersionTable

BTW: If you like … there are German Powershell forums as well. For example Microsoft Technet Forum Windows Powershell. Sometimes it’s easier to ask questions or to explain complex szenarios in your native language. :wink:

… and I almost forgot - there are logging modules or frameworks already available in the PowershellGallery. No need to re-invent the wheel. :wink:

Hi,

You can use the function I created. Its on the GitHub:

Write-Log.ps1

Thanks,

Tushar