Powershell Comparing two folders then copying it into another file - shell

I'm trying to compare two folders and copy the the files that exists in one but not the other into a whole separate folder.
This is what I have so far
$fso = Get-ChildItem -Recurse -path C:\Users\akalkandelen\Desktop\old
$fsoBU = Get-ChildItem -Recurse -path C:\Users\akalkandelen\Desktop\new
foreach($item in Compare-Object -ReferenceObject $fso -DifferenceObject $fsoBU -PassThru){
Copy-Item -Path $item.FullName -Destination C:\Users\akalkandelen\Desktop\release
}
The problem is that directory structure of the files copied into Release has to match. So if a file within a folder within another folder it has to maintain that structure. If i use -Recurse than it adds all the sub-folders and files into the root folder as well.

Related

i need copy command support

Currently I have a directory tree system like the image:
I would like someone to help me create a small piece of code. I want to search all directories, I will see a folder named "C" as above, copy all the data and rename it to a higher level folder, will copy to another folder with the name E . You can only copy the A1 folder and contain the C folder inside. I'm using windows 10. Thank you very much.
In PowerShell, the Copy-Item cmdlet can rename an item while copying. So you want to:
Use Get-ChildItem to find all subfolders of the source named "C".
Pipe these to Copy-Item
Construct the destination path and name using Join-Path.
$Source = 'C:\Source' ### Parent folder of folders "A", "B", etc.
$Dest = 'D:\Dest' ### Destination path for copied folders
# Destination root must exist:
If (!(Test-Path $Dest)) {mkdir $Dest | out-null}
Get-ChildItem -Path $Source -Filter 'C' -Directory -Recurse |
Copy-Item -Destination {Join-Path $Dest $_.Parent.Name} -Recurse
Which can be shortened using positional parameters and aliases to:
gci $Source 'C' -ad -s |
copy -Dest {Join-Path $Dest $_.Parent.Name} -Recurse

how can ı do that moving subfolder to top folder

Can I do this with cmd?
for example
c:\a\a1\qw.exe => c:\a1\qw.exe like that
I have many directories like that so I want to learn how can I do this in windows?
I want to move many folders in one command
Thank you for your answer
You can combine move with two for /d loops:
for /d %i in (?) do for /d %j in ("%i\*.*") do move "%j" .
The first loop will find all directories with a single character (? will match a, b) below the current directory. The second loop will find all directories (*.* will match everything) in these directories and move it to the current directory.
Replace ? by *.* if you don't have single letter directories. But be warned: do not run this in C:\, or it will attempt to move all folders out of the Windows and Program Files directory.
The Move Command allows users to transfer files or directories from one directory to another, or from one drive to another.
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/move
move /?
Example of Move Command
To move the files of c:\windows\test to the test directory in the root directory, this is of course assuming you have the Windows\test directory.
move c:\windows\test\*.* c:\test
Powershell Move-Item
The Move-Item cmdlet moves an item, including its properties, contents, and child items, from one location to another location. The locations must be supported by the same provider. For example, it can move a file or subdirectory from one directory to another or move a registry subkey from one key to another. When you move an item, it is added to the new location and deleted from its original location.
https://social.technet.microsoft.com/Forums/en-US/729f90e2-4c1d-445d-ad72-6f752a3d7d24/powershell-move-folder-and-subfolders
Example Using PowerShell Move-Item
$parentpath = "C:\Temp"
$files = Get-ChildItem -Path $parentpath -Filter "*.txt" -Recurse
Set-Location $parentpath
New-Item -Name "test" -ItemType Directory -ErrorAction SilentlyContinue
Set-Location .\test
foreach ($file in $files)
{
$destination = New-Item -ItemType directory -Name $(split-path $file.Directory -Leaf) -erroraction 'silentlycontinue'
$file | Move-Item -Destination $destination
}
Bit-Transfer
My Bit-Transfer script is here. I would place it here for you, but some start complaining that I copied my own script to this post.
backup www directory from local to network drive powershell
Here You Go Using WhatIf -- 'd:\deneme\a\a1', 'd:\deneme\b\b1', 'd:\deneme\c\c1' one level up 'd:\deneme\a1', 'd:\deneme\b1', 'd:\deneme\c1'
$paths = "d:\deneme\a\a1", "d:\deneme\b\b1", "d:\deneme\c\c1"
ForEach($path in $paths) {
$path = $path.ToString()
$up = $path.Substring(0, $path.lastIndexOf('\'))
#Move-Item -Path $path -Destination $up -force -Verbose
Move-Item -Path $path -Destination $up -WhatIf
}

Powershell copying specific files from all subfolders to a single folder

I'm trying to copy all of the cover.jpg files in my music library to one folder. My attempts so far have either landed me with one file in the destination, or every desired file but also in their own folder matching the source (i.e. folders named for each album containing just the cover.jpg file).
Get-ChildItem "C:\Music" -recurse -filter *.jpg | Copy-Item -Destination "C:\Destination"
I realised that the copy-item command was simply overwriting the previous copies thus leaving me with only one file. I then tried going down the renaming route by moving the file then renaming it but of course that failed as the folder I was basing the rename off has now changed. I don't want to change the name of the file before I copy it as other programs still need the cover.jpg to function.
My question is...
Does anybody know how to recursively look through each folder in my music library to find the cover.jpg file, rename it to match the parent folder (or even if possible, grandparent and parent) then copy that file to a new folder making sure to not copy or create any new folders in this destination?
As a bonus, could this check if a file already exists so that if I ran it in the future only new files will be copied?
The file structure for the library is pretty simple. \Music\Artist\Album title\cover.jpg
If you have a music library structure like that, the easiest way would be to use the properties Directory and Parent each FileInfo object returned by Get-ChildItem contains:
$sourcePath = 'C:\Music'
$destination = 'C:\Destination'
# if the destination folder does not already exist, create it
if (!(Test-Path -Path $destination -PathType Container)) {
$null = New-Item -Path $destination -ItemType Directory
}
Get-ChildItem -Path $sourcePath -Filter '*.jpg' -File -Recurse | ForEach-Object {
$newName = '{0}_{1}_{2}' -f $_.Directory.Parent.Name, $_.Directory.Name, $_.Name
$_ | Copy-Item -Destination (Join-Path -Path $destination -ChildPath $newName)
}

Unzip Multiple Files into Different Directories

I have multiple zip files.
They are called folder(1).zip, folder(2).zip, folder(3).zip. Using PowerShell, when I attempt to unzip them all into unique folders using this...
Get-ChildItem 'c:\users\name\downloads' -Filter *.zip | Expand-Archive -DestinationPath 'c:\users\name\downloads' -Force
I get all of the files into one folder called "folder". How can I get the zip folders to unzip into separate folders?
Bonus question, is there a way, as part of this process, to rename each folder as it's coming out so folder(1).zip becomes Name-Here, folder(2).zip becomes Other-Name-Here, etc?
Thanks!
Because you specify only one destination path they will all be extracted into c:\users\name\downloads. I suppose the zip archives each contain a folder named "folder", so all contents from all archives end up together in c:\users\name\downloads\folder
You would have to specify a different destination path for each archive. Not sure what your naming convention should be, I have used a simple counter:
$counter = 0
Get-ChildItem 'c:\users\name\downloads' -Filter *.zip | foreach {
$destination = Join-Path $_.DirectoryName ("YourName" + $counter++)
Expand-Archive $_.FullName -DestinationPath $destination
}
Of course I suppose, now every of those folders will have the subfolder "folder", but if that's how the archives are built there's not really a way to change that. If you are absolutely sure that all archives have that subfolder, you could do something like this:
$counter = 0
Get-ChildItem 'c:\users\name\downloads' -Filter *.zip | foreach {
# expand to the root folder first
Expand-Archive $_.FullName -DestinationPath $_.DirectoryName
# now rename the extracted "folder" to whatever you like
Rename-Item (Join-Path $_.DirectoryName "folder") -NewName ("YourName" + $counter++)
}

How to create destination folder with date appended to it via Powershell?

I have backup files sitting in a directory. The objective I am trying to achieve is that each time I run this piece of Powershell against that directory, I want it to move the files into a folder that gets created and append today's date to it. I have tried this:
Get-ChildItem -Path 'C:\API\APIBackups' | ForEach-Object {
Move-Item -Path $_.FullName -Destination "C:\Users\Admin\Desktop\New folder\$($_.BaseName,(Get-Date).ToString("MMddyyyy"),$_.Extension)"
}
All this does is moves the backup files into "New folder" and append the date to the files themselves. I'm wanting it to create a new folder with today's date appended within "New folder" and have the backup files sitting in there. Any help would be great.
For one the commas do not belong but each section of "code" needs their own subexpression. You are also sticking the date in between the base filename and the file extension, so it looks like you want to insert the date in the file name. Instead, you can adjust it to this.
Get-ChildItem -Path 'C:\API\APIBackups' | ForEach-Object {
Move-Item -Path $_.FullName -Destination "C:\Users\Admin\Desktop\New folder$((Get-Date).ToString("MMddyyyy"))\"
}
Unless you're renaming the file, you don't need to specify it in the path.
Important Note that if that folder does not exist, you will need to create it first. Otherwise you'll end up with an extensionless file with that name instead. You could test for the path first, create if it doesn't exist, then move.
Get-ChildItem -Path 'C:\API\APIBackups' | ForEach-Object {
$newfolder = "C:\Users\Admin\Desktop\New folder$((Get-Date).ToString("MMddyyyy"))\"
if(-not(Test-Path $newfolder)){
$null = New-Item -Path $newfolder -ItemType Directory
}
Move-Item -Path $_.FullName -Destination $newfolder
}
The $null is to hide the output that New-Item creates by default.
A suggestion for improvement would be to use Join-Path for building the new folder path

Resources