[Powershell]: 2nd Execution of Copy-Item creates subfolder (5.1.17763.1007) - powershell

After searching for a wile I need to post my question here:
I want to do a simple task:
copy-item -path "C:\Folder Copied" -destination "C:\Folder Copied_New" -recurse
Assuming the dir "Folder Copied_New" doenst exist in "C:", PS will create a folder, and copy the folder (and its content) "C:\Folder Copied" to "Folder Copied_New"
HOWEVER, if you execute the command a second time, the following happens:
Powershell created: "C:\Folder Copied_New\Folder Copied" (content "Test.txt" was also copied to this newly created folder...
The 3rd time you execute the command, it ll say that the folder already exists...
So my question:
After I run the command a 2nd time, PS should throw an error, that "Folder Copied_New". How do I do that?
I tried copying and renaming the new folder, using and NOT using "" in the paths, but nothing worked. I do think of using -Testpath, but I thought I ask the community for a simplier (BestPractice) approache.
Thanks in advance for reading and advising!
Well explained in another question but same issue

Not an answer but to long to write in comments.
Can you run following script and show us the output?
$root = "$($env:TEMP)\test"
$source = "$($root)\Logfiles"
$destination = "$($root)\Drawings\Logs"
# Verify folders don't exist yet
if (Test-Path $source) {Throw}
if (Test-Path $destination) {Throw}
# Set up
New-Item $source, $destination -ItemType Directory -Force | Out-Null # Create folders
New-Item "$($source)\testfile" -ItemType File -Force | Out-Null # Create a testfile
# Show files/folders before copy
Write-Output "Before copy"
Get-ChildItem $root -Recurse | select fullname
# Copy first time
Copy-Item -path $source -destination $destination -Recurse -ErrorAction Continue
Write-Output "After first time copy"
Get-ChildItem $root -Recurse | select fullname
# Copy second time
Copy-Item -path $source -destination $destination -Recurse -ErrorAction Continue
Write-Output "After second time copy"
Get-ChildItem $root -Recurse | select fullname
# Copy third time
Copy-Item -path $source -destination $destination -Recurse -ErrorAction Continue
Write-Output "After third time copy"
Get-ChildItem $root -Recurse | select fullname
# Clean up
Remove-Item $source, $destination -Force -Recurse | Out-Null
On my computer, I don't observe any abnormal behavior. The source folder get's copied to destination after the first time. The second run does not alter anything, neither does the third run.

That behavior is the default:
Let's say you want to copy and rename an item, so you are doing this:
Copy-Item -path source.txt -Destination destination.txt
You expect a file named destination.txt with the content of source.txt.
If you want to copy a file but without renaming it you do this:
Copy-Item -path source.txt -Destination C:\test
You expect the file source.txt to apear in C:\test. If C:\test didn't exist it will be created.
Now let's try to copy a folder while the destination does not exist.
Copy-Item -path C:\test -Destination D:\toast
The destination didn't exist so you created it by copying the source folder to the destination. The content of the destination will be the same as the source. The folder D:\toast is the same as C:\test but it got renamed in the process.
However if you provide a destination path where the source object (folder) is going to be located, it will be located in there.
Copy-Item -path C:\test -Destination D:\toast
D:\toast did exist from our previouse action so a copy of C:\test will be created in there: D:\toast\test

Related

Powershell - How to prefix filename into folder for any path containing that file type

Powershell script needed to pull the file basename from a file type within time and date stamped folders on a directory and append those folders with that base name.
The script below works to replace the path name below but I need to prefix the folder. Is it possible to join-path in this way?
Original link for script below
cd C:\Directory
Get-ChildItem *.lsa -File -Recurse | ForEach-Object {
Rename-Item (Split-Path $_ -Parent) ($_.BaseName) -WhatIf
}
Result:
What if: Performing the operation "Rename Directory" on target "Item: C:\Directory\originalpath
Destination: C:\Directory\basename".
What I want is "C:\Directory\basename_originalpath"
Or even better would be "C:\Directory\basename\originalpath"
I think Join-path is the solution but I'm first time scripting and can't link the two commands. I also have to specify the starting directory as the first attempt ran my entire c:\ drive without it.
Its not pretty but I think this would work:
Get-ChildItem *.lsa -File -Recurse | ForEach-Object {
if(-Not (Test-Path -Path "$outputDirectory\$($_.BaseName)")){
New-Item -WhatIf -ItemType Directory -Path "$outputDirectory\$($_.BaseName)"
}
Move-Item (Split-Path $_ -Parent) "$outputDirectory\$($_.BaseName)\$($_.Directory.BaseName)" -WhatIf
}
Updated code.

PowerShell Copy-Item not creating subfolders

I want Copy-Item to copy to the destination file and create any subfolders on the way, but I can't seem to get that to work.
Copy-Item $fullsrc $fulldst -Recurse -Force -Verbose
$fullsrc and $fulldst are full paths with filenames as the destination filename is different from the source filename. Is there a way to get Copy-Item to create the subfolders and then copy the file over?
VERBOSE: Performing the operation "Copy File" on target "Item: D:\mypath\logs\001.123.log
Destination: D:\newpath\newlogs\123.234.log".
Copy-Item : Could not find a part of the path 'D:\newpath\newlogs\123.234.log'.
Copy-item have't function to create a folder, you need to previously create it
Copy-Item $fullsrc $(new-item -ItemType Directory -Path $fulldst) -Recurse -Force -Verbose -ErrorAction SilentlyContinue
You have to create the parent directory of the destination file on your own.
# Split-Path with single parameter outputs the parent directory
$null = New-Item (Split-Path $fulldst) -ItemType Directory
Copy-Item $fullsrc $fulldst -Force -Verbose
Note that -Recurse switch has no use when you specify full source and destination file paths, so I've removed it.

Place files with prefix in folder with number

I have batch changed multiple files that all start with a prefix of a folder where I need them in.
The files are located on another location, like a folder on the desktop.
For example:
101AA0001.dat
101AA0002.dat
102AA0001.dat
102AA0002.dat
The destination folder will for example be:
C:\destfolder\101\ or C:\destfolder\102\
Files starting with 101 need to go in the 101 folder and the files starting with 102 go to folder 102.
I can find some scripts that creates the folder based on the filename. But in this situation the folders already exist. I also know for sure the files don't exist, so I don't have to overwrite files or something.
I guess it is easy for the people that know PowerShell very well, but I don't know how to do this. Can someone please help me? This can save me a lot of time.
I have tried to move the files with the following rule:
Move-Item -Path C:\Users\Username\Desktop\test*.dat -Destination C:\Users\Username\Desktop\test2\ -include "*.dat"
But it copies the whole folder except for the files.
You can do that quite easily with code like below:
$sourceFolder = Join-Path -Path $env:USERPROFILE -ChildPath 'Desktop'
$destination = 'C:\destfolder'
Get-ChildItem -Path $sourceFolder -File -Filter '*.dat' | ForEach-Object {
$targetFolder = Join-Path -Path $destination -ChildPath $_.Name.Substring(0, 3)
# if the target folder does not exist yet, create it
if (!(Test-Path -Path $targetFolder -PathType Container)) {
$null = New-Item -Path $targetFolder -ItemType Directory
}
$_ | Move-Item -Destination $targetFolder -WhatIf
}
The -WhatIf switch shows what would happen in the console without actually performing the move. If you are satisfied with what is output, remove that switch.
This will take all files that end in ".dat" from the $Source folder into a subfolder inside the $DestinationRoot named for the first three characters of the ".dat" file.
$Source = "C:\Users\Username\Desktop"
$DestinationRoot = "C:\Users\Username\Desktop\test2"
$Filelist = Get-ChildItem -Path $Source -Filter "*.dat" -File
foreach ($File in $Filelist){ $DestinationFolder = $File.Name.Substring(0,3)
$FinalPath = "$DestinationRoot\$DestinationFolder"
Move-Item -Path $File.Fullname -Destination $FinalPath -Whatif }
Remove the -Whatif when you're ready to run it for real.
This doesn't handle folder creation and should error out if the file already exists in the target location so it won't accidentally overwrite anything.

Copy-Item when destination folder exists or doesn't

When destination folder exists the right way of copying files is defined here
Copy-Item 'C:\Source\*' 'C:\Destination' -Recurse -Force
If destination folder doesn't exist, some files in the source subfolders are copied straight into destination, without keeping original folder structure.
Is there a way to have a single Copy-Item command to address both cases and persist folder structure? Or is it too much to ask from Powershell?
You may want to use a if statement with test-path
this is the script i used to fix this problem
$ValidPath = Test-Path -Path c:\temp
If ($ValidPath -eq $False){
New-Item -Path "c:\temp" -ItemType directory
Copy-Item -Path "c:\temp" -Destination "c:\temp2" -force
}
Else {
Copy-Item -Path "c:\temp" -Destination "c:\temp2" -force
}

How to prevent creating additional folder if destination folder exists while copying file using powershell

I am trying to copy a folder from the local computer to a remote server. It works but if the destination folder already exists it is creating a duplicate folder inside it.
copy-item -Path C:\test -Destination \\server\F$\testpassed -recurse -Force
To copy only the files from within C:\test to the \\server\F$\testpassed folder you need to use the following command:
Copy-Item -Path C:\test\* -Destination \\server\F$\testpassed -Recurse
\* is a wildcard for anything within the folder, and will cause Copy-Item to copy anything within the folder to the Destination. You could also use *.txt to only copy txt files if you wanted only a specific file type to be copied.
EDIT:
I would test for the presence of $TARGETDIR and then create it if needed. This way you only have a single copy command.
$TargetDir = "\\server\F$\testpassed"
$SourceDir = "C:\test"
if(!(Test-Path -Path $TARGETDIR)) {New-Item -Path $TARGETDIR -ItemType Directory}
Copy-Item -Path "$SourceDir\*" -Destination $TARGETDIR -Recurse
Using source path in below way will solve your issue
Copy-Item -Path C:\test*
Try
$Source = Get-childitem C:\test -Recurse
copy-item -Path $Source.FullName -Destination C:\temp -recurse -Force
Use GC to stop getting the folder as well as the contents.