How to get the Parent's parent directory in Powershell?
PowershellScriptingPowershell Problem Overview
So if I have a directory stored in a variable, say:
$scriptPath = (Get-ScriptDirectory);
Now I would like to find the directory two parent levels up.
I need a nice way of doing:
$parentPath = Split-Path -parent $scriptPath
$rootPath = Split-Path -parent $parentPath
Can I get to the rootPath in one line of code?
Powershell Solutions
Solution 1 - Powershell
Version for a directory
get-item
is your friendly helping hand here.
(get-item $scriptPath ).parent.parent
If you Want the string only
(get-item $scriptPath ).parent.parent.FullName
Version for a file
If $scriptPath
points to a file then you have to call Directory
property on it first, so the call would look like this
(get-item $scriptPath).Directory.Parent.Parent.FullName
Remarks
This will only work if $scriptPath
exists. Otherwise you have to use Split-Path
cmdlet.
Solution 2 - Powershell
I've solved that like this:
$RootPath = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent
Solution 3 - Powershell
You can split it at the backslashes, and take the next-to-last one with negative array indexing to get just the grandparent directory name.
($scriptpath -split '\\')[-2]
You have to double the backslash to escape it in the regex.
To get the entire path:
($path -split '\\')[0..(($path -split '\\').count -2)] -join '\'
And, looking at the parameters for split-path, it takes the path as pipeline input, so:
$rootpath = $scriptpath | split-path -parent | split-path -parent
Solution 4 - Powershell
You can use
(get-item $scriptPath).Directoryname
to get the string path or if you want the Directory type use:
(get-item $scriptPath).Directory
Solution 5 - Powershell
You can simply chain as many split-path
as you need:
$rootPath = $scriptPath | split-path | split-path
Solution 6 - Powershell
In PowerShell 3, $PsScriptRoot
or for your question of two parents up,
$dir = ls "$PsScriptRoot\..\.."
Solution 7 - Powershell
To extrapolate a bit on the other answers (in as Beginner-friendly a way as possible):
- String objects that point to valid paths can be converted to DirectoryInfo/FileInfo objects via functions like Get-Item and Get-ChildItem.
- .Parent can only be used on a DirectoryInfo object.
- .Directory converts a FileInfo object to a DirectoryInfo object (targeting the file's directory), and will return null if used on any other type (even another DirectoryInfo object).
- .DirectoryName converts a FileInfo object to a String object (targeting the file's directory), and will return null if used on any other type (even another String object).
- .FullName converts a DirectoryInfo/FileInfo object to a String object, and will return null if used on any other type (even another DirectoryInfo/FileInfo object).
- .Path converts a PathInfo object to a String object, and will return null if used on any other type (even another PathInfo object).
Check the object type with the GetType Method to see what you're working with: $scriptPath.GetType()
Lastly, a quick tip that helps with making one-liners: Get-Item has the gi
alias and Get-ChildItem has the gci
alias.
Solution 8 - Powershell
simplest solution
Here's the simplest solution
"$path\..\.."
If you want to get an absolute path, you can
"$path\..\.." | Convert-Path
reusable solution
Here is a reusable solution, first define the getParent function, then call it directly.
function getParent($path, [int]$deep = 1) {
$result = $path | Get-Item | ForEach-Object { $_.PSIsContainer ? $_.Parent : $_.Directory }
for ($deep--; $deep -gt 0; $deep--) { $result = getParent $result }
return $result
}
getParent $scriptPath 2
Solution 9 - Powershell
Split-Path -Path (Get-Location).Path -Parent
Solution 10 - Powershell
In powershell :
$this_script_path = $(Get-Item $($MyInvocation.MyCommand.Path)).DirectoryName
$parent_folder = Split-Path $this_script_path -Leaf
Solution 11 - Powershell
If you want to use $PSScriptRoot you can do
Join-Path -Path $PSScriptRoot -ChildPath ..\.. -Resolve