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

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.

Related

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'

Powershell script to copy files based on filename

I have a folder that contains several thousand files. I would like to write a Powershell script that loops through the files and copies each file whose filename contains a specific keyword. In pseudocode:
For each file in C:\[Directory]
If filename contains "Presentation" Then
copy file in C:\[Directory 2]
Simply like this ?
copy-item "C:\SourceDir\*Presentation*" "C:\DestinationDir"
or like this :
copy-item "C:\SourceDir\*" "C:\DestinationDir" -Filter "*rrrr*"
But a risk exist if you have a directory with "presentation" in his name into the source directory. Then take all method proposed here and add -file in get-childitem command.
Like in this short version of Robdy code :
gci "C:\SourceDir" -file | ? Name -like "*Presentation*" | cpi -d "C:\DestinationDir"
That code should do the trick:
$files = Get-ChildItem -Path "C:\path\to\source\folder"
$files | Where-Object Name -Like "*Presentation*" | Copy-Item -Destination "C:\path\to\destination\folder"
Of course can be written in one line but I put in two for visibility.
Edit: as Esperento57 pointed out, you might want to add -ItemType File to Get-ChildItem cmdlet to not include folders with 'Presentation' in their name. Also, depending on your needs you might also want to use -Recurse param to include files in subfolders.
If you have files in subfolders and you want to keep the path in destination folder you'll have to change the script a bit to something like:
Copy-Item -Destination $_.FullName.Replace('C:\path\to\source\folder','C:\path\to\destination\folder')
And for the above you'll have to make sure that folders are actually created (e.g. by using -Force for Copy-Item.
This seems to work:
$src = "Dir1"
$dst = "Dir2"
Get-ChildItem $src -Filter "*Presentation*" -Recurse | % {
New-Item -Path $_.FullName.Replace($src,$dst) -ItemType File -Force
Copy-Item -Path $_.FullName -Destination $_.FullName.Replace($src,$dst) -Force
}
Try something like this:
Get-ChildItem "C:\Your\Directory" -File -Filter *YourKeyWordToIsolate* |
Foreach-Object { Copy-Item $_.FullName -Destination "C:\Your\New\Directory" }
... but, of course, you'll need to fill in some of the blanks left open by your pseudocode example.
Also, that's a one-liner, but I inserted a return carriage for easier readability.

Deleting specific folders within folders that have changing names

So my boss needs me to create a script that deletes everything in a directory with the exception of the folders with the name "incoming" and "outgoing," while still deleting all files and directories within those folders. These two folders are also stored in random company name folders so I cant specify each one as the list will keep growing.
How can I delete all the incoming and outgoing folder contents without deleting the folder that those folders are stored in?
Here is the code I have so far:
Get-ChildItem -Path ("C:\Users\testuser\Desktop\Test") -Exclude "Incoming","Outgoing" | foreach ($_) {
"CLEANING :" + $_.FullName
Remove-Item $_.FullName -Force -Recurse
"CLEANED... :" + $_.FullName
}
Is this the right approach? is there a switch or something that I should be adding to this command to add extra options? This script will be run daily via a Windows task I'm going to setup. Maybe there's a way to specify how deep the deletion script goes?
Hopefully this is what you need. This should delete files and folders that are in under the folders "Incoming" and "Outgoing."
$folders = Get-ChildItem -Path "C:\Users\mkrouse\Desktop\Test" -Recurse -Directory | Where-Object {($_.basename -contains "Incoming") -or ($_.BaseName -contains "Outgoing")}
foreach($folder in $folders){
$items = Get-ChildItem -Path $folder.FullName -Recurse
foreach($file in $items) {
Remove-Item -Path $file.FullName -Recurse -Force -WhatIf
}
}

Need a script to publish build output to a staging server

I am trying to write a PowerShell script that will copy a subset of files from a source folder and place them into a target folder. I've been playing with "copy-item" and "remove-item" for half a day and cannot get the desired or consistent results.
For example, when I run the following cmdlet multiple times, the files end up in different locations?!?!:
copy-item -Path $sourcePath -Destination $destinationPath -Include *.dll -Container -Force -Recurse
I've been trying every combination of options and commands I can think of but can't find the right solution. Since I'm sure that I'm not doing anything atypical, I'm hoping someone can ease my pain and provide me with the proper syntax to use.
The source folder will contain a large number of files with various extensions. For example, all of the following are possible:
.dll
.dll.config
.exe
.exe.config
.lastcodeanalysisissucceeded
.pdb
.Test.dll
.vshost.exe
.xml
and so on
The script needs to only copy .exe, .dll and .exe.config files excluding any .test.dll and .vshost.exe files. I also need the script to create the target folders if they don't already exist.
Any help getting me going is appreciated.
try:
$source = "C:\a\*"
$dest = "C:\b"
dir $source -include *.exe,*.dll,*.exe.config -exclude *.test.dll,*.vshost.exe -Recurse |
% {
$sp = $_.fullName.replace($sourcePath.replace('\*',''), $destPath)
if (!(Test-Path -path (split-path $sp)))
{
New-Item (split-path $sp) -Type Directory
}
copy-item $_.fullname $sp -force
}
As long as the files are in one directory, the following should work fine. It might be a bit more verbose than needed, but it should be a good starting point.
$sourcePath = "c:\sourcePath"
$destPath = "c:\destPath"
$items = Get-ChildItem $sourcePath | Where-Object {($_.FullName -like "*.exe") -or ($_.FullName -like "*.exe.config") -or ($_.FullName -like "*.dll")}
$items | % {
Copy-Item $_.Fullname ($_.FullName.Replace($sourcePath,$destPath))
}

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