Move files that have the same name but different extension - powershell

I'm trying to use the script from here to move avi files I've converted into mp4, back into their original folders. All seems to work ok, the script tries to move the files to the correct location (see below) but the mp4 files aren't moved.
What if: Performing the operation "Move File" on target "Item: Z:\AVI\MVI_4965.mp4 Destination: Z:\Pictures\2011\04_21_11_Bergen\MVI_4965.mp4".
All files are located on my Z: NAS drive and I've modified the script to account for this (see below) starting from PS Z:\>.
# Create a hashtable with key = file basename and value = containing directory
$mediaFiles = #{}
Get-ChildItem -Recurse .\Pictures | ?{!$_.PsIsContainer} | ForEach-Object {
$mediaFiles[$_.BaseName] = $_.DirectoryName
}
# Look through lost files and if the lost file exists in the hash, then move it
Get-ChildItem -Recurse .\AVI | ?{!$_.PsIsContainer} | ForEach-Object {
if ($mediaFiles.ContainsKey($_.BaseName)) {
Move-Item -whatif $_.FullName $mediaFiles[$_.BaseName]
}
}
Any ideas whats stopping the files being moved or how to correct?

That's the point of -WhatIf. It simply says what it would do without actually doing it so you can verify the script first. Remove it from the Move-Item command.

Related

How do I move a selection of files into several different directories in one loop?

First time toying seriously with Powershell. I'm running into the problem that my little loop doesn't do what I want it to; it creates a list of series names from the files found in a directory and creates the directories needed to hold the files.
[TAG]Series first.txt
[TAG]Series something else.txt
File.jpg
etc.
This should be sorted into
Series first [Sometag]\[TAG]Series first.txt
Series something else [Sometag]\[TAG]Series something else.txt
File.jpg
etc.
But I can't get Move-Item to actually move the files into the new directories. It leads to extensionless files or errors stating that the file (directory) already exists.
$details = ' [Sometag]'
$series = Get-ChildItem . -Name -File -Filter *.txt |
% {$_.Replace("[TAG]", "").Split("-")[0].Trim()} |
Get-Unique
$series | ForEach-Object {
New-Item -ErrorAction Ignore -Name $_$details -ItemType Directory
}
This is the command that should move the files that it finds using the $serie collection into the directories previously created.
foreach ($serie in $series) {
Get-ChildItem -File -Filter *$serie*.txt |
Move-Item -Destination '.\$serie$details'
}
Which results in it complaining that the file already exists. What would be the best way to deal with this, and can I optimize the first two lines?

Powershell , remove folder with the same name like .zip

I must delete files which have been extracted from a zip file, into a folder named after the zip file, i.e.:
\test1.zip -> \test1
My script must find the folder which have the same name as the zip file and delete this folder.
Get a list of all of the Zip files in the directory, then loop over the results and delete any folder with the same name minus the extension, also known as the BaseName.
Get-ChildItem -Filter *.zip | `
ForEach-Object { if (Test-Path $_.BaseName) {
Remove-Item -Recurse -Force $_.BaseName }
}
You can enter the entire command on one line, I have split it up so that it is easy to read on here. I used the following commands in this example:
Get-ChildItem - Creates a object in the pipeline for each file with a .zip extension
ForEach-Object - Simply allows you to perform an action for each object in the pipeline.
Remove-Item - note the use of -Recurse and -Force ensures that the folder is removed even if it contains files, you will not be asked to confirm.

Powershell loop through folder, search by file names and location then replace

I would like to use a loop for my program that grabs the file names of only the .dll in the folder and subfolders of that directory. It then searches a specified location/path for a .dll with the same file name and if it exists it replaces it. So far my program copies all files from one location to the other and once they are copied I need the above stated to be worked out.
My biggest issue is how do you search by filenames in a loop at a specified location and if it exists, replace it? Below code is locally in random places before I put the correct paths using servers and other drives.
#sets source user can edit path to be more precise
$source = "C:\Users\Public\Music\Sample Music\*"
#sets destination
$1stdest = "C:\Users\User\Music\Sample Music Location"
#copies source to destination
Get-ChildItem $source -recurse | Copy-Item -destination $1stdest
#takes 1stdest and finds only dlls to variable
#not sure if this is right but it takes the .dlls only, can you do that in the foreach()?
Get-ChildItem $1stdest -recurse -include "*.dll"
Here you go, you'll need to edit your paths back in. Also, note that $1stDest was changed to enumerate the list of files in the destination folder.
The logic goes through all of the files in $source, and looks for a match in $1stDest. if it finds some, it stores them in $OverWriteMe. The code then steps through each file to be overwritten and copies it.
As written, it uses -WhatIf, so you'll have a preview of what would happen before running it. If you like what you see, remove the -WhatIf on line 15.
$source = "c:\temp\stack\source\"
#sets destination
$1stdest = get-childitem C:\temp\stack\Dest -Recurse
#copies source to destination
ForEach ($file in (Get-ChildItem $source -recurse) ){
If ($file.BaseName -in $1stdest.BaseName){
$overwriteMe = $1stdest | Where BaseName -eq $file.BaseName
Write-Output "$($file.baseName) already exists # $($overwriteMe.FullName)"
$overwriteMe | ForEach-Object {
copy-item $file.FullName -Destination $overwriteMe.FullName -WhatIf
#End of ForEach $overwriteme
}
#End Of ForEach $file in ...
}
}
OutPut
1 already exists # C:\temp\stack\Dest\1.txt
What if: Performing the operation "Copy File" on target "Item: C:\temp\stack\source\1.txt Destination: C:\temp\stack\Dest\1.txt".
5 already exists # C:\temp\stack\Dest\5.txt
What if: Performing the operation "Copy File" on target "Item: C:\temp\stack\source\5.txt Destination: C:\temp\stack\Dest\5.txt".

Move a files that have the same name but different extension. Powershell

I am a junior tech and have been tasked to write a short powershell script. The problem is that I have started to learn the PS 5 hours ago - once my boss told that I'm assigned to this task. I'm a bit worried it won't be completed for tomorrow so hope you guys can help me a bit. The task is:
I need to move the files to different folders depending on certain conditions, let me start from the he folder structure:
c:\LostFiles: This folder includes a long list of .mov, .jpg and .png files
c:\Media: This folder includes many subfolders withe media files and projects.
The job is to move files from c:\LostFiles to appropiate folders in c:\Media folder tree if
The name of the file from c:\LostFiles corresponds to a file name in one of the subfolders of the C:\media We must ignore the extension, for example:
C:\LostFiles has these files which we need to move (if possible) : imageFlower.png, videoMarch.mov, danceRock.bmp
C:\Media\Flowers\ has already this files: imageFlower.bmp, imageFlower.mov
imageFlower.png should be moved to this folder (C:\media\Flowers) because there is or there are files with exactly the same base name (extension must be ignored)
Only the files that have corresponding files (the same name) should be moved.
So far I have written this piece of code (I know it is not much but will be updating this code as I am working on it now (2145 GMT time). I know I missing some loops, hey yeah, I am missing a lot!
#This gets all the files from the folder
$orphans = gci -path C:\lostfiles\ -File | Select Basename
#This gets the list of files from all the folders
$Files = gci C:\media\ -Recurse -File | select Fullname
#So we can all the files and we check them 1 by 1
$orphans | ForEach-Object {
#variable that stores the name of the current file
$file = ($_.BaseName)
#path to copy the file, and then search for files with the same name but only take into the accont the base name
$path = $Files | where-object{$_ -eq $file}
#move the current file to the destination
move-item -path $_.fullname -destination $path -whatif
}
You could build a hashtable from the media files, then iterate through the lost files, looking to see if the lost file's name was in the hash. Something like:
# Create a hashtable with key = file basename and value = containing directory
$mediaFiles = #{}
Get-ChildItem -Recurse .\Media | ?{!$_.PsIsContainer} | Select-Object BaseName, DirectoryName |
ForEach-Object { $mediaFiles[$_.BaseName] = $_.DirectoryName }
# Look through lost files and if the lost file exists in the hash, then move it
Get-ChildItem -Recurse .\LostFiles | ?{!$_.PsIsContainer} |
ForEach-Object { if ($mediaFiles.ContainsKey($_.BaseName)) { Move-Item -whatif $_.FullName $mediaFiles[$_.BaseName] } }

Moving every n files into a separate folder

I have several files with a repetitive naming convention, e.g.
1*Intro*
2*
3*
…
10*intro*
….
I want to move each module into a separate folder. So, I should separate from every *intro* till the next one.
Also, I should note that files are numbered and sorted.
I guess, the easiest way to do this is to:
1. Get a list of intros.
2. Separate their numbers.
3. Start moving files starting from one number till their smaller than the next one.
$i = 1
Ls *intro* | ft {$_.name -replace '\D.*', ''}
// The reason for .* is that the files are `mp4`.
Ls * | ? {$_.name -match '[^firstNumber-SecondNumber-1]'} | move-item -literalpath {$_.fullname} -destination $path + $i++ + '/' +{$_.name}
So the last command should be something like:
Ls *intro* | % { ls * | ? {…} | move-item … }
Or maybe the move-item itself can do the filtering job.
The regular expression doesn't work and I don't have enough Powershell knowledge to write anything better. Can you think of any script to do that? Also how should I permit move-item to create the folder?
I'll be thankful if someone could edit this post with a better title.
This could be done with a simple Switch. The switch will be run against all items in the current folder (items gotten with the Get-ChildItem cmdlet which you use by it's alias 'LS'). It looks to see if the file has the string "Intro" in the file name. If it does, it creates a new folder with that file's name, and stores that folder's info in the $TargetFolder variable (variable created previously to avoid scoping issues). It then moves the file to that folder, and continues to the next file. If the file does not have "Intro" in its file name it simply moves the file to whatever the last assigned $TargetFolder is that was created.
$TargetFolder = ""
Switch(Get-ChildItem .\*){
{$_.BaseName -match "intro"} {$TargetFolder = New-Item ".\$($_.BaseName)" -ItemType Directory; Move-Item $_ -Destination $TargetFolder; Continue}
default {Move-Item $TargetFolder}
}