Powershell

RTM (it does not mean what you think)

Well… it actually stands for… Read The Manual (no cuss words please πŸ˜‰).

I realized it while I was experimenting with some more Dynamic Parameters scenarios and I was playing with filters. It is a basic scenario, Get-ChildItem (or one of its forms) is a fairly common cmdlet I use every day without thinking too much about it, but it still surprised me.

This is how I (and I guess, likely most of the Powershell users) use Get-ChildItem:

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem

    Directory: /Users/carlo/Temp/dynamicParameter

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----           4/17/19 12:18 PM                folder1
d-----           4/17/19 12:18 PM                folder2
d-----           4/17/19 12:18 PM                folder3
d-----           4/17/19 12:18 PM                folder4
d-----           4/17/19 12:18 PM                folder5
------           4/24/19  7:00 PM              0 file1.csv
------           4/17/19  1:57 PM              0 file1.txt
------           4/24/19  7:00 PM              0 file2.csv
------           4/17/19  1:57 PM              0 file2.txt
------           4/24/19  7:00 PM              0 file3.csv
------           4/17/19  1:57 PM              0 file3.txt
------           4/24/19  7:00 PM              0 file4.csv
------           4/17/19  1:57 PM              0 file4.txt
------           4/24/19  7:00 PM              0 file5.csv
------           4/17/19  1:57 PM              0 file5.txt

And if I’m looking for some specific files I can do:


PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem *.csv

    Directory: /Users/carlo/Temp/dynamicParameter

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
------           4/24/19  7:00 PM              0 file1.csv
------           4/24/19  7:00 PM              0 file2.csv
------           4/24/19  7:00 PM              0 file3.csv
------           4/24/19  7:00 PM              0 file4.csv
------           4/24/19  7:00 PM              0 file5.csv

Easy enough. Anyway Get-ChildItem offers more advanced filtering capabilities, so let’s say I want to get the list of txt files but I also want to exclude the file1.txt from the output:

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Filter *.txt -Exclude *1*
PS /Users/carlo/Temp/dynamicParameter> 

No files returned? 😲
Ok, let’s try to qualify the path (even though Get-ChildItem by default takes the current directory as -Path):

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Path . -Filter *.txt -Exclude *1*
PS /Users/carlo/Temp/dynamicParameter> 

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Path /Users/carlo/Temp/dynamicParameter -Filter *.txt -Exclude *1*
PS /Users/carlo/Temp/dynamicParameter> 

Again no output, no matter if I pass “.” (current folder) or explicitly pass the full folder path to the -Path parameter πŸ€”
Well, let me try to explicitly include the files I want then:

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Include *.txt -Exclude *1*                                         
PS /Users/carlo/Temp/dynamicParameter> 

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Include *.txt -Exclude *1* -Filter *
PS /Users/carlo/Temp/dynamicParameter> 

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Include *.txt -Exclude *1* -Filter *.txt
PS /Users/carlo/Temp/dynamicParameter> 

No matter the parameter combination I try I cannot get the output I expect.

Time to admit defeat and go back to the basics:

Get-Help -Name Get-ChildItem -Online

-Filter

Specifies a filter in the format or language of the provider. The value of this parameter qualifies the Path parameter.

The syntax of the filter, including the use of wildcard characters, depends on the provider. Filters are more efficient than other parameters, because the provider applies them when the cmdlet gets the objects. Otherwise, PowerShell filters the objects after they are retrieved.

-Exclude

Specifies, as a string array, a property or property that this cmdlet excludes from the operation. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as *.txt or A*. Wildcard characters are accepted.

A trailing asterisk (*) in the Path parameter is optional. For example, -Path C:\Test\Logs or -Path C:\Test\Logs\*. If a trailing asterisk (*) is included, the command recurses into the Path parameter’s subdirectories. Without the asterisk (*), the contents of the Path parameter are displayed.


-Include

Specifies, as a string array, an item or items that this cmdlet includes in the operation. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as *.txt. Wildcard characters are accepted.

Include needs the Path parameter to use a trailing asterisk (*) to specify the directory’s contents, such as: -Path C:\Test\Logs\* If there is no trailing asterisk (*), add the Recurse parameter to the command. Otherwise the Get-ChildItem command fails.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-6

Sooo…. Include needs the Path parameter to use a trailing asterisk (*) to specify the directory’s content. If there is no asterisk, add the Recurse parameter.

Alright, let’s give it a shot:

PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem -Include *.txt -Exclude *1* -Path *      

    Directory: /Users/carlo/Temp/dynamicParameter

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
------           4/17/19  1:57 PM              0 file2.txt
------           4/17/19  1:57 PM              0 file3.txt
------           4/17/19  1:57 PM              0 file4.txt
------           4/17/19  1:57 PM              0 file5.txt


PS /Users/carlo/Temp/dynamicParameter> Get-ChildItem  -Exclude *1* -Path *              

    Directory: /Users/carlo/Temp/dynamicParameter

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
------           4/24/19  7:00 PM              0 file2.csv
------           4/17/19  1:57 PM              0 file2.txt
------           4/24/19  7:00 PM              0 file3.csv
------           4/17/19  1:57 PM              0 file3.txt
------           4/24/19  7:00 PM              0 file4.csv
------           4/17/19  1:57 PM              0 file4.txt
------           4/24/19  7:00 PM              0 file5.csv
------           4/17/19  1:57 PM              0 file5.txt

Finally! πŸŽ‰

Also, notice how in the first command I included only txt files while in the second command I included csv files too, still excluding file1.txt and file1.csv.

As an added bonus, the documentation also states that Filters are more efficient than other parameters, because the provider applies them when the cmdlet gets the objects. Otherwise, PowerShell filters the objects after they are retrieved. Sure enough, if we measure the time taken even on such a small folder, the -Filter command is about 50% faster than -Path.

PS /Users/carlo/Temp/dynamicParameter> Measure-Command { Get-ChildItem -Path *.txt }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 2
Ticks : 21210
TotalDays : 2.45486111111111E-08
TotalHours : 5.89166666666667E-07
TotalMinutes : 3.535E-05
TotalSeconds : 0.002121
TotalMilliseconds : 2.121

PS /Users/carlo/Temp/dynamicParameter> Measure-Command { Get-ChildItem -Filter *.txt }
Days : 0
Hours : 0
Minutes : 0
Seconds : 0
Milliseconds : 1
Ticks : 12292
TotalDays : 1.42268518518519E-08
TotalHours : 3.41444444444444E-07
TotalMinutes : 2.04866666666667E-05
TotalSeconds : 0.0012292
TotalMilliseconds : 1.2292

The importantthing is not to stopquestioning. – Albert Einstein 

One Comment

  • Suresh Raavi

    I can’t remember how many times I tried things without properly reading the manual and wondering why it isn’t working as I expected 😬 Well explained the importance of help and getting basics right πŸ‘

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.