I'm writing a script which archives files for analysis. My issue is that the file names aren't unique over multiple folders so they are being over written.
For instance:
C:\StuffToCopy\Folder1\myFile1.txt
C:\StuffToCopy\Folder1\myFile2.txt
C:\StuffToCopy\Folder2\myFile1.txt
C:\StuffToCopy\Folder2\myFile2.txt
At the end of my copy process I'm only getting 2 files, but I want 4.
I'd like the output to be like this:
C:\ArchiveCopy\Folder1_myFile1.txt
C:\ArchiveCopy\Folder1_myFile2.txt
C:\ArchiveCopy\Folder2_myFile1.txt
C:\ArchiveCopy\Folder2_myFile2.txt
Here's my script so far.
$files = dir -r -path "C:\StuffToCopy\" -i *.*
foreach ($file in $files)
{
if ($file.LastWriteTime -gt (get-date).AddDays(-1)) {
copy -path $file C:\ArchiveCopy\
}
}
I want to do something like copy -path $file.FolderName & '_' & $file C:\ArchiveCopy\
I'm just not sure how to do it.
Use Split-Path Cmdlet to Get the Parent's Parent Directory in PowerShell. The Split-Path cmdlet displays the specified part of a path. It can be a parent folder, subfolder, file name, or file extension. The default is to return the parent folder of the specified path.
PowerShell utilizes the “Get-ChildItem” command for listing files of a directory. The “dir” in the Windows command prompt and “Get-ChildItem” in PowerShell perform the same function.
Description. The Get-ChildItem cmdlet gets the items in one or more specified locations. If the item is a container, it gets the items inside the container, known as child items. You can use the Recurse parameter to get items in all child containers and use the Depth parameter to limit the number of levels to recurse.
The Split-Path cmdlet returns only the specified part of a path, such as the parent folder, a subfolder, or a file name. It can also get items that are referenced by the split path and tell whether the path is relative or absolute. You can use this cmdlet to get or submit only a selected part of a path.
If $file
is really a file – an instance of System.IO.FileInfo
(and not really a directory: System.IO.DirectoryInfo
) then it has property Directory
which is an instance of DirectoryInfo
which has a Name
:
$file |
copy-item -destination {
Join-Path C:\ArchiveCopy\ -childpath ($_.Directory.Name + "_" + $_.Name) }
(Using a pipeline to start because the -LiteralPath
parameter of Copy-Item
will bind to the PSPath
property from the pipeline, so no need to pull the original file's name from the $file
object.)
If $file
might be a directory, then you need to do more of the work yourself, but probably easier to filter out directories first:
dir -r -path C:\StuffToCopy\ |
where { -not $_.PSIsContainer } |
copy-item -destination {
Join-Path C:\ArchiveCopy\ -childpath ($_.Directory.Name + "_" + $_.Name) }
Note:
-i "*.*"
: this is the default anyway (and if you need to filter files on a wildcard pattern prefer the -filter pattern
parameter: the filter is passed to the filesystem rather than creating .NET objects and then filtering them which is much slower if there are a lot of files).Try this:
dir -r -path C:\StuffToCopy |
where {!$_.psiscontainer} |
copy -dest { "C:\ArchiveCopy\$($_.Directory.Name)_$($_.Name)"}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With