Searching for a String in Environmental Variables in Powershell

I've updated the post through feedback in the comments:
Regex compare on strings for Get-Variable is Where-Object -Match.

So, the closest parallel to the following bash code:

set | grep "Users"

is the following Powershell:

Get-Variable | Where-Object { $_.Value -Match "Users" }

or shortened:

gv | ? {$_.Value -Match "Users"}

Original Post, with Updates
I'm kind of dumbfounded how this:

Get-Variable | Select-String -Pattern "Users"

returns nothing.

Yet,

Get-Variable > gv.txt
Get-Content gv.txt | Select-String -Pattern "Users"

returns:

$                              Users
HOME                           C:UsersAdministrator
PWD                            C:UsersAdministrator

My initial thought was that maybe redirect captures standard output and standard error and the pipe doesn't, but then, standard error should all come to the screen unfiltered if not captured by the pipe.

Added:
To add insult to injury, apparently

Get-Variable -Include "PS*"

or just

Get-Variable "PS*"

will do a wildcard search for variable names.

Updated, per the comment from @jburger

Get-Variable | Where-Object { $_.Value -ne $null } | Where-Object {$_.ToString().Contains("Users") }

or

gv | ? { $_.Value -ne $null } | ? {$_.Value.ToString().Contains(“Users”) }

Playing with the Where-Object syntax, I was able to reduce this to:

Get-Variable | Where-Object { $_.Value -ne $null -and $_.ToString().Contains("Users") }

or

gv | ? { $_.Value -ne $null  -and $_.Value.ToString().Contains(“Users”) }

Definitely, this does the trick. However, I'm disappointed that PowerShell doesn't automatically cast the object output using a ToString() operation.

2 Replies to “Searching for a String in Environmental Variables in Powershell”

  1. The thing here is that you have to remember that powershell is more of a programming language than a scripting lanugage. I.E Get-* will output typed objects, not string values. The upshot is that we can actually do some really complicated filtering... there is more to these objects than just their string data that you see output on the screen. 
    For instance... type:

    Get-Member -InputObject gv[0] 

    ..this will show all the members on the object type that gv outputs

    Note that the Value property is System.Object not System.String ... this is why select-string doesn't work.

    So...the 'downside' to powershell is you need to think like a .NET programmer.

    To answer you're q, to do what you want without hitting the filesystem, you need to drill into the string representation of the Value property. I did it using powershells where clause. (there are probably better ways - Im no PS guru). In long form.

    Get-Variable | Where-Object { $_.Value -ne $null } | Where-Object { $_.Value.ToString().Contains("Users") }

    Short form

    gv | ? { $_.Value -ne $null } | ? {$_.Value.ToString().Contains("Users") }

    Now I consider myself a PS newbie - so there is probably a less verbose, neater way to do this. But htis is it from first principles AFAIK.

    Hope that Helps

    Jim Burger

  2. To avoid disappointmens in future:
     
    1. Select-String is not grep. 😉 means: do not filter objects using it as you would filter command results in *nix shells.
    2. Contains is for array operations, not for searching the string.
    1,2,3,4 -contains 3
    3. Regex compare for strings is done with -match operator.
    That reduces all hard work to:
    gv | ? { $_.Value -match 'Users' }
    4. Simple pattern ('*', '?' and '[]') compare is done with -like operator.
    gv | ? { $_.Value -like '*[u-v]se?s*' }
     
    BTW: get-help where-object -examples would probably get you there before I wrote my comment. Help i PS is really greate resources on how to use it... 🙂 To see all articles about operators you can do get-help operators. about_operators contains basic info that could also save you few dissapointments. 🙂
    Good luck!

Comments are closed.