Michele
Michele

Reputation: 3871

How Get-Childitem and only include subfolders and files?

I have a script, and currently I do the following, which gets the full path to the files in the subdir:

$filenameOut = "out.html"

#get current working dir
$cwd = Get-ScriptDirectory 

#get files to display in lists
$temp = Join-Path $cwd "Initial Forms"
$temp = Join-Path $temp "General Forms"
$InitialAppointmentGenArr = Get-ChildItem -Path $temp 

So this will return a list where the first file in the array looks like this:

"//server/group/Creds/Documents/Initial Forms/General Forms/Background Check.pdf"

However, to have my generated web page work on our extranet, I can't give the full path to the file. I just need it to return:

"Initial Forms/General Forms/Background Check.pdf"

This will be a link I can use on the extranet. How do I get get-childitem to return just the sub-path?

My script is run from

//server/group/Creds/Documents

I can't find any examples similar to this. I'd like to avoid hard-coding the script location as well, in case it gets moved.

Upvotes: 1

Views: 2602

Answers (2)

mklement0
mklement0

Reputation: 437121

I suggest the following approch:

$relativeDirPath = Join-Path 'Initial Forms' 'General Forms'

Get-ChildItem -LiteralPath $PSScriptRoot/$relativeDirPath | ForEach-Object {
  Join-Path $relativeDirPath $_.Name
}

Note that I've used $PSScriptRoot in lieu of $cwd, as it sound like the latter contains the directory in which your script is located, which automatic variable $PSScriptRoot directly reports.

Here's a generalized variation that also works with recursive use of Get-ChildItem:

$relativeDirPath = Join-Path 'Initial Forms' 'General Forms'

Get-ChildItem -LiteralPath $PSScriptRoot/$relativeDirPath | ForEach-Object {
  $_.FullName.Substring($PSScriptRoot.Length + 1)
}

As an aside: In the cross-platform PowerShell (Core) 7+ edition, the underlying .NET Core framework's System.IO.Path type now has a .GetRelativePath() method, which is a convenient way to obtain a relative path from an absolute one, via a reference path:

# PowerShell (Core) 7+ only.
PS> [IO.Path]::GetRelativePath('/foo/bar', '/foo/bar/bam/baz.txt')
bam/baz.txt

Note:

  • Since .NET's working directory typically differs from PowerShell's, be sure to provide full input paths.

  • Also, be sure that the paths are file-system-native paths, not based on PowerShell-only drives.

  • Convert-Path can be used to determine full, file-system-native paths.

Upvotes: 1

HAL9256
HAL9256

Reputation: 13453

The easy way is to simply trim the unneeded path including trailing slash:

$filenameOut = "out.html"

#get current working dir
$cwd = Get-ScriptDirectory 

#get files to display in lists
$temp = Join-Path $cwd "Initial Forms"
$temp = Join-Path $temp "General Forms"

$FullPath = Get-ChildItem -Path $temp 
$InitialAppointmentGenArr = $FullPath | %{ $_.FullName.Replace($cwd + "\","")}

Upvotes: 1

Related Questions