0
\$\begingroup\$

I have a Powershell script that selects a random file in a lab environment and then reads, writes, creates, and deletes files to simulate a live environment. This lab also includes folders that I don't have access to. When I perform these file actions I pick a folder at random, which can sometimes be a folder that I don't have access to. In order to ensure that I have selected a random folder that is both (a) accessible and (b) contains files, I run the following code:

function Get-RandomAccessibleFile {
    param(
        [Parameter(ValueFromPipeline)][ValidateNotNullOrEmpty()][System.Collections.ArrayList]$Folders
    )
    do {
        $RandomFolder = $Folders | Get-Random
        $RandomFiles = Get-ChildItem $RandomFolder -File -ErrorAction SilentlyContinue
    } until ($RandomFiles)
    $RandomFile = $RandomFiles | Get-Random
    return $RandomFile
}

This works, but I now find myself in a situation where I need to only validate if the folder can be accessed. This means that the Get-ChildItem could potentially run successfully, but if the randomly selected folder is empty, the $RandomFiles variable will become $null and my script would keep running until it finds a folder that currently contains files (and removing the -File flag isn't enough as it can be a completely empty folder without any subfolders). The only way I have found to guarantee that I find a folder that I have access to is to check the Acl with Get-Acl like so:

function Get-RandomAccessibleFolder {
    param(
        [Parameter()][ValidateNotNullOrEmpty()][System.Collections.ArrayList]$Folders
    )
    do {
        $RandomFolder = $Folders | Get-Random
        $FolderIsAccessible = Get-ChildItem $RandomFolder -ErrorAction SilentlyContinue
        if (-not $FolderIsAccessible) {
            try {
                Get-Acl -Path $RandomFolder -ErrorAction Stop > $null
                $FolderIsAccessible = $true
            }
            catch {
                $null
            }
        }
    } until ($FolderIsAccessible)
    return $RandomFolder
}

This feels super-inefficient. If I don't have access to the folder the first Get-ChildItem will fail, and then I run the Get-Acl again which I know will fail. I would only need to check the Get-Acl if the Get-ChildItem succeeded AND the result is empty.

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.