I'm very new to PowerShell and have basically zero knowledge about PowerShell scripting, which is why I need some help.
I have folder structure with subfolders (as shown below) for which I want to generate a filelist.txt in every 1st level subfolder using Get-ChildItem -Recurse
.
Main Folder
├───Sub 1
│ │ file.ext
│ └───Sub A
│ file.ext
└───Sub 2
| | file.ext
| └───Sub B
└─── etc.
So far, I experimented with some code I found online but either I'm getting errors or absolutely nothing happens. This is the closest thing to what I want, as it creates filelist.txt files in the correct directories, but unfortunately those files are empty. In addition, a filelist.txt is created in the main folder which I don't want.
Get-ChildItem -Recurse -Directory |
ForEach-Object {
New-Item -ItemType file -Path "$($_.FullName)" -Name "filelist.txt"
Get-ChildItem $_ -Recurse > filelist.txt
}
Any help or suggestions are very appreciated!
CodePudding user response:
If you're looking for the immediate sub-folders of Main Folder
you shouldn't use -Recurse
on your first call to Get-ChildItem -Directory
as that would give you all sub-folders recursively as zett42 pointed out in his helpful comment.
Regarding your export line:
Get-ChildItem $_ -Recurse > filelist.txt
It would place the filelist.txt
file on your current location not on the subfolders, it would also replace the file per loop iteration.
The code would look like this if I understood correctly what you were looking for:
Get-ChildItem 'path\to\Main Folder' -Directory | ForEach-Object {
$destination = Join-Path $_.FullName -ChildPath filelist.txt
Get-ChildItem -LiteralPath $_.FullName -Recurse |
Set-Content $destination
}
Worth noting that this would only export the absolute paths of the files and folders under each sub-folder of Main Folder
, however it might be worth changing the export type to CSV to have the properties of each object as you see them on your console:
$destination = Join-Path $_.FullName -ChildPath filelist.csv
Get-ChildItem -LiteralPath $_.FullName -Recurse |
Export-Csv $destination -NoTypeInformation
CodePudding user response:
While I normally avoid external commands when a proper solution can be found with PowerShell cmdlets, tree /f
already does this for you. There is some funkiness with relying on transcripts to provide the directory tree but you should be able to manually redirect the output to a file without issue:
cd /path/to/base/folder
tree /f > filelist.txt
This will create filelist.txt
relative to the directory you ran tree /f
from, and redirect the output to filelist.txt
. Note that if filelist.txt
exists already in the folder tree, it will be enumerated with the rest of the files.
CodePudding user response:
Here's what I did.
##variables
$startingLocation = Get-Location
$subs = Get-ChildItem -Recurse -Depth 1 -Directory
$startingCheck = ($startingLocation).Path "\filelist.txt"
##create starting list in original directory
##check if it exists already and write to it
if ( Test-Path -Path $startingCheck) {
Get-ChildItem -Recurse >> filelist.txt
}
else {
Write-Warning "File doesn't exist... creating file."
New-Item -ItemType File -Path $startingLocation -Name "filelist.txt"
Write-Warning "File created."
Get-ChildItem -Recurse >> filelist.txt
Write-Warning "File created and now writing GCI to log."
}
##loop
foreach ($s in $subs) {
##go to the location
Set-Location -Path $s.FullName -Verbose
##test if output file exists in current directory of loop
$testPwd = Get-Location -Verbose
$currentPath = ($testPwd).Path "\filelist.txt"
## if the file already exists - write GCI to it
if (Test-Path -Path $currentPath) {
Get-ChildItem -Recurse -Depth 1 >> filelist.txt
Write-Warning "File exists... writing GCI to log."
}
## otherwise if there is no file, make one and write GCI to it
else {
Write-Warning "File doesn't exist... creating file."
New-Item -ItemType File -Path $testPwd -Name "filelist.txt"
Write-Warning "File created."
Get-ChildItem -Recurse -Depth 1 >> filelist.txt
Write-Warning "File created and now writing GCI to log."
}
##exit the loop
}
#go back to original location
Set-Location $startingLocation
Before:
Folder PATH listing for volume Windows
Volume serial number is A4DB-B980
C:.
│ test.ps1
│
├───Folder1
│ │ doc1.txt
│ │ doc2.txt
│ │
│ ├───FolderA
│ └───FolderB
│ └───FolderB1
│ doc1b.txt
│ doc2b.txt
│
├───Folder2
│ ├───FolderA
│ └───FolderB
└───Folder3
Result:
Folder PATH listing for volume Windows
Volume serial number is A4DB-B980
C:.
│ filelist.txt
│ test.ps1
│
├───Folder1
│ │ doc1.txt
│ │ doc2.txt
│ │ filelist.txt
│ │
│ ├───FolderA
│ │ filelist.txt
│ │
│ └───FolderB
│ │ filelist.txt
│ │
│ └───FolderB1
│ doc1b.txt
│ doc2b.txt
│
├───Folder2
│ │ filelist.txt
│ │
│ ├───FolderA
│ │ filelist.txt
│ │
│ └───FolderB
│ filelist.txt
│
└───Folder3
filelist.txt
CodePudding user response:
I think what you want is:
Get-ChildItem -Path $BaseFolder -Depth 1
You can mess with the -Depth argument if you need another level.