I am struggling with a PowerShell script to return .json file types in all users %APPDATA% folders. When I run it in ISE, it returns "Get-ChildItem : Access is denied" and when I run ISE as admin, no output is returned.
Here is the script I am working with:
Get-ChildItem C:\Users\*\AppData\Roaming -Filter '*.json' -File -Recurse -Force -ErrorAction SilentlyContinue |
ForEach-Object {
Write-Host $('.json found in {1}' -f $_.Name, ([System.IO.Path]::GetDirectoryName($_.FullName)))
}
Any help would be greatly appreciated!
CodePudding user response:
tl;dr
It is the use of the
-File
switch that prevents your command from working - see next section.Given that you're filtering by
*.json
and that directories are unlikely to match that pattern, you can simply omit it.- If you do need to guard against that, insert a
Where-Object { -not $_.PSIsContainer }
pipeline segment after theGet-ChildItem
call; in PowerShell (Core) 7 , you can simplify toWhere-Object -Not PSIsContainer
- If you do need to guard against that, insert a
# Do NOT use -File
# Note: Run from an ELEVATED session (as admin), which is necessary to
# access other users' directories.
Get-ChildItem C:\Users\*\AppData\Roaming -Filter '*.json' -Recurse -Force -ErrorAction SilentlyContinue |
ForEach-Object { '{0} found in {1}' -f $_.Name, $_.DirectoryName }
The reason that Get-ChildItem
's -File
doesn't work in your case is that you're combining it with a -Path
value that is an actual wildcard expression rather than a literal path:
The wildcard expression is resolved first and - perhaps surprisingly - if directories are among the matching paths, they are returned as themselves, rather than listing their children (what is inside them); the latter only happens with literal input paths.
In your case, only directories match and the
-File
switch is therefore applied to them, not to their children. Since directories don't match the-File
switch (by definition aren't files), there is no output.- Whether or not the
-Recurse
switch is also present then makes no difference, given that there's nothing to recurse into.
- Whether or not the
As an aside:
If you wanted to make your command work without -Recurse
, -File
can be made to work, but only if you append \*
to your input wildcard (the positionally implied -Path
argument), so as to force enumeration of the children to match the -File
and the -Filter
against:
# Without recursion and a trailing /*, -File works
Get-ChildItem C:\Users\*\AppData\Roaming\* -File -Filter '*.json'
However, since PowerShell then needs to enumerate all children first, it is then simpler and more efficient to omit -Filter
and append its pattern directly to the input wildcard:
# No -Filter, pattern appended to input path
Get-ChildItem C:\Users\*\AppData\Roaming\*.json -File