top of page

Powershell Logging - Transcripts, they're GREEEEAT!

No breakfast cereals or comic tigers were harmed in the writing of this Blog post.


I have a love for Powershell, it makes my life as a SQL Server tech so much easier when I have to either treat my instances as a herd cattle, rather than separate bovine entities, or have them interact with other technologies as part of a larger task... ie... play with the other farm animals if you will.


Enough of the animal metaphors.


We write Powershell, we run powershell, we swear when our powershell does not do what we would like it to. To this end, we need to log the output somewhere, particularly when our scripts are not going to be run interactively so outputting to the screen becomes pointless.


You may have something like this, a little function to pass information to a file.

Function LogOutput([String]$Message, [string]$LogFile)
{    
	Add-Content -Path $LogFile $Message
}

LogOutput $(Get-date) C:\Temp\MyLogfile.txt
LogOutput "We need to know about this happening" C:\Temp\MyLogfile.txt
LogOutput "And this!" C:\Temp\MyLogfile.txt

We log, and we log hard.... but hang on, this has a few drawbacks.


What if we have non string types that we want to see, and or logged?

What if we have script that run interactively as well as to a file. The above gives us no output to screen.



Yes, you could use Write-Host, or Write-Verbose in your scripts as well as the above function, but this doesn't cover everything. It's also rather easy to bloat your scripts with logging what's going on, rather than just the code for what's going on.


Transcripts are our friend.


Transcripts in powershell have been around for a while now, and they can make life considerably easier.


To start a transcript log:

Start-Transcript -Path "Path to your log file" -IncludeInvocationHeader


The IncludeInvocationHeader switch just adds some useful info in the log file at the beginning.


And to Stop the transcript

Stop-Transcript


Its that easy.


Par Example

Here's Example with a little bit of error handling in. I like to use a Finally block to ensure my transcript is stopped last.


try {
	$Logpath="C:\temp\Logs"
	$LogName="TestingTranscripts"
	Start-Transcript -Path "$Logpath\$LogName-$(Get-Date -format dd-MM-yyyy-	hhmm).log" -IncludeInvocationHeader

	Write-Host $(Get-date)
	Write-Host "We need to know about this happening" 
	Write-Host "And this!" 
}

catch {$exception = $_.Exception.Message
   	write-host "Failed transcript Test: $exception" -ForegroundColor Red
}

finally {
	Stop-Transcript
}

And our transcript log file.


**********************

Windows PowerShell transcript start

Start time: 20240328173854

Username: LAPTOP3\roded

RunAs User: LAPTOP3\roded

Configuration Name:

Machine: LAPTOP3 (Microsoft Windows NT 10.0.22631.0)

Host Application: C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe

Process ID: 129684

PSVersion: 5.1.22621.2506

PSEdition: Desktop

PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.22621.2506

BuildVersion: 10.0.22621.2506

CLRVersion: 4.0.30319.42000

WSManStackVersion: 3.0

PSRemotingProtocolVersion: 2.3

SerializationVersion: 1.1.0.1

**********************

Transcript started, output file is C:\temp\Logs\TestingTranscripts-28-03-2024-0538.log

28/03/2024 17:38:54

We need to know about this happening

And this!

**********************

Windows PowerShell transcript end

End time: 20240328173854

**********************


Something other than writing Text...


Lets run a cmdlet to generate some output. In this case, get Get-service to grab the running services on my local client. Contrived example I know.

try {
	$Logpath="C:\temp\Logs"
	$LogName="TestingTranscripts"
	Start-Transcript -Path "$Logpath\$LogName-$(Get-Date -format dd-MM-yyyy-hhmm).log" -IncludeInvocationHeader

	Write-Host $(Get-date)
	Write-Host "We need to know about this happening" 
	Write-Host "And this!" 
    Write-Host "Better do some work... what services are running on my client?"
    get-service | Where {$_.Status -eq 'Running'} 
}

catch {
    	$exception = $_.Exception.Message
   	write-host "Failed transcript Test: $exception" -ForegroundColor Red
}

finally {
	Stop-Transcript
}



And this is in our transcript too... (truncated deliberately.)


**********************

Windows PowerShell transcript start

Start time: 20240328172444

Username: XXXXXX\rod

RunAs User: XXXXXX\rod

Configuration Name:

Machine: LAPTOP3 (Microsoft Windows NT 10.0.22631.0)

Host Application: C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe

Process ID: 129684

PSVersion: 5.1.22621.2506

PSEdition: Desktop

PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.22621.2506

BuildVersion: 10.0.22621.2506

CLRVersion: 4.0.30319.42000

WSManStackVersion: 3.0

PSRemotingProtocolVersion: 2.3

SerializationVersion: 1.1.0.1

**********************

Transcript started, output file is C:\temp\Logs\TestingTranscripts-28-03-2024-0524.log

28/03/2024 17:24:44

We need to know about this happening

And this!

Better do some work... what services are running on my client?

Status Name DisplayName

------ ---- -----------

Running ACCSvc ACC Service

Running AcerARTAIMMXDri... AAADSvc

Running AcerARTAIMMXSer... ARTAimmxService

Running AcerCCAgentSvis Acer Care Center

Running AcerDeviceEnabl... Acer Device Enabling Sevice V2



All from a couple of lines of wrapper code, it allows both logging to a file AND to the screen at the same time. Function output is capture, user input (should you have it), and errors.


Errors you say?

Yes, lets throw a dummy error in, by calling ImnotaFunction, which is a made up function I haven't written...just to produce an error. #Anarchy

Write-Host "Better do some work... what services are running on my client?"
    ImnotaFunction
    get-service | Where {$_.Status -eq 'Running'} | ft

Transcript file contents, minus the header.

**********************

Transcript started, output file is C:\temp\Logs\TestingTranscripts-28-03-2024-0552.log

28/03/2024 17:52:03

We need to know about this happening

And this!

Better do some work... what services are running on my client?

Failed transcript Test: The term 'ImnotaFunction' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

**********************

Windows PowerShell transcript end

End time: 20240328175203

**********************


Easy life.

Thanks for reading.


Rod.log


bottom of page