Recursively compare file contents from two folders, archive if different, then copy - powershell

I have been asked to put together this utility in a hurry which will compare files in source/destination folders, check if different, and if so, archive the file in destination via renaming and copy the source file over. I dug around some of the commands and looked at things like Compare-Object -Recursive, however I'm not sure if this is the correct command. This is my progress so far:
get-childitem -recurse $source | Where-Object {$_.Name -eq (Get-ChildItem -recurse $destination)} | Copy-Item -recurse -path "$source\*" -destination $destination -force
But I don't think this is correct. Would greatly appreciate being pointed in the right direction here.

This is an example how you can compare with the compare command.
$items1 = Get-ChildItem -Path C:\temp -Recurse
$items2 = Get-ChildItem -Path C:\temp2 -Recurse
$diffent = Compare-Object -ReferenceObject $items1 -DifferenceObject $items2
foreach($item in $diffent){
$path = $item.InputObject.FullName
#copy the item with the path in the variable $path
}

Related

Powershell Loop through folder move file, create directory if doesn't exist

Good Afternoon,
I apologize if this is a basic question, but I have been struggling with it, also still very new to Powershell.
I have a network mapped folder Z:\Test.
Under Z:\Test is multiple subfolders with the same structure. I need to loop through all of the subfolders and move all PDF files if they exist in a specific location.
Z:\Test\1\Work\PDF\*.PDF - then move
Z:\Test\2\Work\PDF\*.PDF - Move So on and so on.
I have tried the following, but like I said I have been struggling with it. Thanks any help
Get-ChildItem -Path Z:\temp\*\Work -File -Include "*.PDF" -Recurse | Copy-Item -Force -Destination Y:\Temp\*\Work
I would try something like this:
$files = Get-ChildItem -Path Z:\Temp\*\Work -File -Include "*.PDF" -Recurse
foreach ($file in $files) {
Copy-Item -Path $file.FullName -Destination Y:\Temp\*\Work -Force
}

powershell copy all folder structure and exclude one or more folders

I'm trying to use PowerShell to copy a folder with sub-folders from our users to a small backup. These folders contain a folder called "windows" I don't want to copy.
I have tried "exclude" but can't seem to get it to work.
This is the script so far:
Copy-Item "E:\Curos folder" -Exclude 'Windows' -Destination "E:\Curos folder backup" -Recurse -Verbose
I have read other posts but don't quiet understand how it works
It's my first time working with PowerShell
You are complete right.
Actually the script it's simpler than the one I have wrote before.
Here we go:
$source = "C:\Users\gaston.gonzalez\Documents\02_Scripts"
$destination = "D:\To Delete"
$exclude = "Windows"
$folders = Get-ChildItem -Path $source | Where {($_.PSIsContainer) -and ($exclude -notcontains $_.Name)}
foreach ($f in $folders){
Write-Host "This folders will be copied: $f"
Copy-Item -Path $source\$f -Destination $destination\$f -Recurse -Force
}
I'd use something like this:
Get-ChildItem $root -Directory -Recurse | % {$_.name -ne 'Windows'} | foreach {Copy-Item "$($_.FullName)" -Destination $dest -Recurse}
I haven't tested it but it's the skeleton of something you should be able to make work, although I don't find the point of using recurse on both, Get-ChildItem and Copy-Item my advice is to use it on Get-ChildItem.

Copy all files and folders from a source folder to multiple folders with a specic name

I have a source folder(c:\test*) and I want that folder copied to all folders in the same location (c:\resultaat) but only to the folders in that location that contains the name demo_profit.
I think I'm almost there, but I'm missing a small part I think.
$destination = get-item -include demo_profit* -path C:\resultaat\*
copy-item C:\test\* $destination -recurse -force
thanks for your help
The -Directory parameter of Get-ChildItem requires AFAIK PSv5
Get-ChildItem -Directory -Path 'C:\resultaat\' | ForEach-Object{
if (Test-Path (Join-Path $_.FullName 'demo_profit')){
Copy-Item C:\test\* $_.FullName -recurse -force
}
So it is not clear if you want to copy the files to a folder containing an item named demo_profit, or to folder with demo_profit in the name. The second is simple, so I'll start there:
Get-ChildItem C:\resultaat\* -Directory |
Where{$_.Name -match 'demo_profit'} |
ForEach{ Copy-Item C:\test\* -dest $_.FullName -recurse -force }
That finds any folder within c:\resultaat that has 'demo_profit' as part of its name, and copies the desired files/folders into that folder. Example: C:\resultaat\Folder1_demo_profit would have all the files from C:\temp copied into it.
If you are looking for things named demo_profit, and want to copy the files into the same folder as that item you need to use the PSParentPath property, and some wildcards.
Get-ChildItem c:\resultaat\*\*demo_profit*
This command would find a file or folder with a path such as 'C:\resultaat\Amazon\az_demo_profit'. Then to copy files into the folder containing that you would use the PSParentPath property as such:
Get-ChildItem c:\resultaat\*\*demo_profit* |
Select -Expand PSParentPath -Unique
ForEach{ Copy-Item C:\test\* -dest $_ -recurse -force }

I get errors when trying to rename files

I have files in a folder C:\Users\xxx\Documents\Projects\files\old\. I have built a loop to rename them but it doesn't work out:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName $newfiles+"$($entry.Custom_ID).$($file.BaseName).PDF"
How do I concatenate properly $newfiles to the rename path? I tried everything but keep getting errors:
Rename-Item : A positional parameter cannot be found that accepts argument '-'
you need to either copy and rename or move and rename files.using -whatif is a good practise because it shows you what is going to happen if you execute a particular command.
Notice also i am using a filter to get-childitem to only get the pdf files so that i know that the files i am going to rename will only be pdf files. of course if the oldfiles folder only contains pdf files then you dont need to use the filter.
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
$oldfiles = "C:\Users\xxx\Documents\Projects\files\old\"
Get-ChildItem -Path $oldfiles -Filter *.pdf |
Move-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
or
Get-ChildItem -Path $oldfiles -Filter *.pdf |
copy-Item -Destination {Join-Path -Path $newfiles -ChildPath "$($entry.Custom_ID).$($_.BaseName).pdf"} -WhatIf
This is how I always concatenate things in Powershell:
$newfiles = "C:\Users\xxx\Documents\Projects\files\new\"
Rename-Item -Path $file.FullName -NewName ("{0}{1}.PDF" -f $newfiles,$($entry.Custom_ID).$($file.BaseName))
From experience, this always works.

Need a script to publish build output to a staging server

I am trying to write a PowerShell script that will copy a subset of files from a source folder and place them into a target folder. I've been playing with "copy-item" and "remove-item" for half a day and cannot get the desired or consistent results.
For example, when I run the following cmdlet multiple times, the files end up in different locations?!?!:
copy-item -Path $sourcePath -Destination $destinationPath -Include *.dll -Container -Force -Recurse
I've been trying every combination of options and commands I can think of but can't find the right solution. Since I'm sure that I'm not doing anything atypical, I'm hoping someone can ease my pain and provide me with the proper syntax to use.
The source folder will contain a large number of files with various extensions. For example, all of the following are possible:
.dll
.dll.config
.exe
.exe.config
.lastcodeanalysisissucceeded
.pdb
.Test.dll
.vshost.exe
.xml
and so on
The script needs to only copy .exe, .dll and .exe.config files excluding any .test.dll and .vshost.exe files. I also need the script to create the target folders if they don't already exist.
Any help getting me going is appreciated.
try:
$source = "C:\a\*"
$dest = "C:\b"
dir $source -include *.exe,*.dll,*.exe.config -exclude *.test.dll,*.vshost.exe -Recurse |
% {
$sp = $_.fullName.replace($sourcePath.replace('\*',''), $destPath)
if (!(Test-Path -path (split-path $sp)))
{
New-Item (split-path $sp) -Type Directory
}
copy-item $_.fullname $sp -force
}
As long as the files are in one directory, the following should work fine. It might be a bit more verbose than needed, but it should be a good starting point.
$sourcePath = "c:\sourcePath"
$destPath = "c:\destPath"
$items = Get-ChildItem $sourcePath | Where-Object {($_.FullName -like "*.exe") -or ($_.FullName -like "*.exe.config") -or ($_.FullName -like "*.dll")}
$items | % {
Copy-Item $_.Fullname ($_.FullName.Replace($sourcePath,$destPath))
}