0

I have a problem getting a filter argument to Get-ChildItem in a function.

The following works fine and displays a whole list of files:

c:\temp\Get-ChildItem -Include *deleteme*.txt -Recurse

Now say I have the following script

#file starts here
#filename = GetLastFile.ps1

param([string] $filter)

$files = Get-ChildItem $filter

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;


$file.name  #returns filename
#File ends here

Now trying to run the script,

c:\temp.\GetLastFile.ps1 "-Include *deleteme*.txt -Recurse"

returns nothing.

Supplying a filter, *.*, works fine. It seems to be failing due to the -Include or -Exclude. Any ideas?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
El Toro Bauldo
  • 1,199
  • 3
  • 16
  • 26

3 Answers3

5

You're starting to get into an area where where Powershell 2.0 proxy functions can help. However, short of that, here's a simple way in PowerShell 2.0 to do this assuming all you need is -Include and -Recurse. Actually, I would recommend using -Filter instead it will do what you want and frankly it's quite a bit faster (4x on some of my tests) because -filter uses filesystem filtering provided by the OS whereas -include is processed by PowerShell.

param([string]$Filter, [switch]$Recurse)

$files = Get-ChildItem @PSBoundParameters

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;

$file.name #returns filename

The @ symbol is used to "splat" an array or hashtable across the parameters to a command. The $PSBoundParameters variable is an automatic variable new to PowerShell 2.0 that is defined in functions. It's a hashtable that contains all the bounded (named and positional) parameters e.g.:

PS> function foo($Name,$LName,[switch]$Recurse) { $PSBoundParameters }
PS> foo -Name Keith Hill -Recurse

Key                                                         Value
---                                                         -----
Name                                                        Keith
Recurse                                                     True
LName                                                       Hill

When you splat a hashtable like this against a command, PowerShell will map the key's (e.g. Recurse) value to the parameter named Recurse on the command.

Keith Hill
  • 194,368
  • 42
  • 353
  • 369
0

I believe what is happening is your $filter parameter is being treated as a single string argument to the Get-ChildItem command. As such, unless you have a directory named "-Include deleteme.txt -Recurse", the command will always return nothing.

As for fixing your problem, well, there are a bunch of ways you could approach it. Probably one of the more versatile ways is to switch program behavior if the the $filter argument is passed, and instead of passing the entire filter string just pass the "deleteme.txt" string.

Goyuix
  • 23,614
  • 14
  • 84
  • 128
0

You can use Invoke-Expression to execute a command stored in a variable. For example:

param([string] $filter)
$files = Invoke-Expression "Get-ChildItem $filter"

Write-Host $files

$file = $files | Select-Object -Last 1

$file.name
xXhRQ8sD2L7Z
  • 1,686
  • 1
  • 14
  • 16