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.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
$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!
1 thought on “Friday Fun What’s My Variable”
Comments are closed.