Weekend Scripter: Playing with PowerShell's Get-Variable Cmdlet

Weekend Scripter: Playing with PowerShell's Get-Variable Cmdlet

  • Comments 4
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, spends some time playing around with the Get-Variable cmdlet.

Microsoft Scripting Guy, Ed Wilson, is here. This morning I am doing something a little different. Instead of drinking English Breakfast tea, I woke up feeling like I wanted Oolong tea instead. So I made a pot of Oolong tea with a spoonful of jasmine buds, a half spoon of peppermint leaves, three juniper berries, and half of a crushed cinnamon stick. It is quite invigorating, without being too overbearing.

Checking the value of a variable

So I am sitting on the lanai in my porch swing, and I just finished checking the email for the scripter@microsoft.com email alias. I received an email asking why I would bother using the Get-Variable cmdlet, when I can simply reference the variable to see the value? The reason is that there are many more things I need to do with variables than simply see the value contained inside the variable. The following example assigns a directory listing to the $dir variable:

$dir = dir -Directory | ? lastwritetime -gt $([datetime]'4/1/13')

To see the value that is contained in the $dir variable, I can type $dir. The command and the output are shown in the image that follows.

Image of command output

Use Get-Variable

I can also do this by using the Get-Variable cmdlet. When use Get-Variable, both the name and the value appear. To return only the value, I group the expression, and get the Value property as shown here:

(Get-Variable dir).value

This command and the associated output are shown in the image that follows.

Image of command output

Use the Variable provider

But there are other ways to retrieve values from Windows PowerShell variables. For example, I can use the Variable provider and access the value from the Windows PowerShell Variable drive. I do this by using the command shown here:

$variable:dir

The command and the output are shown in the following image.

Image of command output

Because the Variable provider creates a PSDrive named Variable, I can use the standard Windows PowerShell cmdlets to work with the variable. For example, I can use Get-Item as shown in this example:

Get-Item -Path Variable:\dir

But if I only want the value of the Dir variable, I need to select the Value property:

(Get-Item -Path Variable:\dir).value

The commands and associated output are shown in the image that follows.

Image of command output

One of the cooler things to do is to use the Get-Content cmdlet to obtain the contents of the variable. When using this technique, only the first value from the array returns. This is shown here:

PS C:\> Get-Content variable:\dir

 

    Directory: C:\

 

Mode                LastWriteTime     Length Name

----                -------------     ------ ----

d----         4/23/2013  12:41 PM            fso

Examining the type of a variable

I am sure you know that there are different types of variables in Windows PowerShell. If I use the Get-Variable cmdlet, pipe the results to the Format-List cmdlet, and choose all of the properties, I obtain some pretty interesting information. This is shown here:

PS C:\> Get-Variable dir | fl *

 

PSPath        : Microsoft.PowerShell.Core\Variable::dir

PSDrive       : Variable

PSProvider    : Microsoft.PowerShell.Core\Variable

PSIsContainer : False

Name          : dir

Description   :

Value         : {fso, fsox, Program Files, Program Files (x86)...}

Visibility    : Public

Module        :

ModuleName    :

Options       : None

Attributes    : {}

If I take the $dir variable and pipe it to the Get-Member cmdlet, it returns information about the objects that are contained in the variable, and not about the variable itself.

$dir | get-member

The command and output from the command are shown in the image that follows.

Image of command output

To find information about the variable itself, I use Get-Variable to return the variable, and then I pipe the result to the Get-Member cmdlet:

Get-Variable dir | Get-Member

The command and output from the command are shown here.

Image of command output

Finding different types of variables

Unfortunately, this does not return anything about the type of Windows PowerShell variable. So what is the easy way to find the variable type? Use the Get-Variable cmdlet and pipe the returned objects to the Get-Member cmdlet. Next, I select only the TypeName property, and I use the Unique switch to ensure only unique instances return. Here is the command and the results:

PS C:\> Get-Variable | Get-Member | select typename -Unique

 

TypeName

--------

System.Management.Automation.PSVariable

System.Management.Automation.QuestionMarkVariable

System.Management.Automation.LocalVariable

System.Management.Automation.SessionStateCapacityVariable

System.Management.Automation.NullVariable

When I know the different types of variables, I can use Windows PowerShell to list a particular type of variable. To do this, I pipe the results of Get-Variable to the Where-Object. In my Where-Object filter, I use the PSObject property so I can reference the underlying type. This technique is shown here where I find all variables of the type LocalVariable.

Get-Variable | where {$_.psobject.typenames -match 'local'}

The command and output from the command are shown here.

Image of command output

Join me tomorrow for the exciting conclusion to the Windows PowerShell and Security series by Yuri Diogenes and Tom Schinder. To catch up, read the two previous posts in this series.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • From following your thoughts/investigation I ended up with this script to show me the different TypeName-groups. I just wanted to share my process:

    --------------------------------------------------------------------------------------------------

    $global:1 = 1

    $script:2 = 2

    $local:3 = 3

    cls

    Get-Variable |

       ForEach-Object {

           [pscustomobject]@{

               Name = $_.name

               Typename = $_.psobject.typenames[0]

           }

       } | Group-Object TypeName |

           ForEach-Object{

               write-host $($_.name -replace 'System.Management.Automation.') -ForegroundColor Blue -BackgroundColor white

               $_.group.name

               ""

           }

    --------------------------------------------------------------------------------------------------

  • @Anders

    Are you trying to do this:

    Get-Variable |

        Select Name, @{N='Type';E={$_.GetType().Name}} |

        Format-Table -GroupBy Type -Property name -HideTableHeaders

  • @Anders

    If you prefer color than this variation is easy:

    Get-Variable |

        Select Name, @{N='Type';E={$_.GetType().Name}} |

        Group-Object type |

        ForEach-Object{

           Write-Host "`nTypeName:$($_.Name)" -ForegroundColor black -BackgroundColor white

           $_.Group | %{Write-Host "`tVariable: $_" -ForegroundColor green -BackgroundColor white}

        }

  • I am after a script that gives me directory names, file names , last modified and create date, is this simple to do? Is it like the old .bat files where you can output to a txt file?