How to overwrite files with Copy-Item in PowerShell - powershell

I am trying to copy content of a folder, but there are two files which I would like to exclude. The rest of all the content should be copied to a new location and existing content on that new location should be overwritten.
This is my script. It works fine if my destination folder is empty, but if I have files and folder, it doesn't overwrite them.
$copyAdmin = $unzipAdmin + "/Content/*"
$exclude = #('Web.config','Deploy')
Copy-Item -Path $copyAdmin -Destination $AdminPath -Exclude $exclude -Recurse -force

As I understand Copy-Item -Exclude then you are doing it correct. What I usually do, get 1'st, and then do after, so what about using Get-Item as in
Get-Item -Path $copyAdmin -Exclude $exclude |
Copy-Item -Path $copyAdmin -Destination $AdminPath -Recurse -force

Robocopy is designed for reliable copying with many copy options, file selection restart, etc.
/xf to excludes files and /e for subdirectories:
robocopy $copyAdmin $AdminPath /e /xf "web.config" "Deploy"

How about calling the .NET Framework methods?
You can do ANYTHING with them... :
[System.IO.File]::Copy($src, $dest, $true);
The $true argument makes it overwrite.

Related

Powershell copy file/folder based on keyword

I want to copy folder which match with the keyword. however i want powershell read the keyword from starting point. i added my script below
if any folder name contain test at the start, script will copy the folder. but it's coping all folder even if "Test" keyword is available in the middle name. like if there is two folder
"This.is.a.Test.Folder"
"Test.this.is.a.Folder"
I want powershell copy only "Test.this.is.a.Folder"
any help please
$dest = "D:\2";
$include= #("*Test*")
Get-ChildItem $source -recurse -Force -Verbose -include $include | copy-Item -Destination {Join-Path $dest $_.FullName.Substring($source.length)}```
Your wildcard is meant to capture anything that contains the word Test in this case.
If you want to specifically start with the word Test followed by anything: Test*
Contrary, anything that ends with the word Test would be: *Test
$include = #( "Test*" )
Get-ChildItem $source -Include $include -Recurse -Force -Verbose |
Copy-Item -Destination {
Join-Path $dest -ChildPath $_.FullName.Substring($source.length)
}
Note, that you can use -File to filter only files and -Directory to filter only folders.

Powershell script to copy folder structure and specific file types

I have the following script to copy the folder structure (including empty folders) and specific file types into another directory. However, the issue is that the script copies all files instead of just the .dat and .py files even though I'm using the -Include switch. How to fix this so that it only copies the desired file types
$sourceDir = "C:\User\001"
$targetDir = "C:\User\002"
Get-ChildItem -Path $sourceDir | Copy-Item -Destination $targetDir -Recurse -Include '*.dat', '*.py' -Container
As #Lee_Dailey pointed out, it's probably best to use robocopy for this:
robocopy $sourceDir $targetDir *.dat *.py /e
Yes, this is tricky. You should look up the documentation for the -Include parameter
The Include parameter is effective only when the command includes the contents of an item, such as C:\Windows*, where the wildcard character specifies the contents of the C:\Windows directory.
You could make it work like this:
Copy-Item $sourceDir\* -Destination $targetDir -Recurse -Include '*.dat', '*.py'
-Container is true by default, so you can safely omit it.
Note that you can always use the -WhatIf switch to check if you command will actually do what you want.
You could make it work like this:
i use -Filter
Specifies a filter to qualify the Path parameter. The FileSystem
provider is the only installed PowerShell provider that supports the
use of filters. You can find the syntax for the FileSystem filter
language in about_Wildcards. Filters are more efficient than other
parameters, because the provider applies them when the cmdlet gets the
objects rather than having PowerShell filter the objects after they're
retrieved.
#('*.dat', '*.py') | %{Copy-Item -Path $sourceDir -Destination $targetDir -Recurse -Filter $_ -Force}
or
Copy-Item -Path $sourceDir -Destination $targetDir -Recurse -Filter '*.dat' -Force
Copy-Item -Path $sourceDir -Destination $targetDir -Recurse -Filter '*.py' -Force
it should work but
The Include parameter is effective only when the command includes the
contents of an item, such as C:\Windows*, where the wildcard character
specifies the contents of the C:\Windows directory.
Copy-Item -Destination $targetDir -Recurse -Include '*.dat', '*.py'
may find it easier to include files that can be excluded
Copy-Item -Destination $targetDir -Recurse -Exclude'*.da1', '*.xxx

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.

Copy folder structure and content of specific folders

So I've found xcopy super helpful to copy entire folder structures. But I also need to copy the contents of specific folders into the new directories as well.
For example:
1. C:\OriginalDir
- \This
* \Test
- \That
* \Test
- \Other
I can use: xcopy C:\OriginalDir C:\TempDir /e /t to copy the entire structure of the C:\OriginalDir. However, I also need to copy the contents of both \Test folders into the new directory as well. I'm fairly new to xcopy and I've also looked into robocopy. Is there a way to do this? I'm trying to accomplish this in powershell and thought about iterating through the folder structure, but that still doesn't store the parent folder structure when I finally reach the Test folder.
Thanks.
Have you tried robocopy - for example:
$source = "C:\Your\Source\Directory"
$dest = "C:\Your\Destination\Directory"
robocopy $source $dest /e
The 'e' switch will copy subdirectories and their contents (including empty subdirectories).
If you wanted to exclude the \Other directory (it's not entirely clear from your question), you could do the following:
robocopy $source $dest /e /xf *
(This just copies the directory structure with no files copied)
robocopy $source $dest /XD C:\Other /e
(This copies files, but excludes the named directories)
You can find more information here:
https://technet.microsoft.com/en-GB/library/cc733145.aspx
Edit:
In order to only copy directories beginning with 'Test', you could do the following:
$exclude = gci C:\OriginalDir -ad | ?{ $_.Name -notlike 'Test*'
robocopy $source $dest /XD $exclude /e
If your folder structure is more than one level deept, you could use the -recurse switch on Get-Childitem
Thanks to Steve for getting me started and getting me thinking about this correctly. Ended up scripting it out manually without using RoboCopy or Xcopy as I could not get them to work exactly how I wanted to.
$target = "C:\\TestTemp"
foreach($item in (Get-ChildItem "C:\\OriginalDir\\This" -Recurse)){
if ($item.PSIsContainer -and ($item.Name -eq "obj" -or $item.Name -eq "bin")){
$tempPath = $target
$path = $item.FullName
$trimmed = $path.TrimStart("C:\\OriginalDir")
$pieces = $trimmed.Split("\\");
foreach($piece in $pieces){
$tempPath = "$tempPath\$piece"
New-Item -ItemType Directory -Force -Path "$tempPath"
if($piece -eq "Test" -or $piece -eq "Temp"){
Copy-Item -path $path\** -Destination $tempPath -Recurse -force
}
}
}
}

Copy file with relative path

I would like to copy all files of a certain type from a certain sub-directory with their relative path from that sub-directory to another directory with the relative path intact. e.g.:
Source sub-dir:
c:\temp\sourcedirectory
Source files:
c:\temp\sourcedirectory\tonymontana\fileOne.txt
c:\temp\sourcedirectory\poker\fileTwo.txt
Target dir:
c:\temp\targetdirectory
Desired result:
c:\temp\targetdirectory\tonymontana\fileOne.txt
c:\temp\targetdirectory\poker\fileTwo.txt
So far I've come up with:
Set-Location $srcRoot
Get-ChildItem -Path $srcRoot -Filter $filePattern -Recurse |
Resolve-Path -Relative |
Copy-Item -Destination {Join-Path $buildroot $_.FullName}
However, this "everything is an object" à la PowerShell is beating me down (at least that's what I suspect). I.e. the files gets copied, but without their relative path.
Anyone who could enlighten me a bit?
Don't bother with PowerShell cmdlets for this, simply use robocopy:
robocopy C:\temp\sourcedirectory C:\temp\targetdirectory *.txt /s
You can try this:
$srcroot = "c:\temp\sourcedirectory"
$builroot= "c:\temp\targetdirectory"
gci -path $srcroot -filter $filepattern -recurse |
% { Copy-Item $_.FullName -destination ($_.FullName -replace [regex]::escape($srcroot),$builroot) }
Try this:
Copy-item $srcRoot -destination $destination -recurse
To prevent copying the folder itself i.e. creating
c:\temp\targetdirectory\sourcedirectory
Change into the source folder, then use a wildcard instead of the folder as the source:
cd C:\temp\sourcedirectory\
Copy-item * -destination c:\temp\targetdirectory -recurse`