1

I’m trying to write a PowerShell script that will allow a user to pass in a parameter with multiple types of files they want to process (i.e. *.txt and *.docx). When I run the Get-Childitem command with the -include option and manually type in the file types, it works file. But when I try to supply a variable for the -include mask, it does not work (returns nothing).

The problem only occurs when I’m using multiple file types $incFiles = “””.txt””`, “”.docx”””

If I use a single file type, it works just fine. $incFiles = “*.txt”

$incFiles = ""
$incFiles = """*.txt""`, ""*.docx"""
Write-Host "Manual Method:" '"*.txt", "*.docx"'
Write-Host "Calcul Method:" $incFiles

Write-Host "`nManual method works"
Get-ChildItem -path "C:\users\paul\Downloads" -Recurse -Include "*.txt", "*.docx"

Write-Host "This does not work"
Get-ChildItem -path "C:\users\paul\Downloads" -Recurse -Include $incFiles

Write-Host "End"

Results

Manual Method: "*.txt", "*.docx"
Calcul Method: "*.txt", "*.docx"

Manual method works

Directory: C:\users\paul\Downloads\Test2
Mode                LastWriteTime         Length Name                                                                                                                           
----                -------------         ------ ----                                                                                                                           
-a----        3/28/2020   9:54 AM              0 File1.txt                                                                                                                      
-a----        3/28/2020   9:55 AM              0 File2.docx                                                                                                                     

This does not work

End
Paul Wasserman
  • 137
  • 2
  • 13
  • 2
    `$incFiles = """*.txt""`, ""*.docx"""` --> `$incFiles = "*.txt", "*.docx"`. You are 'over-quoting' and even have a backtick in there. – Theo Mar 28 '20 at 14:54
  • 1
    To add to Theo’s comment, your “manual” method is creating an array of two separate string values ```*.txt``` and ```*.docx ```, but because of your “overquoting”, ```$incFiles``` is a single string value ```"*.txt", "*.docx"```. – mclayton Mar 28 '20 at 15:51

1 Answers1

0

Theo and mclayton have provided crucial pointer in comments on the question:

$incFiles = """*.txt""`, ""*.docx"""

creates a single string, whose verbatim content ends up as "*.txt", "*.docx".

As an aside: the backtick (`), PowerShell's escape character, isn't necessary, given that , has no special meaning inside "..." (an expandable string).

While that looks like an array literal as you would pass it directly to a parameter that accepts an array of string values (such as -Include in this case), what you're passing is a single string, which is interpreted as a single wildcard pattern, and will therefore not work.

What you're trying to do would require PowerShell to parse the content of the string being passed as PowerShell source code - i.e., would require an additional evaluation round - which it (fortunately) doesn't do.[1]

PowerShell, unlike other shells, is capable of passing values of any type as direct arguments to commands, whether via a variable ($incFiles, in your case) or via an expression / nested command, using (...); e.g., Write-Host -Foreground Yellow ('-' * 10))

Therefore, construct your $incFiles variable as an array of strings, and pass that array as-is to the -Include parameter:

# Create a string array of wildcard expressions.
# (an [object[]] instance whose elements are of type [string]).
# Note the use of '...' rather than "...", which clearly signals that
# the enclosed text should be taken *verbatim* (rather than being subject to
# *expansion* (string interpolation).
$incFiles = '*.txt', '*.docx'

# Pass the array as-is to -Include
Get-ChildItem -path "C:\users\paul\Downloads" -Recurse -Include $incFiles

For a comprehensive overview of how PowerShell parses unquoted arguments passed to commands, see this answer.


[1] By contrast, POSIX-like shells such as bash do apply additional evaluation to unquoted variable references to a limited extent, via so-called shell expansions - see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775