PowerShell Transcripts

Do you test cmdlets in a PowerShell window? Do you just do something that you know should work and it doesn’t? Have you ever thrown the kitchen sink at a problem and all of a sudden your script is working? I bet you just closed the PowerShell window you were working in and lost all that work, because I’ve done it before.

Well, once bitten, twice isn’t gonna happen. Why? Because I’ve added the Start-Transcript cmdlet to my profile. It’s that simple, no muss, no fuss. There are a lot of different parameters that you can set with Start-Transcript such as:

  • [-OutputDirectory <String>]
  • [-Append]
  • [-Force]
  • [-NoClobber]
  • [-IncludeInvocationHeader]
  • [-WhatIf]
  • [-Confirm]
  • [[-LiteralPath] <String>]
  • [[-Path] <String>]

I dislike the naming convention that is default with PowerShell so I have added the Start-Transcript with the following bit of code

$a = (Get-Date).ToString(‘Mdy’)

Start-Transcript -Path C:\PowerShell\Transcript\$a”_transcript.txt” -append

What I’m doing is storing the current date in a variable as a string of just the month, day, and year which when you run $a will look something like “4619“, which is April 6th 2019. I then start the transcript with the -path parameter to my powershell\transcript folder with the name 4619_transcript.txt. I also use the -append  parameter in case I quit my powershell session during that day. Using append will just continue with the same transcript and avoid an overwrite of the file or an error.

Overall this is for me is easier to understand and find. I hope this helps you and gives you some idea’s for improvements to what I’ve shown you. Let me know in the comments if you have any enhancements.

PowerShell: Simple Profile

I’ve read a lot of different posts, articles and listened to any different Power Users tell me how to set up my PS profile. What I have seen is that a lot, if not most people want to trick up their profile adding all kinds of cool things that just increase the load time of the PowerShell console. You can import modules when you need them, you can update help when you need it. You get my point.

I believe simple is better, including just enough to make it work and that’s not much at all. Lets see what I have in my PS profile:

set-location c:\Powershell
$a = (Get-Host).PrivateData
$a.ErrorForegroundColor = “green”

Four lines, that’s it, but what do they do?

  1. set-location “Path” Just drops me in my PowerShell folder that all my scripts are in.
  2. $a = (Get-Host).PrivateData sets a variable so that I can change colors by accessing the ChildObject PrivateData to assign a different color to different things in the PS window.
  3. $a.ErrorForegroundColor = “green” uses the $a to add the ErrorForegroundColor so that I can assign it a value of  green. You can do more with assigning cmdlets to variables but that isn’t the lesson here.
  4. cls is because I like a a clean workspace while I work.

That’s my whole profile. Nothing spectacular, or even ingenious. I just want to get working and I hate the RED error messages. Green looks so much better.



PowerShell: Get Computer Software and Version

Something that I have found useful in getting a hard copy of is a computers installed software, vendor and version. Today I’m just going to work with the local computer. In another post I will talk about the ability to get all software installed on a group of computers. In PowerShell there are a few ways to do what I am going to show you. The one I prefer is Get-CimInstance. I use this over Get-WMIObject becasue it gets me more information and Get-WMIObject is actually the older way from PS 2.0. It has really been replaced with Get-CimInstance. If you go to Introduction to CIM Cmdlets (MSDN Blog) you will find this quote:

“Getting/Enumerating instance of a class is the most commonly performed operation. We wanted the new Get-CimInstance Cmdlet to have better performance and even better user experience as compared to the old Get-WmiObject cmdlet. To achieve these goals we made the following design decisions:”

So, how do I write the code?

Get-ciminstance Win32_Product


Gcim Win32_Product (gcim is the alias for Get-Ciminstance)

That just spits out the information in the ugly format below:


I like my data so I can read it properly and with all the data I really want. Lets add a Piped command:

| Format-Table name, version, vendor

This gives you the results below:


Okay, so that’s nice, but how about in a CSV file that I can print or look at later? Cool, lets do it:

Gcim Win32_Product | Select-Object name, version, vendor | Export-Csv C:\software1.csv

I know, your saying wait you changed the second line from Format-Table to Select-Object and you would be correct. Why did I change it, well format-Table is for output to the console, not for something you are piping to Export-CSV. You have to Select the Objects you want to send to the CSV file to get proper data. Go ahead and try to use the Format-Table once to see you get nothing you can use in the CSV file. The output you get when you use the Select-Object is below. That’s how I would like it, how about you?