Moving or copying several files at once in Powershell - powershell

In bash, you can
cp filea fileb filec Folder
which will copy filea fileb and filec into Folder
For some reason, i couldn't find a way to do the same thing in Powershell.
Everywhere i looked, all i could find is just the possibility to use wildcards in order to move
a bunch of files from the same type like:
cp *.txt Folder
But that's not what i'm looking for. I'm looking for a way to copy several files
by their names in one command.
Does anybody knows a way to do that?

"I'm looking for a way to copy several files
by their names in one command."
Here are three examples that can do what you want. The first one is closest to what you're looking for.
param(
$files = #('filea', 'fileb', 'filec'),
$dest = 'Folder'
)
Copy-Item -LiteralPath $files -Destination $dest -Verbose
$files | ForEach-Object { Copy-Item -Path $_ -Destination $dest -Verbose }
foreach ($file in $files) { Copy-Item -Path $file -Destination $dest -Verbose }

A one liner to do:
#("file1","file2","filen") | % {Copy -Path $_ -Destination "destination"}

Related

Powershell Move Files With Matching Substrings

I'm trying to clean up a directory with a ton of files with windows powershell, and so far all the other StackOverflow posts haven't seemed to help me crack my issue.
I have a parent directory named /1/
I have a sub directory named /1/j/
I want to have all of the files in directory /1/ with (J) in any part of their names (including the parenthesis) moved into the /j/ sub directory. Example filename would be: "example filename (J).smc"
Here is the code I have so far that's not working:
$source = 'F:\1\'
$destination = 'F:\1\j'
Get-ChildItem $source -filter *.smc -recurse | Select-String -List -Pattern "(J)" | ForEach-Object {
Move-Item $PSItem.Path -Destination $destination
}
I feel like it's something simple, so I apologize if it is! Thanks for your help!!!
Made it harder than it had to be. Thanks Olaf!
Solution:
Get-ChildItem -Path 'F:\1\' -Filter *'(j)'*.smc | Move-Item -Destination 'F:\1\j'

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.

PowerShell to copy files to destination's subfolders while excluding certain folders in the destination

So I have danced with this off and on throughout the day and the timeless phrase "There's more than one way to skin a cat" keeps coming to mind so I decided to take to the community.
Scenario:
Source folder "C:\Updates" has 100 files of various extensions. All need to be copied to the sub-folders only of "C:\Prod\" overwriting any duplicates that it may find.
The Caveats:
The sub-folder names (destinations) in "C:\Prod" are quite dynamic and change frequently.
A naming convention is used to determine which sub-folders in the destination need to be excluded when the source files are being copied (to retain the original versions). For ease of explanation lets say any folder names starting with "!stop" should be excluded from the copy process. (!stop* if wildcards considered)
So, here I am wanting the input of those greater than I to tackle this in PS if I'm lucky. I've tinkered with Copy-Item and xcopy today so I'm excited to hear other's input.
Thanks!
-Chris
Give this a shot:
Get-ChildItem -Path C:\Prod -Exclude !stop* -Directory `
| ForEach-Object { Copy-Item -Path C:\Updates\* -Destination $_ -Force }
This grabs each folder (the -Directory switch ensures we only grab folders) in C:\Prod that does not match the filter and pipes it to the ForEach-Object command where we are running the Copy-Item command to copy the files to the directory.
The -Directory switch is not available in every version of PowerShell; I do not know which version it was introduced in off the top of my head. If you have an older version of PowerShell that does not support -Directory then you can use this script:
Get-ChildItem -Path C:\Prod -Exclude !stop* `
| Where-Object { $_.PSIsContainer } `
| ForEach-Object { Copy-Item -Path C:\Updates\* -Destination $_ -Force }
To select only sub folders which do not begin with "!stop" do this
$Source = "C:\Updates\*"
$Dest = "C:\Prod"
$Stop = "^!stop"
$Destinations = GCI -Path $Dest |?{$_.PSIsContainer -and $_.Name -notmatch $Stop }
ForEach ($Destination in $Destinations) {
Copy-Item -Path $Source -Destination $Destination.FullName -Force
}
Edited Now copies all files from Update to subs of Source not beginning with "!stop" The -whatif switch shows what would happen, to arm the script remove the -whatif.
Edit2 Streamlined the script. If also Sub/sub-folders of C:\Prod shall receive copies include a -rec option to the gci just in front of he pipe.

Powershell restore previous version of the files

We got hit by virus, it changed all common file extension to .kmybamf (.txt >> .txt.kmybamf ) and if I delete .kmybamf , the file got damaged.....
So I made a list of all files that got damaged. now I'm trying to overwrite them by previous version. Anyone knows how to do it in Powershell?
I can do it in cmd similar to this
subst X: \localhost\D$\#GMT-2011.09.20-06.00.04_Data
robocopy Z: D:\Folder\ /E /COPYALL
But I want to do it in one shot in Powershell, It has to be a "if .kmybamf found, then restore previous version." and powershell seems like has no such cmdlet for restoring previous version of files or folders.
$fileList = Get-Content -Path "\\localhost\D$\#GMT-2011.09.20-06.00.04_Data"
$destinationFolder = "D:\Folder\"
foreach ($file in $fileList)
{
Copy-Item -Path $file -Destination $destinationFolder -Force
}
This will also work but I find it less readable
Get-Content -Path "\\localhost\D$\#GMT-2011.09.20-06.00.04_Data" | ForEach-Object { Copy-Item -Path $_ -Destination "D:\Folder" -Force }
Get-Content is for reading the text from the files, to read the files from a folder you would have to use Get-Childitem

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))
}