3

The function

 function findf {
     Write-Host "Find files that match: $args"
     gci -r | Where-Object { $_.name -match ".*$args.*" }
 }

doesn't seem to work. For example,

 findf .exe

-- Prints a bunch of stuff not limiting output to EXE files --

Any ideas what I'm doing wrong?

If I run the same command from the PowerShell command window the command works:

 gci -r | Where-Object { $_.name -match ".*.exe.*" }

This works and correctly shows me the files that match the *.EXE pattern

JNK
  • 63,321
  • 15
  • 122
  • 138
PatS
  • 138
  • 1
  • 2
  • 9

2 Answers2

5

$args is an object representing a collection of arguments.

You should either:

  • Reference $args[0] to get the string representing the first argument
  • Use param to define the input parameter like:

.

 function findf {
     param ([string]$SeachStr)
     Write-Host "Find files that match: $SeachStr"
     gci -r | Where-Object { $_.name -match ".*$SeachStr.*" }
 }

I always advocate using param when possible, since you can strongly type your variables like I did in the example. Otherwise it might be possible to do something confusing like pass an array as a parameter which can cause all sorts of hard-to-trace issues.

JNK
  • 63,321
  • 15
  • 122
  • 138
2

$args is not working because the filter is a script block, and runs in it's own scope. Every scope is initialized with it's own $args, so you cannot implicitly pass $args to a child scope. Since there's no provision for passing arguments to a filter script block, you have to do something like this:

  function findf {
       Write-Host "Find files that match: $args"
       $filter = $args[0]
       gci -r | Where-Object { $_.name -match ".*$filter.*" }
   }

Using a named parameter also works, because that will pass implicitly to the child scope.

mjolinor
  • 66,130
  • 7
  • 114
  • 135