Friday Fun What’s My Variable

I use scriptblocks quite a bit in my PowerShell work, often saved as variables. These are handy for commands you want to run again, but don’t necessarily need to turn into permanent functions.

$freec={(get-wmiobject win32_logicaldisk -filter "deviceid='c:'" -property Freespace).FreeSpace/1mb}

Now in PowerShell I can invoke the scriptblock.

PS S:\> &$freec

Ok then. I have a number of these defined. I decided I wanted an easy way to identify them when I run Get-Variable. For example, if I remembered all the variable names I could just do this:

PS S:\> get-variable freec,dirt

Name Value
---- -----
freec (gwmi win32_logicaldisk -filter "deviceid='c:...
dirt Param([string]$Path=$env:temp) Get-ChildItem ...

But needless to say that’s asking too much. When I first looked at this problem I went down the path of trying to parse values I saw with Get-Variable to identify potential script blocks. Then I realized this was a rookie mistake. PowerShell is all about the objects. Now a variable is also an object with a value property. This value could be a string, and integer or a pscredential. So my task then was to identify each value type.

Every object in PowerShell has a built in method called GetType().

PS S:\> $s=get-service spooler
PS S:\> $s.GetType()

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False ServiceController System.ComponentM...

This is actually another object with a Name property.

PS S:\> $s.GetType().name

Aha! Let’s look at this with my variable.

PS S:\> (get-variable freec).value.GetType().Name

This is a one-line shortcut that gets the Value property of the Freec variable and then runs the GetType() method followed by retrieving just the Name property. This is promising. Here’s one way I can use this:

get-variable | Where {$_.value.GetType().Name -eq "ScriptBlock"}

As you can see there is still an issue with variables with no values.

I’ll just add another condition to my Where expression.

get-variable | Where {$_.value -AND $_.value.GetType().Name -eq "ScriptBlock"}


These are in fact all of the scriptblocks in my current session. But now I can take this a step further and look at my other variables and their type.

get-variable | select Name,@{Name="Type";Expression={$_.value.GetType().Name}}

Or I might try grouping.

get-variable | select Name,@{Name="Type";Expression={$_.value.GetType().Name}} | where {$_.type} | Group Type | Sort Count -Descending

I wanted to filter out empty values so I’m only keeping objects that have a defined type in my grouped output.

The bottom line is never forget about the object!

Get My Variables

As you might imagine I write a lot of PowerShell scripts and examples. Often my PowerShell Window is open for days at a time. One challenge I have always has is trying to remember what variables I have defined. If I knew the name I’d simply use Get-Variable. What I really want is a way to see just the variables that I’ve created. So I wrote a function to do just that. As an added benefit I can also export these variables and re-import them into another PowerShell session. Continue reading “Get My Variables”