6

If $fileName exists then the cmdlet equivalent of [System.IO.Path]::GetFullPath($fileName); is (Get-Item $fileName).FullName. However, an exception is thrown if the path does not exist. Is their another cmdlet I am missing?

Join-Path is not acceptable because it will not work when an absolute path is passed:

C:\Users\zippy\Documents\deleteme> join-path $pwd 'c:\config.sys'
C:\Users\zippy\Documents\deleteme\c:\config.sys
C:\Users\zippy\Documents\deleteme>
Justin Dearing
  • 14,270
  • 22
  • 88
  • 161

3 Answers3

8

Join-Path would be the way to get a path for a non-existant item I believe. Something like this:

join-path $pwd $filename

Update:

I don't understand why you don't want to use .Net "code". Powershell is .Net based. All cmdlets are .Net code. Only valid reason for avoiding it is that when you use .Net Code, the current directory is the directory from which Powershell was started and not $pwd

I am just listing the ways I believe this can be done so that you can handle absolute and relateive paths. None of them seem simpler than the GetFullPath() one:

$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($filename)

If you are worried if absolute path is passed or not, you can do something like:

if(Split-Path $filename -IsAbsolute){
    $filename
}
else{
    join-path $pwd $filename  # or join-path $pwd (Split-Path -Leaf $filename)
}

This is the ugly one

 $item = Get-Item $filename -ea silentlycontinue
 if (!$item) {
 $error[0].targetobject
 } else{
 $item.fullname
 }

Similar question, with similar answers: Powershell: resolve path that might not exist?

Community
  • 1
  • 1
manojlds
  • 290,304
  • 63
  • 469
  • 417
  • Join-Path creates its own problem, it falls apart when the parameter passed is an absolute path. If a combination of this and other Cmdlets will fix the issue, thats more complex than including .net code. – Justin Dearing Aug 24 '11 at 01:00
  • @Justin Dearing - Updated my answer again. – manojlds Aug 24 '11 at 01:48
  • I have nothing against calling the .NET methods. I just wanted to know if their was a cmdlet equivalent just like Test-Path is the equivalent to [System.IO.File]::Exists(). The [script](https://gist.github.com/1166670) that prompted this question actually makes two [PInvoke calls](http://pinvoke.net/), so I have nothing against calling .NET or unmanaged functions in PowerShell. – Justin Dearing Aug 24 '11 at 09:16
  • There is also [System.IO.Path]::Combine($pwd, $yourIncompletePath). – OldFart Aug 24 '11 at 15:18
  • Split-Path d:folder -IsAbsolute gives $True, but the resolved path above depends on the current directory on drive d: I would venture to suggest that this path is 'relative'. At the least it is not a complete path spec, therefore Split-Path -IsAbsolute does not work correctly for the purposes of excluding only absolute and full/complete paths from the above processing. – jdw Apr 11 '14 at 09:32
  • After further testing: The 'ugly' Get-item method appears to work in this + (e.g. x:myfolder as opposed to x:\myfolder) case, whereas, the Split-Path -IsAbsolute method does not. – jdw Apr 11 '14 at 09:42
  • GetFullPath() will resolve path, alternative would be `Join-Path $pwd "..\otherfolder" -Resolve`, but it would fail if the folder does not exist. Without -Resolve, Join-Path just concatenate two strings adding/removing "\" as necessary – papo Aug 06 '18 at 21:13
1

You could use the Test-Path cmdlet to check it exists before getting the fullname.

if (Test-Path $filename) {(Get-Item $fileName).FullName}

EDIT:

Just seen your comment above about Test-Path being the equivalent to the [system.io.file]::exists() function and I believe I understand your question better now.

No is the answer as I see it but you could make your own.

function Get-Fullname {
  param($filename)
  process{
      if (Test-Path $filename) {(Get-Item $fileName).FullName} 
  }
}

you could tidy it up some by making the parameters accept pipeline, both strings and properties but it serves the purpose.

Matt
  • 1,931
  • 12
  • 20
  • If the `$fileName`does not contain the whole path, you may have to test against full path as well: `$filepath = (Get-Item $fileName).FullName; if (Test-Path $filepath) { #do something with $filepath }` – Torbjörn Bergstedt Aug 24 '11 at 07:37
  • @tbergstedt it shouldn't as either $filename is a relative filename in which case Test-Path will work or it is an absolute again this will work. I don't see another outcome... – Matt Aug 24 '11 at 08:08
-1

You can remove the drive qualifier of 'c:\config.sys' (Using Split-Path) and then join the two paths:

PS > Join-Path $pwd (Split-Path 'c:\config.sys' -NoQualifier)    
C:\Users\zippy\Documents\deleteme\config.sys
Shay Levy
  • 121,444
  • 32
  • 184
  • 206
  • 1
    -1 - That is not the OP wants. If you give `c:\config.sys` output should be that itself. If you give `.\config.sys` output should be `C:\Users\zippy\Documents\deleteme\config.sys`, if you give `..\notexisting.txt` output should be `C:\Users\zippy\Documents\notexisting.txt` and so on. And even for what you are showing `-Leaf` is a better option that `-NoQualifier`. – manojlds Aug 24 '11 at 14:25