问题
In my script I have below function that returns a string as "*.csproj", "*.vbproj", "*.sln". Assuming I always pass a string such as "csproj, vbproj, sln" to $filter parameter:
Function Create-Filter($filter)
{
$str = $filter.Split(',') | ForEach-Object {"""*.$($_.Trim())"""}
$str = $str -join ', '
[string]$str
return
}
Later in my script I perform:
$filter = Create-Filter($filter)
$myFiles = Get-ChildItem $source -Include $filter -Recurse
But $myFiles is empty, Get-ChildItem is not returning anything. I know that the problem is in $filter parameter when passing to Get-ChildItem but I do not know how to solve this.
Anyway, from powershell console, If i do below It works:
PS > $filter = "*.csproj", "*.vbproj", "*.sln"
PS > Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $filter -Recurse
So what am I doing wrong?
My powershell version is as below image shows:
UPDATE (SOLUTION): Solution proposed by AdminOfThings works. In my case applying AdminOfThings was not working because I did a mistake in my code. I was assigning the value returned by Create-Filter function into the same variable as that I was passing as argument, like below:
$filter = Create-Filter ($filter)
Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $filter -Recurse
In order to make it work I have done below:
$formattedfilter = Create-Filter ($filter)
Get-ChildItem "D:\Path\To\My\Root\Folder" -Include $formattedfilter -Recurse
...that is, using a different variable to assign returned value by function instead of using the same as that I was passing as argument.
回答1:
In short, you need to remove the literal quotes (replace triple double quotes with single double quotes), the -Join
, and the string casting ([string]
) from your function. Basically, anything that stringifies your output, needs to be removed.
Function Create-Filter($filter)
{
$filter.Split(',') | ForEach-Object {"*.$($_.Trim())"}
return
}
The -Include
parameter accepts a single string or an array of strings. When you pass -Include "string1","string2"
, you are passing an array of strings into the command. In your filter, you are creating one string that includes literal quotes and commas. The subtlety here is including the commas within the quotes creates a string that contains quotes whereas quotes BETWEEN commas creates a comma separated list of strings. So effectively, the command is reading -Include '"string1","string2"'
, which will find nothing. Even though your function outputs text that looks identical to what you would type directly into the command, PowerShell will interpret those values differently.
You can see the behavior below where the output of your function is interpreted by PowerShell as a single string.
create-filter ("txt","csv")
"*.txt", "*.csv"
(create-filter ("txt","csv")).gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
The array syntax (comma separated list of string types) below outputs a different result.
"*.txt","*.csv"
*.txt
*.csv
("*.txt","*.csv").gettype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Executing the Code:
$str = "txt,csv"
create-filter $str
*.txt
*.csv
$filter = create-filter $str
Get-ChildItem . -Include $filter -Recurse
Directory: C:\temp\test1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/8/2019 10:47 AM 68 -44.csv
-a---- 6/8/2019 10:47 AM 101 -54.csv
-a---- 6/11/2019 8:50 AM 229 count.txt
-a---- 6/11/2019 8:58 AM 170 destination.txt
-a---- 6/11/2019 8:53 AM 302 f.txt
-a---- 6/12/2019 6:36 AM 294 hashash.txt
-a---- 6/6/2019 1:14 PM 4 jaf.csv
-a---- 6/6/2019 1:31 PM 0 job1.txt
回答2:
Hmm, I would use -filter which is faster.
ls -r D:\Path\To\My\Root\Folder -filter *.csproj,*.vbproj,*.sln
EDIT: Aww, that doesn't work. But this does. I'm not sure what you need the function for.
ls -r D:\Path\To\My\Root\Folder -include *.csproj,*.vbproj,*.sln
or
$source = 'D:\Path\To\My\Root\Folder'
$filter = '*.csproj','*.vbproj.*','*.sln' # or
$filter = echo *.csproj,*.vbproj,*.sln
ls -r $source -include $filter
来源:https://stackoverflow.com/questions/56621552/passing-powershell-get-childitem-filter-parameter-through-a-string-variable-is-n