get-childitem c:\ -exclude windows
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 10/10/2019 2:17 PM PerfLogs
d-r-- 10/10/2019 10:20 AM Program Files
d-r-- 10/24/2019 3:56 PM Program Files (x86)
d---- 4/18/2019 11:05 AM temp
d-r-- 9/10/2019 10:00 AM Users
It could be 5 6 or 7.
Name Value
---- -----
PSVersion 6.2.3
PSEdition Core
GitCommitId 6.2.3
OS Microsoft Windows 10.0.16299
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
@mklement0 has a very detailed discussion of this behaviour here in a StackOverflow answer but the short version would be:
Get-Item c:\* -Exclude windows (rather than get-childitem).Get-ChildItem -Path c:\* -Exclude Windows will get you the child items of all the folders in c: excluding the childitems in c:windows, or one level too deep. Compare with get-childitem c:\ -Exclude \ which gets you the child items of c: excluding anything in c: - i.e. nothing.(The help get-childitem -online text is not very clear on explaining this behaviour of -Exclude)
Excluding on the root directory seems to be a special case. On subdirectories it works fine.
get-childitem c:\windows -directory -exclude winsxs
By the way, specifying the path this way gives an error message:
get-childitem Microsoft.PowerShell.Core\FileSystem::C:\ -exclude windows
get-childitem : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ get-childitem Microsoft.PowerShell.Core\FileSystem::C:\ -exclude wind ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetChildItemCommand
You'll get something similar in osx:
get-childitem / -directory -exclude var
get-childitem : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ get-childitem / -directory -exclude var
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ChildItem], PSArgumentException
+ FullyQualifiedErrorId : Argument,Microsoft.PowerShell.Commands.GetChildItemCommand
By the way, I'm having trouble editing these posts in any browser.
This seems to be a workaround for ps 6 & 7:
get-item c:\ | get-childitem -exclude *.txt
The simplest workaround is still the one quoted by @HumanEquivalentUnit above:
get-item c:\* -exclude *.txt
Thanks for the summary, @HumanEquivalentUnit - small correction:
does filtering _on the path you give to it_, rather than the child items it is about to output.
It applies the filter on the given path _first_, and then to the child items - and that first application may prevent child items from getting considered at all. Situationally, it still _happens to_ work as expected, as in @jszabo98's get-childitem c:\windows -directory -exclude winsxs example: the -Exclude pattern doesn't exclude c:\windows itself, so the child items _are_ considered, and WinSxS is properly excluded.
This counter-intuitive, but seemingly by-(unfortunate)-design behavior has previously been reported in #3304 (I previously got the above distinction wrong there as well, but have fixed it now).
I've made that clearer in the SO answer, and I've added a link to this issue to highlight the outright _bug_ with _root_ paths that @jszabo98 discovered here (which the SO answer described inadequately - fixed now).
To summarize the bug:
Targeting a _root_ directory with either Get-ChildItem or Get-Item in combination with either -Include or -Exclude - irrespective of the specific patterns passed - is broken, in the following scenarios:
On Windows _without_ a provider-qualified path: the command is unexpectedly a _quiet no-op_
On Unix-like platforms _without_ a provider-qualified and on Windows _with_ a provider-qualified path: the command breaks with statement-terminating error cannot process argument because the value of argument "path" is not valid.
Curiously, the behavior is _not_ broken _with_ a provider-qualified path on _Unix_.
Here are Pester tests:
Describe "Get-[Child]Item -Include / -Exclude tests" {
BeforeAll {
$rootPaths = '/', '\' + ($IsWindows ? 'c:\', 'c:/' : @())
$qualifiers = '', 'Microsoft.PowerShell.Core\FileSystem::'
$commands = @(
{ Get-ChildItem $rootPath -Exclude NothingToExclude }
{ Get-ChildItem $rootPath -Include * }
{ Get-Item $rootPath -Exclude NothingToExclude }
{ Get-Item $rootPath -Include * }
)
$testCases = foreach ($rootPath in $rootPaths) {
foreach ($qualifier in $qualifiers) {
foreach ($command in $commands) {
@{
Command = $command
RootPath = $qualifier + $rootPath
}
}
}
}
}
It "Command { <Command> } works with root path '<RootPath>'" -TestCases $testCases {
param($Command, $RootPath)
$(try { & $Command } catch { Write-Warning "{ $Command } with root path '$RootPath' failed unexpectedly: $_" }) | Should -Not -BeNullOrEmpty
}
}
These tests revealed an unrelated bug on Windows, namely that Get-Item Microsoft.PowerShell.Core\FileSystem::\ and Get-Item Microsoft.PowerShell.Core\FileSystem::/ by themselves don't work (whereas Get-ChildItem does) - see #11660
This might be the cause. The string version of the parent properties returned is an empty string.
get-childitem c:\ | % { "$($_.parent)" }
I don't think that's related, because it is only true in _Windows PowerShell_, and looks like the old stringification problem of System.IO.FileSystemInfo _situationally_ stringifying by file _name_ only, and the file name of a root path is the empty string.
Oh I see, fileinfo's don't even have parent properties.