myusrn
myusrn

Reputation: 1110

powershell use of where-object within script function not working

I'm trying to enable my powershell profile script with a function that will let me do literal and wildcard searches for the presence of a function in my current powershell terminal session.

Within my powershell profile script [ $env:userprofile\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 ] i've created the following function.

function Get-Fnc { 
    #Get-ChildItem function:\ | Where-Object { $_.Name -like "$args" }
    Get-ChildItem function:\$args
}

Using the commented out line Get-ChildItem function:\ | Where-Object { $_.Name -like "$args" } doesn't work even though i can use that on the command line, e.g. Get-ChildItem function:\ | Where-Object { $_.Name -like "get-*" } it works as expected. Using the uncommented line Get-ChildItem function:\$args works both in the profile script function and the command line, e.g. Get-ChildItem function:\get-*.

Searching on net and in stackoverflow i've not been able to find any details on gotchas around making use of output piping | to another cmdlet and/or use of the Where-Object cmdlet within functions to determine how to make it work. Any insights on how to make output piped to where-object work in a script function when the same thing is known to work on command line?

Update In addition to answer provided solutin was also able to use the following

function Get-Fnc { 
    $argsFncScope = $args # works because we make function scoped copy of args that flows down into Where-Object script block / stack frame
    Write-Host "function scoped args assigned variable argsFncScope = $argsFncScope and count = $($argsFncScope.Count) and type = $($argsFncScope.GetType().BaseType)"
    Get-ChildItem function:\ | Where-Object { $_.Name -like "$argsFncScope" } 
}

Debug Output

get-fnc *-env

[DBG]: PS C:\Users\myusrn\Documents\WindowsPowerShell> 
function scoped args assigned variable argsFncScope = *-env and count = 1 and type = array

[DBG]: PS C:\Users\myusrn\Documents\WindowsPowerShell>

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-Env

Upvotes: 1

Views: 982

Answers (1)

js2010
js2010

Reputation: 27428

Each scriptblock has its own $args automatic variable.

function Get-Fnc { 
  Get-ChildItem function:\ | where-object { write-host $args; 
    $_.name -like "$args" } }

get-fnc get-*




# lots of empty lines

The $args for where-object is a $null array.

function Get-Fnc {   
  Get-ChildItem function:\ | where-object { $global:myargs = $args;
    $_.name -like "$args" } }

get-fnc get-*

$myargs

$myargs.count

0

$myargs.gettype()

IsPublic IsSerial Name     BaseType
-------- -------- ----     --------
True     True     Object[] System.Array

You can however use the other version of where-object that doesn't use a scriptblock:

function Get-Fnc { 
  Get-ChildItem function:\ | where-object name -like $args }

get-fnc get-*

CommandType Name    Version Source
----------- ----    ------- ------
Function    Get-Fnc

See also: Why doesn't PowerShell Where-Object work when passing a variable?

I actually don't know a way to set $args within the where-object scriptblock, but here's another example of a scriptblock and $args. $args is actually an array.

& { $args[0]; $args[1] } hi there

hi
there

Upvotes: 1

Related Questions