Reputation: 56397
If I run this simple command:
gci e:\mytree -r | select fullname
it gives this output:
E:\mytree\folder1
E:\mytree\folder2
E:\mytree\folder3
E:\mytree\file1.txt
E:\mytree\file12.txt
E:\mytree\folder1\folder.with.dots
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt
E:\mytree\folder3\file4.doc
Is there any way to include in the output even root folder, so that I could have
E:\mytree
E:\mytree\folder1
E:\mytree\folder2
E:\mytree\folder3
E:\mytree\file1.txt
E:\mytree\file12.txt
E:\mytree\folder1\folder.with.dots
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt
E:\mytree\folder3\file4.doc
Upvotes: 6
Views: 9061
Reputation: 24470
Another option is to just roll a function such as below.
Function Get-ItemTree {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[ValidateScript({if (Test-Path $_ -PathType 'Container'){$true}else{throw "Invalid Path: '$_'. You must provide a valid directory."}})]
[String]$Path
)
Get-Item -Path $Path
Get-ChildItem -Path $Path -Recurse -OutBuffer 1000
}
You can add in any parameters you wish to pass through; such as a -Filter argument. Here I've hardcoded the assumption that if using this function you'd want it to be run on a container rather than leaf, you'd want to recurse, and may want to fetch a bunch of files at a time (giving a slight performance gain via the OutBuffer option).
It's not as sexy or clever as other solutions, but should be efficient, easy to reuse, easy to understand, and works for empty containers.
This is similar to your own answer, but has a few differences.
Write-Host
(a cmdlet you should generally avoid)Select-Object -Properties FullName
or Select-Object -ExpandProperty FullName
(the former creating the same output as your current function, the latter returning an array of strings holding the fullname value).Long term, I've suggest this Enhancement to MS.
Upvotes: 2
Reputation: 1
Here's my "old School" solution to this problem. For me, it's a lot easier to use and read.
# add all the file Paths to an array so the Parent can be included
$ToUpdate = @()
$FolderToUpdate = Get-ChildItem $DirectorytoChange -Directory
foreach ($Folder in $FolderToUpdate)
{
#add the paths to the array
$ToUpdate += $Folder.FullName
}
# Include the Root
$ToUpdate += $DirectorytoChange
foreach ($Path in $ToUpdate)
{
# Do stuff
}
Upvotes: -1
Reputation: 131
@(gi e:\mytree) + @(gci e:\mytree -r) | select fullname
@(..) forces the return value from each expression to be an array
Upvotes: 7
Reputation: 1604
get-childitem $root -recurse | foreach-object -begin { $arr = @((get-item $root).fullname) } -process { $arr+= $_.fullname } -end { $arr }
Using foreach-object cmdlet's begin switch, we do some work before handling the objects from get-childitem: we create an array and put the filepath of the root in there.
Then for each object in the pipeline, we append its filepath to the array.
Finally, we output the array to the pipeline.
Upvotes: 6
Reputation: 56397
This is the idea I had
function get-tree($folder) {
if (!(test-path $folder)) {
write-host "$folder doesn't exist"
return
}
else {
$arr = @()
$Object = New-Object PSObject -Property @{
fullname = $folder
}
$arr+=$object
gci $folder -r | % {
$Object = New-Object PSObject -Property @{
fullname = $_.fullname
}
$arr+=$object
}
}
$arr
}
get-tree E:\mytree
E:\mytree
E:\mytree\folder1
E:\mytree\folder2
E:\mytree\folder3
E:\mytree\file1.txt
E:\mytree\file12.txt
E:\mytree\folder1\folder.with.dots
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt
E:\mytree\folder3\file4.doc
But I'll wait other advices. :)
Upvotes: 0
Reputation: 25810
Update: I read the question again and understand that your requirement is different. Looking at how that can be done, right now. :)
OLD ANSWER
PSParentPath
contains the parent folder. If you are referring to root as in E:\, you can get that using root
property.
gci C:\Scripts -Recurse | Select FullName, PSParentPath
or in the second case,
gci C:\Scripts -Recurse | Select FullName, root
Upvotes: 0