Is it possible to list all permissions where I don't have access

Solution 1:

An easier and less confusing way to trap cmdlet specific errors to a file is by using the -Errorvariable parameter. It is built into most cmdlets. It is not reliable to look at the $Error variable as it is a global variable and has a high chance of being stained by other unmitigated errors in the powershell process.

The code below will log the errors in 2 log files.

  1. gci_errors.csv - Contains errors enumerating the folders
  2. gacl_errors.csv - Contains errors enumerating ACL on a particular file/folder.

    Get-ChildItem C:\Temp -Recurse -ErrorAction SilentlyContinue -ErrorVariable gci_errors | ForEach-Object {
    
        $_ | Get-Acl -ErrorAction SilentlyContinue -ErrorVariable gacl_errors
    }
    
    $gci_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gci_errors.csv 
    $gacl_errors | Select-Object -ExpandProperty CategoryInfo | Export-Csv -NoTypeInformation -Path C:\Temp\gacl_errors.csv
    

I have changed the output to a CSV file as per your requirement. It makes more sense as its easier to analyse and import to run commands on the data. The CSV has a colum header called Target which reflects the folder path that is causing you problems. You can write a cmdlet ie Fix-DirPerms and pipe to it. Something like:

    Import-CSV -Path c:\Temp\gci_errors.csv | Fix-DirPerms

Solution 2:

There are a lot of different ways to do this. Here is something I just cooked up.

$Error.Clear()      # This is a global variable!
$Errors = @()
$Items = Get-ChildItem C:\ -Recurse -ErrorAction SilentlyContinue
ForEach($Err In $Error)
{
    $Errors += $Err.Exception
}
ForEach($Item In $Items)
{
    Try
    {
        $Item | Get-ACL -ErrorAction SilentlyContinue | Out-Null
    }
    Catch
    {
        $Errors += "$($_.Exception.Message) $($Item.FullName)"
    }
}    
Write-Host $Errors.Count "errors encountered."
$Errors | Out-File errors.txt

So now you have a neat list of all the errors that were encountered either in the Get-ChildItem process or in the Get-ACL process, which is important because distinct errors can be encountered during each operation. You can pipe the $Errors variable out to a CSV or whatever you want. This will probably take a long time to run on a 3TB network share. Consider adding a progress meter.