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
