Copy specific type files from subfolders using a Powershell script - powershell

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'

Related

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.

Copying Folders with Wildcards

I am trying to copy a whole bunch of files using Powershell, from one directory to another on my computer.
I used Get-ChildItem C:\Users\Tom\Google Drive\My Files\*\Assessment 1\* to identify that this was the path that I wanted to copy too, and I know about Copy-Item, but I want to maintain parts of the path name when copied.
Example:
If I copy from C:\Users\Tom\Google Drive\My Files\Cool Stuff\Assessment 1\*
I want the files to go to a folder that is created called C:\Users\Tom\Archive\Cool Stuff\Assessment 1
Whereas if I copy from C:\Users\Tom\Google Drive\My Files\New Stuff\Assessment 1\*
I want the files to go to a folder that is created called C:\Users\Tom\Archive\New Stuff\Assessment 1
You could use the Get-ChildItem cmdlet to recursively find all Assessment 1 folders within your base directory and then remove the base path using -replace to finally copy the items using the Copy-Item cmdlet:
$baseDir = 'C:\Users\Tom\Google Drive\My Files\'
$destination = 'C:\Users\Tom\Archive\'
Get-ChildItem $baseDir -directory -Filter 'Assessment 1' -Recurse | ForEach-Object {
$newPath = Join-Path $destination ($_.FullName -replace [regex]::Escape($baseDir))
Copy-Item $_.FullName $newPath -Force -Recurse
}

Use PowerShell to copy all files in many folders to a single folder

Copy-Item -Path D:\DB-DNLD\ -Filter *.csv -Destination D:\Dump\CSV -Recurse
I used this command, but it copied all .csv files along with existing folder structures, but my intention is just to copy all CSV to new single destination folder excluding source folder structures.
The Copy-Item cmdlet will maintain the tree structure. If you want to flatten the structure, you can locate the items with Get-ChildItem cmdlet then pipe that to a loop where each file it copied to the destinition folder individually.
dir -Path D:\DB-DNLD\ -Filter *.csv -Recurse | ForEach-Object { Copy-Item $_.FullName D:\Dump\CSV }

How to use the Copy-Item cmdlet correctly to copy piped files

I am building a small script which should copy all .zip files to a special folder called F:\tempzip.
I tried it with Copy-Item cmdlet, but I didn't manage to do it. The script should copy all files from this folder (recursively) which are ".zip".
This is the part of the script I am talking about:
get-childitem F:\Work\xxx\xxx\xxx -recurse `
| where {$_.extension -eq ".zip"} `
| copy-item F:\tempzip
What do I have to add?
It's a lot simpler than that. Copy-Item has its own -Recurse switch. All you have to do is:
Copy-Item F:\Work\xxx\xxx\xxx\*.zip F:\tempzip -Recurse
When piping items to copy-item you need to tell it that "F:\tempzip" is the destination path.
| Copy-Item -Destination F:\tempzip
You can also cutout piping to the where operator by using Get-ChildItem's parameter -filter.
Get-Childitem "C:\imscript" -recurse -filter "*.zip" | Copy-Item -Destination "F:\tempzip"
Edit: Removal of unnecessary foreach loop and updated explanation.
For whatever reason, the Copy-Item recursion didn't accomplish what I wanted, as mentioned here, and how it is documented to work. If you have a bunch of *.zip or *.jpg files in arbitrarily deep subfolder hierarchies, and you want to copy them to a single place (one flat folder, elsewhere), I had better luck with a piped command involving Get-ChildItem. Say you are currently in the folder containing the root of your search:
Get-ChildItem -Recurse -Include *.zip | Copy-Item -Destination C:\Someplace\Else
That command will copy all the files and not duplicate the folder hierarchies.

Powershell Get-ChildItem -recurse doesn't get all items

I'm working on a powershell script erase certain files from a folder, and move the rest into predefined subfolders.
My structure looks like this
Main
(Contains a bunch of pdb and dll files)
-- _publish
--Website
(Contains a web.config, two other .config files and a global.asax file)
-- bin
(Contains a pdb and dll file)
-- JS
-- Pages
-- Resources
I want to remove all pdb, config and asax files from the entire file structure before I start moving them. To which I use:
$pdbfiles = Get-ChildItem "$executingScriptDirectory\*.pdb" -recurse
foreach ($file in $pdbfiles) {
Remove-Item $file
}
And so on for all filetypes I need removed. It works great except for a pdb file located in the bin folder of the website. And for the ASAX file in the website folder. For some reason they get ignored by the Get-ChildItem recurse search.
Is this caused by the depth of the items within the resursive structure? Or is it something else? How can I fix it, so it removes ALL files as specified.
EDIT: I have tried adding -force - But it changed nothing
ANSWER: The following worked:
$include = #("*.asax","*.pdb","*.config")
$removefiles = Get-ChildItem "$executingScriptDirectory\*" -recurse -force -include $include
foreach ($file in $removefiles) {
if ($file.Name -ne "Web.config") {
Remove-Item $file
}
}
Get-ChildItem -path <yourpath> -recurse -Include *.pdb
You can also use the pipe for remove:
Get-ChildItem -path <yourpath> -recurse -Include *.pdb | rm