internal/functions/Get/Resolve-RemotePath.ps1

function Resolve-RemotePath {
    <#
    .SYNOPSIS
        Test for target paths on remote computers.
     
    .DESCRIPTION
        Test for target paths on remote computers.
 
        Has differentiated error handling (see description on TargetHandling or examples),
        in order to ensure proper tracking of all parallely processed targets.
     
    .PARAMETER Path
        The paths to check.
     
    .PARAMETER ComputerName
        The computers to check the paths on.
        Supports established PSSession objects.
 
    .PARAMETER ManagedSession
        Managed Remoting Sessions to associate with the paths resolved.
        Used later to bulk-process the paths in parallel.
     
    .PARAMETER PathHandling
        Whether all specified paths must exist on a target computer, or whether a single finding counts as success.
        Defaults to: All
     
    .PARAMETER TargetHandling
        How the command should handle unsuccessful computer targets:
        All unsuccessful checks lead to a non-terminating exception.
        However, depending on this parameter, a forced terminating exception might be thrown:
        - "All": Even a single unsuccessful computer leads to terminal errors.
        - "Any": If no target was successful, terminate
        - "None": Never terminate
        Defaults to: None
     
    .PARAMETER Cmdlet
        The $PSCmdlet variable of the caller.
        As this is an internal utility command, this allows it to terminate in the context of the calling command and remain invisible to the user.
     
    .EXAMPLE
        PS C:\> Resolve-RemotePath -Path C:\Temp -ComputerName $computers
 
        Checks for C:\Temp on all computers in $computers
        Will not generate any terminating errors.
 
    .EXAMPLE
        PS C:\> Resolve-RemotePath -Path C:\Temp -ComputerName $computers -TargetHandling All
 
        Checks for C:\Temp on all computers in $computers
        If even a single computer cannot be reached or does not have the path, this will terminate the command.
 
    .EXAMPLE
        PS C:\> Resolve-RemotePath -Path C:\Temp, C:\Tmp -ComputerName $computers -TargetHandling All -PathHandling Any
 
        Checks for C:\Temp or C:\Tmp on all computers in $computers
        Each computer is considered successful, if one of the two paths exist on it.
        If even a single computer is not successful - has neither path or cannot be reached - this command will terminate.
 
    .EXAMPLE
        PS C:\> Resolve-RemotePath -Path C:\Temp, C:\Tmp -ComputerName $computers -TargetHandling Any -PathHandling Any -ErrorAction SilentlyContinue
 
        Checks for C:\Temp or C:\Tmp on all computers in $computers
        Each computer is considered successful, if one of the two paths exist on it.
        This command will continue unbothered, so long as at least one computer is successful.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")]
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [string[]]
        $Path,

        [AllowEmptyCollection()]
        [AllowNull()]
        [PSFComputer[]]
        $ComputerName,

        $ManagedSession,

        [ValidateSet('All', 'Any')]
        [string]
        $PathHandling = 'All',

        [ValidateSet('All', 'Any', 'None')]
        [string]
        $TargetHandling = 'None',

        $Cmdlet = $PSCmdlet
    )
    begin {
        #region Implementing Code
        $code = {
            param ($Data)

            $pathResults = foreach ($path in $Data.Path) {
                try {
                    $resolvedPaths = Resolve-Path -Path $path -ErrorAction Stop
                }
                catch {
                    [PSCustomObject]@{
                        ComputerName = $env:COMPUTERNAME
                        Path         = $path
                        Exists       = $false
                    }
                    continue
                }
                foreach ($resolvedPath in $resolvedPaths) {
                    [PSCustomObject]@{
                        ComputerName = $env:COMPUTERNAME
                        Path         = $resolvedPath
                        Exists       = $true
                    }
                }
            }

            $result = [PSCustomObject]@{
                ComputerName = $env:COMPUTERNAME
                Path         = $Data.Path
                Results      = $pathResults
                ExistsAll    = @($pathResults).Where{ -not $_.Exists }.Count -lt 1
                ExistsAny    = @($pathResults).Where{ $_.Exists }.Count -gt 0
                Success      = $null
                Error        = $null
                SessionID    = $global:__PsfSessionId
                Session      = $null
            }
            if ($Data.PathHandling -eq 'All') { $result.Success = $result.ExistsAll }
            else { $result.Success = $result.ExistsAny }

            if (-not $result.Success) {
                $message = "[$env:COMPUTERNAME] Path not found: $(@($pathResults).Where{ -not $_.Exists }.ForEach{ "'$($_.Path)'" } -join ', ')"
                $result.Error = [System.Management.Automation.ErrorRecord]::new(
                    [System.Exception]::new($message),
                    'PathNotFound',
                    [System.Management.Automation.ErrorCategory]::ObjectNotFound,
                    @(@($pathResults).Where{ -not $_.Exists }.ForEach{ "'$($_.Path)'" })
                )
            }

            $result
        }
        #endregion Implementing Code

        # Passing a single array-argument as a hashtable is more reliable
        $data = @{ Path = $Path; PathHandling = $PathHandling }
    }
    process {
        #region Collect Test-Results
        if (-not $ComputerName) {
            $testResult = & $code $data
        }
        else {
            $failed = $null
            $testResult = Invoke-PSFCommand -ComputerName $ComputerName -ScriptBlock $code -ArgumentList $data -ErrorAction SilentlyContinue -ErrorVariable failed
            $failedResults = foreach ($failedTarget in $failed) {
                [PSCustomObject]@{
                    ComputerName = $failedTarget.TargetObject
                    Path         = $Path
                    Results      = @()
                    ExistsAll    = $null
                    ExistsAny    = $null
                    Success      = $false
                    Error        = $failedTarget
                    SessionID    = $null
                    Session      = $null
                }
            }
            $testResult = @($testResult) + @($failedResults) | Remove-PSFNull
        }
        #endregion Collect Test-Results

        foreach ($result in $testResult) {
            if ($result.SessionID) { $result.Session = @($ManagedSession).Where{ $_.ID -eq $result.SessionID }[0] }
            [PSFramework.Object.ObjectHost]::AddScriptMethod($result, 'ToString', { '{0}: {1}' -f $this.ComputerName, ($this.Path -join ' | ') })
            if ($result.Success) { continue }

            if (-not $result.Results) {
                Write-PSFMessage -String 'Resolve-RemotePath.Error.UnReached' -StringValues $result.ComputerName, ($Path -join ' | ') -Tag fail, connect -Target $result
            }
            else {
                Write-PSFMessage -String 'Resolve-RemotePath.Error.NotFound' -StringValues $result.ComputerName, (@($result.Results).Where{ -not $_.Exists }.Path -join ' | ') -Tag fail, notfound -Target $result
            }

            $Cmdlet.WriteError($result.Error)
        }

        if ($TargetHandling -eq 'All' -and @($testResult).Where{ -not $_.Success }.Count -gt 0) {
            Stop-PSFFunction -String 'Resolve-RemotePath.Fail.NotAll' -StringValues (@($testResult).Where{-not $_.Success }.ComputerName -join ' | '), ($Path -join ' | ') -EnableException $true -Cmdlet $Cmdlet
        }
        if ($TargetHandling -eq 'Any' -and @($testResult).Where{ $_.Success }.Count -eq 0) {
            Stop-PSFFunction -String 'Resolve-RemotePath.Fail.NotAny' -StringValues ($testResult.ComputerName -join ' | '), ($Path -join ' | ') -EnableException $true -Cmdlet $Cmdlet
        }

        $testResult
    }
}