ChatGPT解决这个技术问题 Extra ChatGPT

Get full path of the files in PowerShell

I need to get all the files including the files present in the subfolders that belong to a particular type.

I am doing something like this, using Get-ChildItem:

Get-ChildItem "C:\windows\System32" -Recurse | where {$_.extension -eq ".txt"}

However, it's only returning me the files names and not the entire path.


C
Chris N

Add | select FullName to the end of your line above. If you need to actually do something with that afterwards, you might have to pipe it into a foreach loop, like so:

get-childitem "C:\windows\System32" -recurse | where {$_.extension -eq ".txt"} | % {
     Write-Host $_.FullName
}

P
Peter Mortensen

This should perform much faster than using late filtering:

Get-ChildItem C:\WINDOWS\System32 -Filter *.txt -Recurse | % { $_.FullName }

This is true. A caveat: this command actually gets files like *.txt* (-Filter uses CMD wildcards). If this is not what you want then use -Include *.txt.
ls | % { $_.FullName } to get full path in file listing ; assuming alias ls=Get-ChildItem
P
Peter Mortensen

You can also use Select-Object like so:

Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName

Note that Select-Object returns PSCustomObject, not a string. It might not work if you use result as parameter for another program
Yes to what @Chintsu said. To get strings instead of PSCustomObject, use -ExpandProperty FullName instead of simply FullName. As far as I understand, -ExpandProperty parameter causes the cmdlet to return the results as the specified property's (native?) type instead of as some custom object.
I needed time too (I'd messed with the source of a program and thought later that I should probably have started source control on it, but I can get an idea of my first commit against "master" by getting files since installation: Get-ChildItem -Path 'C:\Program Files\TheProgram' -Recurse | Where-Object -FilterScript {($_.LastWriteTime -gt '2020-03-01')} | Select-Object FullName
P
Peter Mortensen

Here's a shorter one:

(Get-ChildItem C:\MYDIRECTORY -Recurse).fullname > filename.txt

Here's a shorter one: (gci -r c:\).fullname
Here's a shorter one: (ls -r c:\).fullname
Here's a shorter one: (ls -r c:).fullname
P
Polymorphix

If relative paths are what you want you can just use the -Name flag.

Get-ChildItem "C:\windows\System32" -Recurse -Filter *.txt -Name


This doesn't seem to give the relative path, only the filename. Could you provide an example?
If the file is in the folder you start in, it only shows the filename. If it is in a subfolder it will give subfolder/file.txt
U
Uwe Allner

Try this:

Get-ChildItem C:\windows\System32 -Include *.txt -Recurse | select -ExpandProperty FullName

Please add a bit of information on what is different with your attempt and why the other did not work.
M
Mandrake
Get-ChildItem -Recurse *.txt | Format-Table FullName

That is what I used. I feel it is more understandable as it doesn't contain any loop syntax.


j
js2010

Really annoying thing in PS 5, where $_ won't be the full path within foreach. These are the string versions of FileInfo and DirectoryInfo objects. For some reason a wildcard in the path fixes it, or use Powershell 6 or 7. You can also pipe to get-item in the middle.

Get-ChildItem -path C:\WINDOWS\System32\*.txt -Recurse | foreach { "$_" }

Get-ChildItem -path C:\WINDOWS\System32 -Recurse | get-item | foreach { "$_" }

This seems to have been an issue with .Net that got resolved in .Net Core (Powershell 7): Stringification behavior of FileInfo / Directory instances has changed since v6.0.2 #7132


T
T3 H40

This worked for me, and produces a list of names:

$Thisfile=(get-childitem -path 10* -include '*.JPG' -recurse).fullname

I found it by using get-member -membertype properties, an incredibly useful command. most of the options it gives you are appended with a .<thing>, like fullname is here. You can stick the same command;

  | get-member -membertype properties 

at the end of any command to get more information on the things you can do with them and how to access those:

get-childitem -path 10* -include '*.JPG' -recurse | get-member -membertype properties

N
NostraDavid

Why has nobody used the foreach loop yet? A pro here is that you can easily name your variable:

# Note that I'm pretty explicit here. This would work as well as the line after:
# Get-ChildItem -Recurse C:\windows\System32\*.txt
$fileList = Get-ChildItem -Recurse -Path C:\windows\System32 -Include *.txt
foreach ($textfile in $fileList) {
    # This includes the filename ;)
    $filePath = $textfile.fullname
    # You can replace the next line with whatever you want to.
    Write-Output $filePath
}

how can I get the individual filepath of a textfile without using foreach textfile in fileList? something like textfile= $fileList[$i].fullname, I know is not the most optimal approach but I need to make it this way :(
Just add a $ in front of textfile: $textfile = $fileList[$i].FullName. Assuming $i has a numeric value, that is.
J
Josué Salomão

I used this line command to search ".xlm" files in "C:\Temp" and the result print fullname path in file "result.txt":

(Get-ChildItem "C:\Temp" -Recurse | where {$_.extension -eq ".xml"} ).fullname > result.txt 

In my tests, this syntax works beautiful for me.


.FullName was what I needed!
P
Peter Mortensen
gci "C:\WINDOWS\System32" -r -include .txt | select fullname

Could you please elaborate more your answer adding a little more description about the solution you provide?
v
vulcan raven

[alternative syntax]

For some people, directional pipe operators are not their taste, but they rather prefer chaining. See some interesting opinions on this topic shared in roslyn issue tracker: dotnet/roslyn#5445.

Based on the case and the context, one of this approach can be considered implicit (or indirect). For example, in this case using pipe against enumerable requires special token $_ (aka PowerShell's "THIS" token) might appear distasteful to some.

For such fellas, here is a more concise, straight-forward way of doing it with dot chaining:

(gci . -re -fi *.txt).FullName

(<rant> Note that PowerShell's command arguments parser accepts the partial parameter names. So in addition to -recursive; -recursiv, -recursi, -recurs, -recur, -recu, -rec and -re are accepted, but unfortunately not -r .. which is the only correct choice that makes sense with single - character (if we go by POSIXy UNIXy conventions)! </rant>)


Note to the rant: the -r short form of -Recurse works fine for me.
@Polymorphix, you are right, it is working for me on Windows 10 (not sure which version I was trying earlier). However, same holds true with -File switch -fi in the sample: -fil and -file works, but not -f. Going by POSIX style, it should be --file (multi-letters) and -f (single-letter, unless -f is reserved for something else, say force switch, then it can be something else like -l or no single-letter option at all).
U
Unheilig

I am using below script to extact all folder path:

Get-ChildItem -path "C:\" -Recurse -Directory -Force -ErrorAction SilentlyContinue | Select-Object FullName | Out-File "Folder_List.csv"

Full folder path is not coming. After 113 characters, is coming:

Example - C:\ProgramData\Microsoft\Windows\DeviceMetadataCache\dmrccache\en-US\ec4d5fdd-aa12-400f-83e2-7b0ea6023eb7\Windows...

J
Jonathan

I had an issue where I had an executable file which had directory path strings as parameters and the format. Like this:

"C:\temp\executable.exe" "C:\storage\filename" "C:\storage\dump" -jpg

I needed to execute this command across terabytes of .jpg files in different folders.

$files = Get-ChildItem  -Path C:\storage\*.jpg -Recurse -Force | Select-Object -ExpandProperty FullName

for ($i=0; $i -lt $files.Count; $i++) {
    [string]$outfile = $files[$i]
    
    Start-Process -NoNewWindow -FilePath "C:\temp\executable.exe" -ArgumentList $outfile, "C:\storage\dump", "-dcm"
   

}