Get files from specific folders in a directory in PowerShell - powershell

I have 4 folders in a directory. All of those folders contains some files. I want to list the file names only from the two folders.
C:\MainFolder\FolderOne\FileOne.txt
C:\MainFolder\FolderTwo\FileTwo.txt
C:\MainFolder\FolderThree\FileThree.txt
C:\MainFolder\FolderFour\FileFour.txt
I only want to list the files under FolderTwo and FolderThree.
If I use -Recurse -Include "FolderNames" it'll list only the folder names.

$source="c:\MainFolder" #location of starting directory
$files=#("*.txt", "*.doc") #if you want to include extensions add -include ($files) to get-ChildItem
Get-ChildItem -recurse ($source) -File | Where-Object {$_.PSParentPath -match "Two|Three"}

get-childitem -recurse 'foldertwo','folderthree'

Did it like this
$arrPath ='C:\MainFolder\FolderTwo','C:\MainFolder\FolderThree'
get-childitem -recurse $arrPath

Related

PowerShell GetChildItem exclude file type in base folder but include same file type from sub folder

I'm trying to find a method of getting GetChildItem to include all .xml files found in subfolders, but exclude the .xml files found in the base folder.
My folder structure looks like this:
MySubFolder\IncludeThis.xml
MySubFolder\AlsoIncludeThis.xml
AnotherSubFolder\IncludeThis.xml
AnotherSubFolder\AlsoIncludeThis.xml
ExcludeThis.xml
AlsoExcludeThis.xml
I've tried using -Include and -Exclude arguments, without any luck, as these arguments seem to only work on file types and cannot be set to work only on certain folders.
Anyone know how to get GetChildItem to filter out the .xml files from the base folder only?
PS) I won't know the names of the sub folders that exist, when using the command.
You need to get the subfolders in a first step and search them for xml Files, e.g.:
#Get list of subfolders
$folders = get-childitem -Path [path] -Directory
#Get xml files in subdirectories
$xmlFiles = get-childitem -Path $folders.fullname -Filter '*.xml' -File -recurse
While searching the the answer to this question, I came up with a method of achieving what I needed, by combining results from multiple calls to Get-ChildItem:
#Find the list of all files and folders, including files in sub folders, from a directory:
$All = Get-ChildItem -Recurse
#Find a list of items to exclude from the first list:
$Exclude = Get-ChildItem *.xml
#Remove excluded items from the list of all items:
$Result = $All | Where-Object {$Exclude.FullName -NotContains $_.FullName}
#These terms can be combined into a single difficult-to-read statement:
Get-ChildItem -Recurse | Where-Object {(Get-ChildItem *.xml).FullName -NotContains $_.FullName}

Copy specific type files from subfolders using a Powershell script

I have many folders, some of which have subfolders. I want to find and copy to special directory all files of one type, for example .txt, from them. I use this script and it works, but it copies all folders on the way to my file too. How can I avoid this? I thought about deleting all empty folders after copying, but I'm sure that the more right way exists.
$folders = [IO.Directory]::GetDirectories("S:\other","*","AllDirectories")
Foreach ($dir in $folders) {
Copy-Item -Path $dir -Filter *.txt -Recurse -Destination 'D:\FinishFolder'
}
Use Get-ChildItem to discover the files, then copy them 1 by 1:
Get-ChildItem S:\other -Filter *.txt -Recurse |Copy-Item -Destination 'D:\FinishFolder'

How to use PowerShell Get-ChildItem to retrieve files AND folders?

I'm using the Get-ChildItem command in a script. I just noticed that it will return file names beginning with bernie3_first or bernie3_second, but not folders. How can this be modified to return folders as well?
$FileNames = Get-ChildItem -Path $FilePath -Include bernie3_first*,bernie3_second* -File -Recurse | select BaseName
Your code shows a parameter that is filtering the results to only show the files and not folders. Filter parameter is -File.
Here an example:
# This would get content of C:\Test, files and folders
Get-ChildItem -Path C:\Test
# This would get content of C:\Test, only folders
Get-ChildItem -Path C:\Test -Directory
# This would get content of C:\Test, only files
Get-ChildItem -Path C:\Test -File
If you want to read more about each of the parameters you can check this on the documentation.

How to do not remove folder if there is a csv file in any of its subfolders

I am trying to clear directories but I want to leave folders that have csv files inside. I tried to use this command:
Remove-Item -Path "$Using:MyPath" -Exclude "*.csv", "*.end" -Recurse -Force -ErrorAction Stop
But it will not work with the structure below. If a csv file is inside
Sub2Folder Remove-Item will remove SubFolder with all it's contents and I will lose my csv files. Is there a way to avoid this situation and not to delete folders if any of it's subfolders has a csv file inside?
MainFolder
SubFolder
Sub2Folder
somefile.csv
I made a small script which does exaclty this. Ask me if you need more help ;)
$subfolders = Get-Childitem "$Using:MyPath\*" -Directory
#Get all folders
#foreach folder in the folders
foreach ($subfolder in $subfolders) {
if (!(Get-Childitem $subfolder.FullName -Recurse -Filter "*.csv")){ #If subfolder empty
Remove-Item $subfolder.FullName -Force -Recurse #Remove this folder
}
}
Edit: Thanks to Grzegorz Ochlik I did some changes to the script. (-Directory switch and no measure-object
If I helped you, please mark this post as the answer :D
This is working for me:
Get-ChildItem "$Using:MyPath" -Exclude "*.csv","*.end" -Recurse -File | Foreach {Remove-Item $_.Fullname}
This will list All files except the wildcarded files and remove them.

How to find all folders which has folder named "Intro" AND filetype *.mp4

The closest I got was using powershell Get-ChildItem given multiple -Filters
Get-ChildItem -Include "Intro", "*.mp4" -Recurse
I think, -Include with multiple params work as OR operator. It gives folders with either "Intro" folder OR "*.mp4" files.
But I need AND condition. Folder must contain a folder named "Intro" and "*.mp4" files.
I need folders structured following -
E:.
└───test1.mp4
└───test2.mp4
└───test3.mp4
└───test4.mp4
└───test5.mp4
└───test6.mp4
└───Intro
Update 1
I am searching for folders which meet two condition.
It must have a subfolder named Intro AND
It must have *.mp4 files.
The answer would look something like the following I guess.
Get-ChildItem -Directory -Recurse {HasSubFolderNamedIntro && HasMP4Files}
Just wanted to add another Method (one-liner) to get the folder which contains mp4 files and a folder Intro (probs to #HenrikStanleyMortensen for most of it):
(Get-ChildItem -include "*.mp4" -Recurse -File).DirectoryName | Select-Object -Unique | Where-Object {(Get-ChildItem $_ -Recurse -Include 'Intro' -Directory)}
Do you need the command to only return the file objects or do you also want the folder objects?
If just the files I would do it like this:
Get-ChildItem -include "*.mp4" -Recurse -File | Where-Object {$_.Directory.Name -match 'Intro'}
So we use the include to find the mp4 files and reduce the amount of objects we pipe.
Then we pipe it to Where-Object and look for the property with the name of the folder and says we want it to contain the word "intro". If the folder needs to be called Intro exactly and not just contain it you can change the -match to -eq
Edit
To get the directories then we could do it like this:
(Get-ChildItem -include "*.mp4" -Recurse | Where-Object {$_.Directory.Name -match 'Intro'}).DirectoryName | Select-Object -Unique
Now we say that all the files that we found that matches our search, we want to see the full directory path of those files.
To only get one match per directory, so if we have 1 directory that matches with multiple mp4 files, and we don't want to see that same directory in our output one time per file, we can pipe the result into Select-Object -Uniqueto only see each directory once.
Edit 2
After clarification from OP.
To find a folder that contains both mp4 files and a subfolder called intro I don't think we can do that only from the Get-ChildItem command in any way I know of, so we can loop through each folder like this:
$Files = (Get-ChildItem -include "*.mp4" -Recurse -File).DirectoryName | Select-Object -Unique
foreach($File in $Files) {
Get-ChildItem -Path $File.DirectoryName -Recurse -Include 'Intro' -Directory
}
We Pipe to the Select-Object -Unique to make sure that folders with multiple mp4 files are not looped through more than once thus giving us an output with the same intro folder multiple times.