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
94079.72265625

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
ServiceController

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


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

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"}

Success!

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!

One thought on “Friday Fun What’s My Variable”

Comments are closed.