Search code examples
powershellnetwork-programmingpermissionstimeoutntfs

How to wait for permission denied type erros over the network


In a script, I use Get-ChildItem -File -Recurse in order to check my permissions on subfolders. Then, I try to read the first character of every files. My goal is to catch Permission Denied type errors using $Error. It works well locally. But when I execute the script on a remote server with a UNC long path, the errors aren't generated. If I run manually the Get-ChildItem command just after the execution of the script, which is supposed to generate some errors, it display the files but does not generate errors. If I wait a few minutes and I run it again, I finally get the errors displayed. Is there a way to wait for the errors to be generated?

Here is the specific part of my code which doesn't generate any error over the network:

# Check if the current item is a folder or a file
If($elem.Attributes -eq 'Directory')
{
    # Get all child items of File type
    $subElem = Get-ChildItem -LiteralPath $elem.FullName -File -Recurse -ErrorAction SilentlyContinue
                
    # Parse subfolders and files to check permissions integrity. To generate an Permission Denied error, a file must be open
    ForEach($subItem in $subElem)
    {
        # Read the first character of the current sub-item
        Get-Content -LiteralPath $subItem.FullName -Encoding byte -TotalCount 1 -ErrorAction SilentlyContinue | Out-Null
    }
}
Else
{
    # Read the first character of the current element
    Get-Content -LiteralPath $elem.FullName -Encoding byte -TotalCount 1 -ErrorAction SilentlyContinue | Out-Null
}

Solution

  • I finally found the solution myself. In this script, I use the module NTFSSecurity (https://github.com/raandree/NTFSSecurity) in order to manage ACLs and inheritance. Over the network, it seems to be a bit slow.

    Before the bit of code I shared above, I have a few lines which check and updates a bunch of ACLs over the network. As it takes some time, errors are only generated some time after. In this case, if the command encounter an error, it just continues but doesn't display or catch the error at the same time.

    I used errors to detect items on which I had to recover the access. Now, I use another cmdlet coming with the NTFSSecurity module, Get-NTFSEffectiveAccess. I wrote a little function which does perfectly the trick:

    Function Check-MyAccess([String]$Path)
    {
        # Get effective permissions
        $effectiveAccess = Get-NTFSEffectiveAccess -Path $Path -ErrorAction SilentlyContinue
        
        # Check to be, at least, able to read the item
        If(($effectiveAccess -eq $Null) -or ($effectiveAccess.AccessRights -Match 'Synchronize') -or ((($effectiveAccess.AccessRights -Like '*Read*') -or ($effectiveAccess.AccessRights -Like '*Modify*') -and ($effectiveAccess.AccessControlType -Match 'Deny'))))
        {
            Return $False
        }
        Else
        {
            Return $True
        }
    }