Public/Get-PathAnalysis.ps1

function Get-PathAnalysis {
    <#
    .SYNOPSIS
        Analyzes the Windows PATH environment variable for issues.
         
    .DESCRIPTION
        Scans both User and Machine PATH entries to detect:
        - Paths that no longer exist (obsolete)
        - Duplicate entries
        - Invalid paths
         
    .PARAMETER Target
        Which PATH to analyze: User, Machine, or Both. Default is Both.
         
    .PARAMETER IssuesOnly
        If specified, only returns entries with issues.
         
    .EXAMPLE
        Get-PathAnalysis
         
    .EXAMPLE
        Get-PathAnalysis -Target User -IssuesOnly
    #>

    [CmdletBinding()]
    [OutputType([PSCustomObject[]])]
    param(
        [ValidateSet('User', 'Machine', 'Both')]
        [string]$Target = 'Both',
        
        [switch]$IssuesOnly
    )

    $results = @()
    $entries = Get-PathEntries -Target $Target
    $allPaths = @()

    # Process User paths
    if ($Target -eq 'User' -or $Target -eq 'Both') {
        foreach ($path in $entries.User) {
            $allPaths += @{
                Path  = $path
                Scope = 'User'
            }
        }
    }

    # Process Machine paths
    if ($Target -eq 'Machine' -or $Target -eq 'Both') {
        foreach ($path in $entries.Machine) {
            $allPaths += @{
                Path  = $path
                Scope = 'Machine'
            }
        }
    }

    # Find duplicates (across all paths)
    $allPathStrings = $allPaths | ForEach-Object { $_.Path }
    $duplicates = Find-DuplicatePaths -Paths $allPathStrings

    # Track seen paths for duplicate detection
    $seenPaths = @{}

    foreach ($item in $allPaths) {
        $testResult = Test-PathEntry -Path $item.Path
        $normalizedPath = $testResult.Expanded.TrimEnd('\').ToLowerInvariant()
        
        # Determine issues
        $issues = @()
        $status = '✓'
        
        if (-not $testResult.Exists) {
            $issues += 'Does not exist'
            $status = '✗'
        }
        
        if ($seenPaths.ContainsKey($normalizedPath)) {
            $issues += "Duplicate of: $($seenPaths[$normalizedPath])"
            $status = '⚠'
        }
        else {
            $seenPaths[$normalizedPath] = $item.Path
        }
        
        $resultItem = [PSCustomObject]@{
            Status       = $status
            Path         = $item.Path
            Scope        = $item.Scope
            Exists       = $testResult.Exists
            Issue        = if ($issues.Count -gt 0) { $issues -join '; ' } else { '-' }
            ExpandedPath = $testResult.Expanded
        }
        
        if ($IssuesOnly) {
            if ($issues.Count -gt 0) {
                $results += $resultItem
            }
        }
        else {
            $results += $resultItem
        }
    }

    # Add summary info
    $userCharCount = Get-PathCharacterCount -Paths $entries.User
    $machineCharCount = Get-PathCharacterCount -Paths $entries.Machine
    
    Write-Verbose "User PATH: $($entries.User.Count) entries, $userCharCount characters"
    Write-Verbose "Machine PATH: $($entries.Machine.Count) entries, $machineCharCount characters"
    Write-Verbose "Total issues found: $(($results | Where-Object { $_.Status -ne '✓' }).Count)"

    return $results
}