Why does Get-PathVariable return string array

Topics: Developer Forum, Project Management Forum, User Forum
Jun 29, 2010 at 5:09 PM

PoweShell 2.0.  I just hit a 'gotcha' with Get-PathVariable.  I have been using Add-PathVariable for a while to build my tools.  But when I recently switched versions of my tools I wanted to remove the old version and add the new one.

I hit this gotcha: the standard way of 'filtering' elements out of arrays is to pipe the array, use '?' operator to filter values, then get the new list with values removed:

@('hello', 'codeplex') | ? { @('hello', 'world') -notconatins $_ } # this will give you the elements in the first array that aren't in the second array

But because Get-PathVariables returns [System.String[]] PowerShell doesn't iterate it by default:

Get-PathVariable | ? { $_ -notmatch 'SDK' } #trying to remove paths that contain 'SDK' but fails ... pipeline value isn't [string], it is [string[]]

There is an easy fix:

Get-PathVariable |
  % { $_ } | # get [string[]], but send [string]
  ? { $_ -notmatch 'SDK' } # now filter on string

So, I'm wondering, is there a good reason to keep Get-PathVariable returning [string[]], or would it be best if this 'gotcha' was removed and return a pipeline-friendly array or list type?

Jun 29, 2010 at 6:51 PM

Hmm, internally the data structure is an array.  I suspect we are using WriteOuput(arr) instead of WriteOutput(arr, true) which would enumerate the array to the output. OTOT Set-PathVariable takes an input of [string[]].  Perhaps these were meant to match up (Get-PathVariable | ... | Set-PathVariable)? 

Jun 29, 2010 at 11:02 PM
Edited Jun 29, 2010 at 11:02 PM

And from the cmdlet's help, it does seem to be the case that the two were meant to work together e.g.:

Get-PathVariable Path -RemoveEmptyPaths -StripQuotes -Target Machine | Set-PathVariable Path -Target Machine
Jun 30, 2010 at 3:15 AM

You should be doing something more like this:

(Get-PathVariable) -notmatch "Program Files"


Set-PathVariable -Name Foo ((Get-PathVariable) -notmatch "Program Files")


Instead of this:

(Get-PathVariable).GetEnumerator() | ? { @("C:\Windo", "C:\Users") -contains $($_[0..7] -join "") }

Jul 21, 2010 at 4:02 AM

OK, I learned that -notmatch can operate on [string[]].  I don't think piping Get-PathVariable to Set-PathVariable is a compelling case, compared to making 'normal' pipeline scenarios work (like custom filtering in a where-object block).  I'm not a maintainer, but that's my opinion.  It's great to get an opinion from the maintainers.  This is a great project.  Great work!