Home > Enterprise >  In Powershell, "Get-ChildItem -recurse" and skip over "Access denied" by printin
In Powershell, "Get-ChildItem -recurse" and skip over "Access denied" by printin

Time:01-25

In powershell, with "gci -recurse", I'm just getting a little bit annoyed by Powershell's overly verbose Error exception messages, is there a way to trap the exception messages and just print a simple one-line: access denied with the file name? Instead of the usual 6 line message in red for each access denied message??

Here's what I want my output to look like:

PS> Get-ChildItem -Path . -Include python*.exe -recurse -ErrorAction Continue

(access denied) C:\condor\tokens.sk
C:\Program Files\Inkscape\bin\python.exe
C:\Program Files\Inkscape\bin\pythonw.exe
C:\Program Files\Inkscape\lib\python3.9\venv\scripts\nt\python.exe
C:\Program Files\Inkscape\lib\python3.9\venv\scripts\nt\pythonw.exe
C:\Program Files\LibreOffice\program\python-core-3.8.10\bin\python.exe
C:\Program Files\LibreOffice\program\python.exe
(access denied) C:\Program Files\Windows Defender Advanced Threat Protection\Classification\Configuration 
(access denied) C:\Program Files (x86)\Google\CrashReports
(access denied) 'C:\Program Files (x86)\Trend Micro\Security Agent\CCSF\module\DRE\data
...

Example of my annoyance, 6 lines of red ink for each access denied, which is very ugly and hard to read:

PS> Get-ChildItem -Path . -Include python*.exe -recurse -ErrorAction Continue

Get-ChildItem : Access to the path 'C:\condor\tokens.d' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\condor\tokens.d:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Access to the path 'C:\condor\tokens.sk' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\condor\tokens.sk:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

C:\Program Files\Inkscape\bin\python.exe
C:\Program Files\Inkscape\bin\pythonw.exe
C:\Program Files\Inkscape\lib\python3.9\venv\scripts\nt\python.exe
C:\Program Files\Inkscape\lib\python3.9\venv\scripts\nt\pythonw.exe
C:\Program Files\LibreOffice\program\python-core-3.8.10\bin\python.exe
C:\Program Files\LibreOffice\program\python.exe
Get-ChildItem : Access to the path 'C:\Program Files\Windows Defender Advanced Threat Protection\Classification\Configuration' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\Program File...n\Configuration:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Access to the path 'C:\Program Files (x86)\Google\CrashReports' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\Program File...le\CrashReports:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Access to the path 'C:\Program Files (x86)\Trend Micro\Security Agent\CCSF\module\DRE\data' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\Program File...module\DRE\data:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Access to the path 'C:\Users\local_admin' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\Users\local_admin:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

Get-ChildItem : Access to the path 'C:\Users\pvadmin' is denied.
At H:\tools\scripts\lib_grep.ps1:55 char:9
          Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction ...
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : PermissionDenied: (C:\Users\pvadmin:String) [Get-ChildItem], UnauthorizedAccessException
      FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand

C:\Window.pre_ise\Installer\{C0C31BCC-56FB-42A7-8766-D29E1BD74C7C}\python_icon.exe
G

I thought about using a try-catch block... but i'm uncertain how this works for a pipe-line of objects...where each object can generate an exception...

CodePudding user response:

You could merge the error stream into the standard output stream (2>&1) and convert all error records to strings:

Get-ChildItem -Path . -Include python*.exe -recurse -ErrorAction Continue 2>&1|%{
  if($_ -is [System.Management.Automation.ErrorRecord]){
    # if this is an error, print the exception message directly to the screen
    Write-Host $_.Exception.Message -ForegroundColor Red
  }
  else {
    # otherwise, just output the input object as-is
    $_
  }
}

If you don't actually want to suppress the errors but just want more concise error messages on screen while running the script, use the $ErrorView preference variable:

PS ~> $ErrorView = 'CategoryView'
PS ~> Get-ChildItem -Path $Dir -Include $Name -recurse -ErrorAction continue |% FullName
PermissionDenied: (C:\condor\tokens.d:String) [Get-ChildItem], UnauthorizedAccessException
PermissionDenied: (C:\condor\tokens.sk:String) [Get-ChildItem], UnauthorizedAccessException
C:\Program Files\Inkscape\bin\python.exe
C:\Program Files\Inkscape\bin\pythonw.exe
C:\Program Files\Inkscape\lib\python3.9\venv\scripts\nt\python.exe
C:\Program Files\Inkscape\lib\python3.9\venv\scripts\nt\pythonw.exe
C:\Program Files\LibreOffice\program\python-core-3.8.10\bin\python.exe
C:\Program Files\LibreOffice\program\python.exe
PermissionDenied: (C:\Program File...n\Configuration:String) [Get-ChildItem], UnauthorizedAccessException
PermissionDenied: (C:\Program File...le\CrashReports:String) [Get-ChildItem], UnauthorizedAccessException
PermissionDenied: (C:\Program File...module\DRE\data:String) [Get-ChildItem], UnauthorizedAccessException
PermissionDenied: (C:\Users\local_admin:String) [Get-ChildItem], UnauthorizedAccessException
PermissionDenied: (C:\Users\pvadmin:String) [Get-ChildItem], UnauthorizedAccessException
C:\Window.pre_ise\Installer\{C0C31BCC-56FB-42A7-8766-D29E1BD74C7C}\python_icon.exe

CodePudding user response:

System.UnauthorizedAccessException can be redirected, you can use a calculated property with Select-Object for example:

$Expression = {
    if($_.Exception -is [System.UnauthorizedAccessException]) {
        return "[Access Denied] - $_"
    } # Other Exceptions can be handled here depending on it's Type.
    $_.FullName
}

Get-ChildItem /etc -Recurse -Force -ErrorAction Continue 2>&1 | Select-Object @{
    Name = 'FullName'
    Expression = $Expression
}

Here is an example output of how it looks while enumerating my etc directory:

FullName
--------
[Access Denied] - Access to the path '/etc/ppp/peers' is denied.
/etc/security/access.conf
[Access Denied] - Access to the path '/etc/chatscripts' is denied.
[Access Denied] - Access to the path '/etc/polkit-1/localauthority' is denied.
/etc/brltty/Contraction/latex-access.ctb
[Access Denied] - Access to the path '/etc/cups/ssl' is denied.
[Access Denied] - Access to the path '/etc/ssl/private' is denied.
/etc/apparmor.d/abstractions/dbus-accessibility
  •  Tags:  
  • Related