How to copy files and folders with an already existing folder? - powershell

I have created a script to copy the folder/sub folders/files from a specific location to a list of servers that I specified on a notepad.
It checks that if the folder has not been created, it will create it and copy over the files, but if the folder has already been created - then it stops.
However, I would like to still copy over newer files even if that folder has already been created, albeit with no subfolders or files in there.
My current code
[String] $KfxComputers = "C:\temp\Kofax Apps\servers.txt"
# This file contains the list of servers you want to copy files/folders to
$computers = get-content -Path $KfxComputers
# the folder you want to copy to the servers in the $computer variable
$sourceRoot = #("\\wdevkofx110\Kofax Software\Oracle Clients",
"\\wdevkofx110\Kofax Software\Kofax Capture 11")
# the destination location you want the file/folder(s) to be copied to
$destinationRoot = "C$\temp"
foreach ($computer in $computers) {
$testpath = Test-Path -Path \\$computer\$destinationRoot
if (!$testpath)
{
Write-Host "creating folder and copying files..." -ForegroundColor green
New-Item -ItemType Directory -Force -Path "\\$computer\$destinationRoot"
copy-item -Path $sourceRoot -Recurse -Destination
"\\$computer\$destinationRoot" -Container
} else {
Write-Host "$computer\$destinationRoot folder already exists"
}
}`

You can use Else IF
[String] $KfxComputers = "C:\temp\Kofax Apps\servers.txt"
# This file contains the list of servers you want to copy files/folders to
$computers = get-content -Path $KfxComputers
# the folder you want to copy to the servers in the $computer variable
$sourceRoot = #("\\wdevkofx110\Kofax Software\Oracle Clients",
"\\wdevkofx110\Kofax Software\Kofax Capture 11")
# the destination location you want the file/folder(s) to be copied to
$destinationRoot = "C$\temp"
foreach ($computer in $computers) {
$testpath = Test-Path -Path \\$computer\$destinationRoot
if (!$testpath)
{
Write-Host "creating folder and copying files..." -ForegroundColor green
New-Item -ItemType Directory -Force -Path "\\$computer\$destinationRoot"
copy-item -Path $sourceRoot -Destination
"\\$computer\$destinationRoot" -Container -Recurse -force
}
ElseIF ($testpath) {
Write-Host "folder already exists, copying files..." -ForegroundColor green
copy-item -Path $sourceRoot -Destination
"\\$computer\$destinationRoot" -Container -Recurse -force
}
else {
Write-Host "$computer\$destinationRoot folder already exists"
}
}`

Related

copy multiple files from yesterday to specific folder powershell script

I am trying to copy all files changed/created yesterday from a certain folder to another certain folder. It writes errors and also does not paste the files into the folder.
Here is the script:
$DestinationFolder = "D:\Dropbox\Public\Download\New folder"
If(!(test-path $DestinationFolder))
{
New-Item -ItemType Directory -Force -Path $DestinationFolder
}
$EarliestModifiedTime = (Get-date).AddDays(-1).ToString("MM/dd/yyyy")
$Files = Get-ChildItem "C:\Users\Harel Gordon\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets\" -File
foreach ($File in $Files)
{
if ($File.LastWriteTime.ToString("MM/dd/yyyy") -eq $EarliestModifiedTime)
{
Copy-Item $File -Destination $DestinationFolder
Write-Host "Copying $File"
}
else
{
Write-Host "Not copying $File"
}
}
Read-Host -Prompt "Press Enter to exit"
These are the errors:
enter image description here
It worked for a while then stopped. do not know why

Create Folders and Moving Files in Powershell

I've seen similar questions and used them as a basis for what i'm trying to do here. I have a folder with many files that are named like "Author Name - Book Title.azw".
I'd like to create sub-folders for each author and move all their books into that folder. This is the script i have so far. It successfully creates folder for the Authors, but it chokes on the move-item, says Could not find a part of the path.
$files = Get-ChildItem -file
foreach ($file in $files){
$title = $file.ToString().Split('-')
$author = $title[0]
if (!(Test-Path $author))
{
Write-Output "Creating Folder $author"
New-Item -ItemType Directory -Force -Path $author
}
Write-Output "Moving $file to $author"
Move-Item -Path $file -Destination $author -Force
}
You have to use this:
Get-ChildItem -file | foreach {
$title = $_.ToString().Split('-')
$author = $title[0]
if (!(Test-Path $author))
{
Write-Host "Creating Folder $($author)"
New-Item -ItemType Directory -Force -Path "$author"
}
Write-Host "Moving $($_) to $($author)"
Move-Item -Path "$_" -Destination "$author" -Force
}
You must surround file paths in double quotes. So your code was not working.
From my understanding, you want to move files in a directory to sub folders where the author names are used as the sub folder names. You can try this solution to achieve this.
# Folder which contains files
$Path = "PATH_TO_FILES"
# Make sure path is a directory
if (Test-Path $Path -PathType Container) {
# Go through each file in folder
Get-ChildItem -Path $Path | ForEach-Object {
# Get full path of file
$filePath = $_.FullName
# Extract author
$author = $_.BaseName.Split("-")[0].Trim()
# Create subfolder if it doesn't exist
$subFolderPath = Join-Path -Path $Path -ChildPath $author
if (-not (Test-Path -Path $subFolderPath -PathType Container)) {
New-Item -Path $subFolderPath -ItemType Directory
}
# Move file to subfolder
Move-Item -Path $filePath -Destination $subFolderPath
}
}

Merge two directories keeping any files with same name

I am looking for some help to create a PowerShell script to merge or copy one directory to another that the destination directory has files with the same name as the source.
I need to keep both, the script can append a number to the source file if it has a file of duplicate name in the destination.
Here is a sample script that deals with one file, but I need to set a directory and let it loose recursively on the entire directory.
$SourceFile = "C:\Temp\File.txt"
$DestinationFile = "C:\Temp\NonexistentDirectory\File.txt"
if ((Test-Path $DestinationFile) -eq $false) {
New-Item -ItemType File -Path $DestinationFile -Force
}
Copy-Item -Path $SourceFile -Destination $DestinationFile
try this
$SourceDir = "C:\Temp"
$DestinationDir = "C:\Temp2\NonexistentDirectory"
#create dir if not exists (dont remove if exist)
New-Item -ItemType Directory -Path $DestinationDir -Force
#get list files destination dir
$DestinationFiles=gci $DestinationDir -File
#loop on file source and create newname for copy while name exist already
gci $SourceDir -File | %{
$counter=0
$name=$_.Name
while ($name -in $DestinationFiles.Name)
{
$counter++;
$name="{0}_{1:d6}{2}" -f $_.BaseName, $counter, $_.Extension
}
Copy-Item -Path $_.FullName -Destination "$DestinationDir\$name"
}

Powershell copy folders and files and re-create parent folder as sub folder

I created simple powershell script to copy files and folders from one location to many location in share computers, this work well but we have to run this script one time every week to copy and over write existen content
The problem is the script next time run create the parents folder inside same parent agian as sub folder for exampel:
Folder1 copied (Next time script run or if the folder exist) this look like
Folder1\folder1
as you can see in the pics this copy correctly the folder and content but if the folder exist or this will create new sub folder in the same folder with the same name
Here is copy of the script to be reviewd.
Clear-Host
#source path
$sourceDir = '\\source\Users\asdew\Desktop\dep'
#Array with Sites Path
$targetDir = #(
#Sites in pc1
'\\Apc20\Users\afded\Desktop\site01',
#Sites in pc2
'\\Apc10\Users\adsed\Desktop\site02'
)
$i=0
Foreach ($dest in $targetDir){
Get-ChildItem $sourceDir -Recurse | % {
$dest = $targetDir[$i] + $_.FullName.SubString($sourceDir.Length)
If (!($dest.Contains('.')) -and !(Test-Path $dest))
{
mkdir $dest
}
#Copy Files and over write existen files.
Write-Host "copy start. Please wait..We are copying your files.." -ForegroundColor DarkYellow
Copy-Item $_.FullName -Destination $dest -Force -PassThru -ErrorAction SilentlyContinue
If(-not $?)
{Write-Warning "Your copy Failed!!" -InformationAction}
else
{Write-Host "Your copy was Success!" -ForegroundColor Green}
}
$i = $i+1
}
I hope some one can help me to resolve this issue.
Regards
I think Copy-Item should do all the job. Try the following code
Clear-Host
#source path
$sourceDir = '\\source\Users\asdew\Desktop\dep'
#Array with Sites Path
$targetDir = #(
#Sites in pc1
'\\Apc20\Users\afded\Desktop\site01',
#Sites in pc2
'\\Apc10\Users\adsed\Desktop\site02'
)
Foreach ($dest in $targetDir){
Get-ChildItem $sourceDir | Copy-Item -Recurse -Destination $dest -ErrorAction Continue -Force
}

Copy items from Source to Destination if they don't already exist

I have a pretty basic powershell copy script that copies items from a source folder to a destination folder. However this is moving way too much data, and I'd like to check if the filename already exists so that file can be ignored. I don't need this as complex as verifying created date/checksum/etc.
Currently it's along the lines of:
Copy-Item source destination -recurse
Copy-Item source2 destination2 -recurse
I'd imagine I need to add the Test-Path cmdlet, but I'm uncertain how to implement it.
You could always call ROBOCOPY from PowerShell for this.
Use the /xc (exclude changed) /xn (exclude newer) and /xo (exclude older) flags:
robocopy /xc /xn /xo source destination
This will ONLY copy those files that are not in the destination folder.
For more option type robocopy /?
$exclude = Get-ChildItem -recurse $dest
Copy-Item -Recurse $file $dest -Verbose -Exclude $exclude
While I agree that Robocopy is the best tool for something like this, I'm all for giving the customer what they asked for and it was an interesting PowerShell exercise.
This script should do just what you asked for: copy a file from Source to Destination only if it does not already exist in the Destination with a minimum of frills. Since you had the -recurse option in your example, that made for a bit more coding than just simply testing for the filename in the Destination folder.
$Source = "C:\SourceFolder"
$Destination = "C:\DestinationFolder"
Get-ChildItem $Source -Recurse | ForEach {
$ModifiedDestination = $($_.FullName).Replace("$Source","$Destination")
If ((Test-Path $ModifiedDestination) -eq $False) {
Copy-Item $_.FullName $ModifiedDestination
}
}
Building off of Wai Ha Lee's post, here's an example that worked for me:
$Source = "<your path here>"
$Dest = "<your path here>"
$Exclude = Get-ChildItem -recurse $Dest
Get-ChildItem $Source -Recurse -Filter "*.pdf" | Copy-Item -Destination $Dest -Verbose -Exclude $Exclude
This builds a list to exclude, then copies any pdf in the source directory and sub-directories to the destination in a single folder...excluding the existing files. Again, this is an example from my needs, but similar to yours. Should be easy enough to tweak to your hearts content.
Function Copy-IfNotPresent will accept one file at a time but it's easy to loop for all files you want to copy. Here's an example:
gci c:\temp\1\*.* -Recurse -File | % { Copy-IfNotPresent -FilePath $_ -Destination "C:\temp\2\$(Resolve-Path $_ -relative)" -Verbose }
Here's the function. It will generate the folder tree if necessary. Here's the gists link: https://gist.github.com/pollusb/cd47b4afeda8edbf8943a8808c880eb8
Function Copy-IfNotPresent {
<#
Copy file only if not present at destination.
This is a one file at a time call. It's not meant to replace complex call like ROBOCOPY.
Destination can be a file or folder. If it's a folder, you can use -Container to force Folder creation when not exists
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory)]
$FilePath,
[Parameter(Mandatory)]
[string]$Destination,
[switch]$Container,
[switch]$WhatIf
)
#region validations
if ($FilePath -isnot [System.IO.FileInfo]){
$File = Get-ChildItem $FilePath -File
} else {
$File = $FilePath
}
if (!$File.Count){
Write-Warning "$FilePath no file found."
return
} elseif ($File.Count -gt 1) {
Write-Warning "$FilePath must resolve to one file only."
return
}
#endregion
# Destination is a folder
if ($Container -or (Test-Path -Path $Destination -PathType Container)) {
if (!(Test-Path $Destination)) {
New-Item -Path $Destination -ItemType Container | Out-Null
}
$Destination += "\$($File.Name)"
}
# Destination is a file
if (!(Test-Path $Destination)) {
if ($WhatIf) {
Write-Host "WhatIf:Copy-IfNotPresent $FilePath -> $Destination"
} else {
# Force creation of parent folder
$Parent = Split-Path $Destination -Parent
if (!(Test-Path $Parent)) {
New-Item $Parent -ItemType Container | Out-Null
}
Copy-Item -Path $FilePath -Destination $Destination
Write-Verbose "Copy-IfNotPresent $FilePath -> $Destination (is absent) copying"
}
} else {
Write-Verbose "Copy-IfNotPresent $Destination (is present) not copying"
}
}
$source = "c:\source"
$destination = "c:\destination"
Create a list of files to exclude, i.e. files already existing in the destination.
$exclude = Get-Childitem -Recurse $destination | ForEach-Object { $_.FullName -replace [Regex]::Escape($destination ), "" }
Recursively copy all contents from the source to the destination excluding the previously collected files.
Copy-Item -Recurse -Path (Join-Path $source "*") -Destination $destination -Exclude $exclude -Force -Verbose
(Join-Path $source "*") add a wildcard at end ensuring that you get the children of the source folder instead of the source folder itself.
Force is used because I don't mind that there are already existing folders (results in error messages). Use with caution.
ForEach-Object { $_.FullName -replace [Regex]::Escape($destination ), "" } transforms the existing file full names into values which can be used as Exclude parameter
Here is a recursive script that syncronizes 2 folders ignoring existing files:
function Copy-FilesAndFolders([string]$folderFrom, [string]$folderTo) {
$itensFrom = Get-ChildItem $folderFrom
foreach ($i in $itensFrom)
{
if ($i.PSIsContainer)
{
$subFolderFrom = $folderFrom + "\" + $i.BaseName
$subFolderTo = $folderTo + "\" + $i.BaseName
Copy-FilesAndFolders $subFolderFrom $subFolderTo | Out-Null
}
else
{
$from = $folderFrom + "\" + $i.Name
$to = $folderTo + "\" + $i.Name
if (!(Test-Path $from)) # only copies non-existing files
{
if (!(Test-Path $folderTo)) # if folder doesn't exist, creates it
{
New-Item -ItemType "directory" -Path $folderTo
}
Copy-Item $from $folderTo
}
}
}
}
To call it:
Copy-FilesAndFolders "C:\FromFolder" "C:\ToFolder"
Lots of great answers in here, here's my contribution as it relates to keeping an mp3 player in sync with a music library.
#Tom Hubbard, 10-19-2021
#Copy only new music to mp3 player, saves time by only copying items that don't exist on the destination.
#Leaving the hardcoded directories and paths in here, sometimes too much variable substitution is confusing for newer PS users.
#Gets all of the albums in the source directory such as your music library
$albumsInLibrary = gci -Directory -path "C:\users\tom\OneDrive\Music" | select -ExpandProperty Name
#Gets all of the albums of your destination folder, such as your mp3 player
$albumsOnPlayer = gci -Directory -Path "e:\" | select -ExpandProperty name
#For illustration, it will list the differences between the music library and the music player.
Compare-Object -DifferenceObject $albumsInLibrary -ReferenceObject $albumsOnPlayer
#Loop through each album in the library
foreach ($album in $albumsInLibrary)
{
#Check to see if the music player contains this directory from the music library
if ($albumsOnPlayer -notcontains $album)
{
#If the album doesn't exist on the music player, copy it and it's child items from the library to the player
write-host "$album is not on music player, copying to music player" -ForegroundColor Cyan
Copy-Item -path "C:\users\Tom\OneDrive\music\$album" -Recurse -Destination e:\$album
}
}