PowerShell for Windows Admins

Sep 21 2018   5:32AM GMT

Splitting paths

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:
Powershell

PowerShell has the Split-Path cmdlet that provides the leaf and parent of a path. But what if you’re splitting paths and need one or paths at a higher level.

Consider the path

PS> $path = 'C:\Scripts\HyperV\Admin\Optimize-VMDisks.ps1'

 

Its just an arbitrary path from my test machine.

Using Split-Path you can get the parent (by default) or the leaf path

PS> Split-Path -Path $path
C:\Scripts\HyperV\Admin
PS> Split-Path -Path $path -Parent
C:\Scripts\HyperV\Admin
PS> Split-Path -Path $path -Leaf
Optimize-VMDisks.ps1

 

But what if you want the grandfather path. That starts to get ugly just using Split-Path.

PS> Split-Path -Path (Split-Path -Path $path -Parent)
C:\Scripts\HyperV

 

The code gets uglier and uglier as you progress up the path

I decided I needed an object whose properties gave me a consistent view of the path hierarchy – the parent path was always level 1; the grandfather was always level 2 etc. Something like this

Level00 : C:\Scripts\HyperV\Admin\Optimize-VMDisks.ps1
Level01 : C:\Scripts\HyperV\Admin
Level02 : C:\Scripts\HyperV
Level03 : C:\Scripts
Level04 : C:\

 

My solution was to create this function

function split-multipath {
  [CmdletBinding()]
  param (
    [string]$path
  )

  if (-not (Test-Path -Path $path -IsValid)) {
    throw "Invalid path: $path" 
  }

  $outpaths = [ordered]@{
    Level00 = $path
  }

  $l = 1

  $path = Split-Path -Path $path  -Parent

  while ($path -ne ''){
    $level = "Level{0:00}" -f $l
    $outpaths += @{
       $level = $path
    }
    
    $l++
    $path = Split-Path -Path $path  -Parent

  }

  New-Object -TypeName PSobject -Property $outpaths

}

 

The split-multipath function takes a string as a parameter. That string is tested to determine if its a valid path – that could be moved to a ValidateScript test on the parameter.

The output is created from an ordered hash table. The Level00 property is set to the full path as input.

Set the counter and split the path to get the parent.

Use a while loop to add the current path into the hash table – create the property name with the string format operator –f.

Increment the counter and split the path – again taking the parent.

The while loop runs while the path has data. If you try to split when the path just contains the drive you get an empty string

PS> (Split-Path -Path c:\ -Parent) -eq ''
True

 

The data is output as an object so you can access a particular level. For instance if you want the great-grandfather level – you use Level03

PS> $test.Level03
C:\Scripts

 

You can use the output object to create a new path based on the level of your choice

PS> Join-Path -Path $test.Level03 -ChildPath Test47
C:\Scripts\Test47

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: