public/Get-Ancestors.ps1
<#
.SYNOPSIS List ancestors of the current or given directory, optionally exporting each one into a global variable. .PARAMETER From The folder from which to start. $PWD by default. .PARAMETER ExcludeRoot Excludes the root level path in the output. .PARAMETER Export Copy output into global variables. .PARAMETER Force When used with Export, overwrites any existing globals variables of the same names with the new values. .EXAMPLE # List the ancestors of the current directory, including the root directory C:\Windows\System32\drivers\etc> Get-Ancestors n Name Path - ---- ---- 1 drivers C:\Windows\System32\drivers 2 System32 C:\Windows\System32 3 Windows C:\Windows 4 C:\ C:\ .EXAMPLE # Expand all ancestors of the given path (except the root) into global variables C:\> Get-Ancestors -From C:\projects\powershell\src\Microsoft.PowerShell.SDK -ExcludeRoot -Export n Name Path - ---- ---- 1 src C:\projects\powershell\src 2 powershell C:\projects\powershell 3 projects C:\projects C:\projects\powershell\src\Microsoft.PowerShell.SDK> $powershell C:\projects\powershell\ C:\projects\powershell\src\Microsoft.PowerShell.SDK> _ #> function Get-Ancestors { [OutputType([IndexedPath])] [CmdletBinding()] param( [Alias('FullName', 'Path')] [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)] [string] $From = $PWD, [switch] $ExcludeRoot, [switch] $Export, [switch] $Force ) Process { $start = Resolve-Path -LiteralPath $From -ErrorAction Ignore $root = $start.Drive.Root if (!$start -or ($start.Path -eq $root)) { return } $next = $start.Path $paths = @(while ($next -and ($next = $next | Split-Path) -and ($next -ne $root)) { $next }) # on Unix there's a weird empty path returned for the root directory # so we add it explicitly here instead of inside the loop if (!$ExcludeRoot -and $From -ne $root) { $paths += $root } $output = IndexPaths $paths if ($Export) { @($output) | % { New-Variable $_.name $_.path -Scope Global -Force:$Force -ErrorAction SilentlyContinue } } $output } } |