I'd like to move all the files in multiple folders into a subfolder within those folders.
So from C:\Desktop\Folder to C:\Desktop\Folder\cv.
I'm having difficulty targeting the correct destination, so far I've tried:
Get-ChildItem *cv -Recurse -Exclude "cv" | Move-Item -Destination {"C:\Desktop\$($_.Name)\cv"}
I'm using Windows PowerShell.
EDIT: For those interested I've found a way to do this using CMD:
FOR /D %G IN ("*cv") DO robocopy /move "%~G" "%~G\cv" "*"
I'd still like to know how to do this using PowerShell, though.
Related
I want to copy all JPGs within a directory (including subfolders) to a target destination (flat hierarchy).
My Powershell Script seems super slow :(
Any ideas how to make the fastest approach? Is robocopy a faster solution?
It seems that Robocopy always also creates the folder of the JPG. But I want it flat like
C:\destination\image1.jpg
C:\destination\image2.jpg
C:\destination\image3.jpg
Is it possible that only images are copied that arent already in the target folder?
Get-ChildItem -Path "R:\XXX\*" -Include *.jpg -Recurse | Copy-Item -Destination $targetpath -verbose
I have a PS script which Zips up the previous months logs and names the zip file FILENAME-YYYY-MM.zip
This works
What I now want to do is copy these zip files off to a network share but keeping some of the folder structure. I currently a folder structure similar to the following;
C:\Folder1\
C:\Folder1\Folder2\
C:\Folder1\Folder3\
C:\Folder1\Folder4\Folder5\
There are .zip files in every folder below c:\Folder1
What I want is for the script to copy files from c:\folder1 to \\networkshare but keeping the folder structure, so I should have 3 folders and another subfolder in folder4.
Currently I can only get it to copy the whole structure so I get c:\folder1\... in my \\networkshare
I keep running into issues such as the new folder structure doesn't exist, I can't use the -recurse switch within the Get-ChildItem command etc...
The script I have so far is;
#This returns the date and formats it for you set value after AddMonths to set archive date -1 = last month
$LastWriteMonth = (Get-Date).AddMonths(-3).ToString('MM')
#Set destination for Zip Files
$DestinationLoc = "\\networkshare\LogArchive\$env:computername"
#Source files
$SourceFiles = Get-ChildItem C:\Sourcefiles\*.zip -Recurse | where-object {$_.lastwritetime.month -le $LastWriteMonth}
Copy-Item $SourceFiles -Destination $DestinationLoc\ZipFiles\
Remove-Item $SourceFiles
Sometimes, you just can't (easily) use a "pure PowerShell" solution. This is one of those times, and that's OK.
Robocopy will mirror directory structures, including any empty directories, and select your files (likely faster than a filter with get-childitem will). You can copy anything older than 90 days (about 3 months) like this:
robocopy C:\SourceFiles "\\networkshare\LogArchive\$($env:computername)\ZipFiles" /E /IS /MINAGE:90 *.zip
You can specify an actual date with /MINAGE too, if you have to be that precise.
How about Copy-Item "C:\SourceFiles\" -dest $DestinationLoc\ZipFiles -container -recurse? I have tested this and have found that it copies the folder structure intact. If you only need *.zip files, you first get them, then for each you call Resolve-Path with -Relative flag set and then add the resultant path into Destination parameter.
$oldloc=get-location
Set-Location "C:\SourceFiles\" # required for relative
$SourceFiles = Get-ChildItem C:\Sourcefiles\*.zip -Recurse | where-object {$_.lastwritetime.month -le $LastWriteMonth}
$SourceFiles | % {
$p=Resolve-Path $_.fullname -relative
copy-item $_ -destination "$DestinationLoc\ZipFiles\$p"
}
set-location $oldloc # return back
I know how to do it with different commands but is there a way to make it so copy-item cmdlet also copies directories to the target folder for example if I wanted to copy everything in the C:\users folder including all directories and sub directories is it possible to do with the copy-item command.
You should be able to do it with:
copy-item C:\users -recurse
copy-item C:\users -destination c:\somewhereelse -recurse
The first way assumes you are currently in the destination folder, the second way is explicit.
Is there a way to replicate an xcopy functional using powershell?
I thought it was an easy question until I tried some cmdlets.
Let's imagine I've got a folder structure like:
src
|-a
|-b
There're files in each folder of course. I need to copy contents of Src to some folder Dst.
With xcopy it'd be like this:
xcopy src dst\ /e /y
PS analog would be something like this:
copy-item src dst\ -force -recurse -verbose
Works great... the first time. The second time it creates a subfolder dst\src and puts files there!
I can't figure out any easy workaround. Can you?
p.s. I know I can use xcopy in PS.
copy-item c:\\src\\* c:\\dst -force -recurse -verbose
Here's another workaround I found here:
https://github.com/nightroman/PowerShellTraps/tree/master/Cmdlets/Copy-Item/Inconsistent-destination I've tried in the past to do this myself and would revert back to xcopy. This is "idempotent" and will have the same result the second time.
mkdir $destination -Force
Copy-Item $source\* $destination -Recurse -Force
I have an array of files that need to be moved to a backup locations. I am collecting the array of desired items using a get-childitem command. I am looking to use robocopy to move stuff once the list of collected items is ready.
$paths=#()
$srcitems = get-childitem $paths
robocopy $srcitems $dest /move
Does this work?
If not what is the best way to pipe to each individual item to robocopy?
Thanks
Steeluser
Usage :: ROBOCOPY source destination [file [file]...] [options]
source :: Source Directory (drive:\path or \\server\share\path).
destination :: Destination Dir (drive:\path or \\server\share\path).
file :: File(s) to copy (names/wildcards: default is "*.*").
Robocopy is expecting a source directory, a destination directory, and a file spec as arguments. It's difficult to give a definitive answer without knowing what your "list of collected items" looks like. If it's source directories, then you can foreach that list through a an ivocation of robocopy, and hardcode a wildcard spec for the file names. If you've got a list of files, you'll need to split those off into directory/file (I'd use split-path), and do an invocation of robocopy for each source directory, specifying the list of files in that directory.
Similar scenario, posting in case it helps:
I needed to copy (move) some folders all beginning with "Friday" and items within from a source to a destination, and came up with this that seems to be working:
Get-ChildItem T:\ParentFolder -Filter "Friday*" -Name | ForEach-Object { robocopy "T:\ParentFolder\$_" "E:\$_" /z /s /MOVE }
The "Get-ChildItem" portion lists the folder names (-Name) starting
with "Friday" (-Filter "Friday*").
This gets piped to the ForEach-Object where robocopy will execute for every instance found.
The robocopy /MOVE argument obviously moves the folders/files.
I'm fairly new to Powershell; not sure if there is a better way. The script is still running, but so far so good.
#walid2mi uses Move-Item which I'm sure works; I just like robocopy b/c it has a restartable mode (/Z).
Syntax that worked for me:
$srcPath = "C:\somefolder"
$dstPath = "C:\someOtherFolder"
$srcitems = get-childitem $srcPath #whatever condition
$srcitems | Select Name | ForEach-Object {robocopy $srcPath $dstPath $_.name}
(which is obvious according to the robocopy documentation)
robocopy
Get-ChildItem $paths | Move-Item -Destination $dest -WhatIf