Differentiate Between Automatic Variables and User Created Variables

I was delivering a PowerShell Work Shop the other week. One of the questions asked by a Mr T. T. was this:

"...How do you show variables created by you in a session?..."

So... Mr T. T. wanted to know how to distinguish between Automatic Variables and user-created variables. A jolly good question and one that's not as easy to answer as one might think!

Here's what I came up with:

powershell.exe -command {(Get-Variable).name > C:\Users\ianfarr\Desktop\automatic_variables.txt} -noprofile

Compare-Object -ReferenceObject (Get-Variable).name -DifferenceObject (Get-Content C:\Users\ianfarr\Desktop\automatic_variables.txt)


Line 1

Right, we create a temporary powershell.exe session and make sure it doesn't load a profile script. A profile script may add user-created variables to the session so we don't want those. Get-Variable is executed in the session to generate variable objects. The variables names are written to a text file for future parsing. The variables captured should only be Automatic variables.


Line 2

Right, we now use the Compare-Object cmdlet to compare the names of the variables in the current session with those from the temporary session. The output shows just user-created variables:


"But, wait, PoSh Chap!", I hear you cry.

"What's that, gentle reader?", I respond.

"Well, isn't LASTEXITCODE an Automatic Variable?"


And, you would be right, my erudite friends! This one is only generated when we call a 'windows-based program', e.g. ipconfig or ping. It's still an automatic variable though. How to remove it from the results:

powershell.exe -command {cmd /c; (Get-Variable).name > C:\Users\ianfarr\Desktop\automatic_variables.txt} -noprofile


Notice the addition of cmd /c in the script block executed by the -command parameter. This populates LASTEXITCODE for us. Which means it's matched by Compare-Object:


New outcome:


There you go Mr T.T. - it ain't pretty, but it works!