Using the rename-item command to overwrite an existing file? - powershell

I'm trying to tidy up imported files from my iPhone using a PowerShell script, specifically wanting edited photos (IMG_E001.jpg) to overwrite the non-edited photos (IMG_001.jpg).
I'm using the rename-item but can't figure out how to get it to overwrite the file. My current workaround is to move all of the edited files into their own folder, run the script, and then copy them over the top of the original files but this is a bit of a pain, plus it doesn't seem as reliable as a fully automated script.
Here's the code I'm using currently:
get-childitem -recurse -Include *.JPG | foreach { rename-item $_ $_.Name.Replace("E", "") };
Please can anyone help me to get this script to overwrite the existing files? Thank you

This is a limitation of rename-item as #postanote mentioned in his comment this is because windows does not allow you to rename a file to an existing name. You will need to remove the other file first or overwrite it. Instead you can use move-item -force for essentially the same effect as it will perform the overwrite.
get-childitem -recurse -Include *.txt | foreach { Move-Item $_ $_.Name.Replace("E", "") -Force };
For more information; here is a related thread rename-item and override if filename exists

Related

PowerShell Move Files From One Server to Another

I know this has been asked a million times, but I can't seem to find anything that works for me. I don't know if there is a permissions issue or what, but I am trying to move files from one server to another using a PowerShell script in the task scheduler and it worked for about a week before it stopped working. There are no errors in the task scheduler, and I'm not well versed in PowerShell at all, I'm just trying to get something quick and simple for our CMS manager to move her files from the website to a folder on another server.
$ORG = "E:\folders\uploads\" ## enter current source folder
$DEST= "\\server-folder-structure\uploads\" ## enter your destination folder
foreach ($ORG in gci $DEST -include *.doc,*.docx,*.pdf,*.png,*.gif,*.jpg,*.jpeg,*.html,*.htm -recurse)
{
Move-Item -path $ORG -destination $DEST ## Move the files to the destination folder
}
I tried this too, in hopes it would work, but still no files are being moved.
Get-ChildItem E:\folder-structure\uploads\* -Include *.doc,*.docx,*.pdf,*.png,*.gif,*.jpg,*.jpeg,*.html,*.htm -Recurse |ForEach-Object { Move-Item $_.FullName \\server-folder-structure\uploads\ }
Am I doing something wrong? Are there permissions to folders that I need to set that I don't know about? Is PowerShell just not the best way to do this? Thanks in advance.
I believe you're making this harder than it should be (with respect to PowerShell being new to you). You don't need a loop on any of your examples if you want to pipe directly to Move-Item:
$ORG = "E:\folders\uploads\" ## enter current source folder
$DEST = "\\server-folder-structure\uploads\" ## enter your destination folder
$filterFor = "*.doc","*.docx","*.pdf","*.png","*.gif","*.jpg","*.jpeg","*.html","*.htm"
Get-ChildItem $ORG -Include $filterFor -File -Recurse |
Move-Item -Destination $DEST -WhatIf
As for what you tried, and as Mathias pointed out, you would be searching your $DEST location in which the files wouldn't exist as they would only be in $ORG; given that that's the actual source folder.
This would also overwrite you $ORG variable with the current item in your iteration in: foreach ($ORG in gci ..){ ... }.
Meaning, your Move-Item would be invalid.

How to copy all files in a folder to another folder and change the extension?

I have some files in a folder with no extension file. I want to copy all the files to another folder and change their extension to .txt.
I tried this code, but it still errors for creating the destination file.
$JOB = Copy-Item -Path C:\Users\XX\Documents\Folder1* -Destination "C:\Users\XX\Documents\Folder2"
Rename-Item -Path C:\Users\XX\Documents\Folder2\* -NewName *.TXT
Get-ChildItem -Path .\Folder1 -File |
ForEach-Object { Copy-Item -Path $_.FullName -Destination ".\Folder2\$($_.BaseName).txt" }
# Alternatively without ForEach-Object (see note below)
Get-ChildItem -Path .\Folder1 -File |
Copy-Item -Path $_.FullName -Destination { ".\Folder2\$($_.BaseName).txt" }
That should do the job. Keep in mind it will work only for one level, if you want recursive copy of folder structure, you'll have to modify the script slightly.
Basically, what's happening here is you find all the files and then pipe them to Copy-Item constructing destination path with BaseName property of source file (which doesn't have extension included, in comparison to Name property).
NOTE: as -Path accepts pipeline input (see docs here), you don't need to use ForEach-Object. However, it might still be useful for visibility (depending on your preferences).
Credits to #LotPings for noticing the above.

For loop while rename and move files withing a folder

Good morning,
started last week using powershell for some small scripts and now I'm stucked at creating a for loop for rename and move files.
I've got these 2 commands
get-childitem "$Quellordner" | Rename-Item -NewName {$_.Name.Replace("[Index]","-")}
get-childitem "$Quellordner" | Move-Item -Force -Destination $Zielordner -Verbose *>&1 | Set-Content $Logfileordner$Logfilename
and they are working fine but it's a bit odd not using a for loop for this. Unfortunately I can't get it to work :/
Any help will be appreciated!
(PS: Is there an other way to create a descending log file (newest to oldest) than copy the actual content and paste it belowe the new line?)
You can combine the rename and move by simply extending the pipeline:
Get-ChildItem -Path *.txt |
Rename-Item -NewName {$_.Name -replace "[Index]","-"} -PassThru |
Move-Item -Destination $Zielordner -Force
Writing to the start of a file is not directly supported, likely because it is an expensive operation (you need to move everything along somehow to make room), and seems like it will be more prone to corruption/data loss. One thing to look at is writing to the log as normal, but displaying it in reverse order. For example, Get-Content can read the individual lines of a text file into an array, which could easily be output from the end to the start.
You're actually already using a foreach loop. ForEach-Object to be precise.
Your line of code:
get-childitem "$Quellordner" | Rename-Item -NewName {$_.Name.Replace("[Index]","-")}
does exactly the same as the following code does:
$files = get-childitem "$Quellordner"
foreach($_ in $files){
Rename-Item -NewName {$_.Name.Replace("[Index]","-")}
}
About your PS: there is no way, I know of, to add a new line at the top of a text file without reading the file, adding the line you want to add at the top and write it back.

Rename bulk files with given name, in directory and subfolders using PowerShell

I’m looking for a solution to rename all files with given name in the directory and subfolders.
E.g.
There is a directory called c:\blah and in this folder, there is one file called BaR.txt and one folder called foo. In the foo folder, there is another file called bAr.txt.
I want to find all files with name bar.txt and change the name of each file to “neo.txt”. It must also be possible to rename the files to lower case as well e.g. bar.txt.
So far, I’ve tried to do this manually using the Windows Explorer in Windows10 but for some weird reason when I try to rename the bulk files there is extra “(1)” sign added to the end of each file name.
I’ve tried to play with PowerShell and I created a command
$_.name -replace 'bar.txt','neo.txt'
But it didn’t work for me.
To do this, you need 2 cmdlets: Get-ChildItem and Rename-Item.
This should work:
Get-ChildItem -Path 'C:\Blah' -Filter 'bar.txt' -Recurse | ForEach-Object {
Rename-Item -Path $_.FullName -NewName 'neo.txt'
}
However, if inside the foo folder there are more subfolders, this code will rename all files called bar.txt (case-insensitive) it finds in all of these subfolders.
If you do not want to go any deeper than the first subfolder in C:\Blah (the one called foo), you can use the -Depth parameter on the command like this:
Get-ChildItem -Path 'C:\Blah' -Filter 'bar.txt' -Recurse -Depth 1 | ForEach-Object {
Rename-Item -Path $_.FullName -NewName 'neo.txt'
}

Reset Filenumber for new folder in Recurse Filerename Powershell

I am working on a powershell batch file.
I want to rename all the files in a certain amount of folders. I need to rename it to a certain part of the folder name followed by an incremental number. So far i managed to create a rename command in powershell that also add numbers to the files.
Get-ChildItem -recurse -filter "*.jpg" | %{$x=1} {Rename-Item $_.FullName -NewName ('{0}-{1}.jpg' -f ($_.FullName.substring(18,8) -replace("-","")) ,$x++)}
This works well how ever i want to reset the number back to 1 for each separate folder. At the moment i keep numbering up trough different folders. How do i reset $x back to 1 when i change folder?
As you can't be sure that each directory is enumerated at ones, I would create a hashtable to keep track of the index. Something like:
$Directories = #{}
Get-ChildItem -recurse -filter "*.jpg" | ForEach {
Rename-Item $_.FullName -NewName ('{0}-{1}.jpg' -f ($_.FullName.substring(18,8) -replace("-","")) ,++$Directories[$_.DirectoryName])
}