Public/Get-rwDirPath.ps1
|
<# .SYNOPSIS Select directories with filters, validation, and a GUI/CLI fallback. .DESCRIPTION Enumerates subfolders under a base path, applies exclusions and optional empty-folder filtering, then lets the user pick single or multiple directories. It favors Out-GridView when available and falls back to the menu helper (which keeps the selection indexes for downstream callers). .PARAMETER Path Path to scan for directories. Pipeline input supported; defaults to the current location. .PARAMETER ExcludeDir Directory names to exclude from being selected (Supports wildcards.). .PARAMETER NoEmptyDir Skip directories that contain no entries. .PARAMETER SingleDir Limit the selection to a single directory. .PARAMETER Name Output only the folder names instead of full paths. .PARAMETER Object Return `DirectoryInfo` instances for richer metadata access. .PARAMETER Title Prompt header shown in the UI (default: "Select A Folder"). .EXAMPLE Get-rwDirPath -Path .\Input -SingleDir # Select one folder, returns the full path. .EXAMPLE Get-rwDirPath -Path .\Mods -NoEmptyDir | Sort-Object # Pick multiple non-empty folders and keep the canonical paths. .EXAMPLE Get-rwDirPath -Title "Pick targets" -Name | ForEach-Object { "Chosen: $_" } # Return names only for display. .NOTES Always returns full paths unless -Name or -Object is specified. Works in both GUI and CLI hosts. #> Function Get-rwDirPath { [CmdletBinding()] [OutputType([string[]])] [OutputType([System.IO.DirectoryInfo[]])] param( [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [string]$Path = (Get-Location).Path, [Parameter()] [string[]]$ExcludeDir = @(), [Parameter()] [switch]$NoEmptyDir, [Parameter()] [switch]$SingleDir, [Parameter()] [switch]$Name, [Parameter()] [switch]$Object, [Parameter()] [ValidateNotNullOrEmpty()] [ValidateLength(1, 200)] [string]$Title = "Select A Folder" ) process { Write-Verbose "Get-rwDirPath: Path='$Path' SingleDir=$SingleDir NoEmptyDir=$NoEmptyDir" if (-not (Test-Path -LiteralPath $Path -PathType Container)) { Write-Warning "Path '$Path' does not exist or is not a directory." return @() } if ($Name -and $Object) { throw [System.ArgumentException] "`-Name` and `-Object` are mutually exclusive. Choose one." } try { $folders = Get-rwDirPathFiltered $Path -ExcludeDir $ExcludeDir -NoEmptyDir:$NoEmptyDir If (-not $folders) { return @() } } catch { Write-Error "Error enumerating directories $($_.Exception.Message)" return @() } $selected = Get-rwDirFromUI -Title $Title -Folders $folders -SingleDir:$SingleDir If (-not $selected) { return @() } Write-Verbose "After Get-rwDirFromUI: Type=$($selected.GetType().FullName) Count=$($selected.Count)" return Out-rwDirSelection -Selection $selected -ReturnName:$Name -ReturnObject:$Object } } function Get-rwDirPathFiltered { param( [string]$Path, [string[]]$ExcludeDir, [switch]$NoEmptyDir ) $dirs = Get-ChildItem -LiteralPath $Path -Directory -ErrorAction SilentlyContinue if ($ExcludeDir) { $dirs = $dirs | Where-Object { $name = $_.Name -not ($ExcludeDir | Where-Object { $name -like $_ }) } } If ($NoEmptyDir) { $dirs = $dirs | Where-Object { $null -ne ([System.IO.Directory]::EnumerateFileSystemEntries($_.FullName) | Select-Object -First 1) } } return Ensure-rwArray $dirs } |