Remove certain characters from all folder names in a folder - powershell

I have a folder with a load of subfolders with a random number at the beginning of their folder name. they are in this format:
1254170-folder1
1212340-folder2
3245417-folder3
What can I to rename all of them to
folder1
folder2
folder3
I tried something like this because I saw something similar about filenames.
for f in *\1*;do( mv "$f" "${f//1/ }");done
but it does not work. the powershell returned
At line:1 char:4
+ for f in *\1*;do( mv "$f" "${f//1/ }");done
+ ~
Missing opening '(' after keyword 'for'.
At line:1 char:17
+ for f in *\1*;do( mv "$f" "${f//1/ }");done
+ ~
Missing statement body in do loop.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingOpenParenthesisAfterKeyword
Not sure what should I do. I am using Windows 10 2004.
Thanks for the help.

This should work:
Get-ChildItem -path . -directory -recurse | Where {$_.Name -match '^\d+-'} | Rename-Item -NewName {$_.Name -replace '^\d+-',''}
First command enumerates folders and all subfolders in current directory (.).
Second command filters folders which starts with digits followed by dash (^\d+- regex)
Third command renames the folders by removing ^\d+- prefix

I complet the #Renat code :
if you want exclude the directories with format without characters after the '-' (example 1254170- )
And if you want your script continue same if a directory with the new name already exist
Get-ChildItem "c:\temp\" -dir | where name -match "^\d+-.+$" | Rename-Item -NewName {$_.Name.Split('-')[1]} -ErrorAction SilentlyContinue

Related

Bulk renaming files to add sequential prefixes via PowerShell

I have two folders all with multiple .msg files I need to add a numerical, sequential prefix to. One folder has over 1500 individual files.
I want the end result to go from this:
"[EXTERNAL] RE%3A Auth....msg"
"Fees....msg"
"Hello There...msg"
To this:
"1[EXTERNAL] RE%3A Auth....msg"
"2Fees....msg"
"3Hello There...msg"
I have tried to combine a few results from other similar threads I have found here and have come up with the following:
$i = 1
#Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.directory.name).msg" -f $i++)}
When I run this script, I get the following errors:
At C:\users\me\Documents\PrependNumbers.ps1:10 char:5
+ #Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.dire ...
+ ~~~~~~~~~~
Unexpected token '-ChildItem' in expression or statement.
At C:\users\me\Documents\PrependNumbers.ps1:10 char:16
+ #Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.dire ...
+ ~~~~~
Unexpected token '*.msg' in expression or statement.
At C:\users\me\Documents\PrependNumbers.ps1:10 char:1
+ #Get-ChildItem *.msg | %{Rename-Item $_ -NewName ("{0:000#}_$($_.dire ...
+ ~~~~
The splatting operator '#' cannot be used to reference variables in an expression. '#Get' can be used only as an
argument to a command. To reference variables in an expression use '$Get'.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : UnexpectedToken
I feel like I probably just have a syntax error somewhere, but am unable to tell where exactly from these errors.

How to use * in a powershell path with [

I need to copy images generated by software (HWMonitorPro). Folders and sub-folders of images cannot be modified (or I did not find how).
The images are stored in the following path:
C:\Users\hugo\Documents\DossierTest\logs\[JUN 13, 2022 - 11:06]\[LAPTOP-P15V]\[1280x960].
As you can see, a directory is created with each recording, with the date and time.
So I decided to use the following technique to be able to take the images of several captures at once:
$C = "C:\Users\hugo\Documents\DossierTest\logs"
copy-item $C'\*\`[LAPTOP-P15V`]\`[1280x960`]\789.txt' -Destination $C\test3
The line works with "[JUN 14, 2022 - 9:22]" instead of "*". This is what I get when I use the line show above:
PS C:\Windows\system32> C:\Users\hugo\Documents\DossierTest\ScriptCC.ps1
Copy-Item : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard character pattern is not valid: [LAPTOP-P15V
At C:\Users\hugo\Documents\DossierTest\ScriptCC.ps1:3 char:1
+ copy-item $C'\*\`[LAPTOP-P15V`]\`[1280x960`]\789.txt' -Destination $C ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.CopyItemCommand
If anyone could help me solve my problem that would be great!
PS: I'm French, sorry if it's badly written.
As it seems there's something strange with paths containing square brackets, you can use CopyTo method to copy files instead of copy-item cmdlet.
E.g. like this:
$rootfolder = "E:\tmp\logs"
$destfolder = "E:\tmp\foldertest3"
$allfiles = gci $rootfolder -File -Recurse
foreach ($file in $allfiles) {
$newfile = $file.CopyTo("$destfolder\$($file.Name)")
}
This copies all files in subdirectories to single destination folder =
you'll need to deal with t further in case there are files with same name in different subfolders.
PS: Your $C is really a terrible variable name when dealing with file paths :-)

How to Recursive Directory Loop, Match a Filename and Manipulate the File

I'm a Powershell novice so apologies for any wrong terminology. I've had a look on SE and I know how to recursively descend into a directory structure, however all the working examples I can find seem to pipe the output of Get-ChildItem, which I can't understand how to further work with the file before the loop iterates.
What I'm trying to do
Provide my script with a directory: C:\Users\Donglecow\myPictures\.
Recursively loop through all directories in the defined directory (I have an extensive file structure).
Find all files which match a filter thumbnail*.jpg, EG: thumbnail_001.jpg
Rename the file to BACKUP-thumbnail*.jpg
Check the dimensions of that image in pixels and print them out to the command line
What I've got so far
param (
[string]$dir = $pwd
)
write-output "Working from $($dir)"
$foundJpg = get-childitem -Recurse -Filter thumbnail*.jpg $dir
foreach($file in $foundJpg) {
write-output "Found $($file)"
#Rename to Backup...
#Check image dimensions...
#Do other stuff...
}
This works and outputs the correct file name, but when I try to rename the file I get an error.
Rename-Item -NewName { $_.Name.replace("thumbnail", "SAFE-thumbnail.jpg") }
Rename-Item : Cannot evaluate parameter 'NewName' because its argument is specified as a script block and there is no
input. A script block cannot be evaluated without input.
At C:\Users\Donglecow\myPictures\med.ps1:9 char:23
+ ... -Item -NewName { $_.Name.replace("thumbnail", "SAFE-thumbnail.jpg") }
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [Rename-Item], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.RenameItemCommand
I've deducted this is probably because I've tried to adapt from a command that pipes the output as shown in answers on this question:
Get-ChildItem -Recurse -Filter *.mp3 | Rename-Item –NewName { $_.name –replace 'xyz','abc' }
Whereas I'm using a different construct for my loop so that I can further interact with each file that I find.
My environment
For reference, a snippet of my file structure is below.
C:\Users\Donglecow\myPictures\
1\001\thumbnail_001.jpg
1\002\thumbnail_001.jpg
1\003\thumbnail_001.jpg
2\001\thumbnail_001.jpg
etc...
Where am I going wrong here?
Try this:
foreach($file in $foundJpg) {
$File | Rename-Item -NewName { $_.Name.replace("thumbnail", "SAFE-thumbnail.jpg") }
#Do other stuff...
}
You need to use $file as the input of the command (which you should be able to do via the pipeline as shown above) as this is what your ForEach loop is using to represent each item retrieved by Get-ChildItem into the $foundJpg variable.

Move-Item with -match and -LiteralPath not working

I have a file move script that looks for files with keywords in the name and moves them to a specific folder. There's about a hundred lines that all work fine, except for one of them, and the only thing I can think of is that the file has brackets in the name.
I'm already using -LiteralPath to grab the full path, but the error is weird. I've tried double quotes, double backticks, and some other options that I've found elsewhere on the boards, but nothing is working.
Here is all the relevant parts of the script (without posting the whole thing):
# Source folders
$RecipesFolder = "F:\Downloads\Downloaded Recipes\"
# Destination Folders Drive I
$CoffeeRecipes = "I:\My Recipes\Coffee Recipes\"
# Get list of files
$Files = Get-ChildItem $RecipesFolder -File -Recurse
# Process Files
foreach ($File in $Files) {
if ($File -match "Coffee") {
Move-Item -LiteralPath $RecipesFolder$File -Destination "$CoffeeRecipes" -Force
}
It's a really simple script, and every other line works fine, except that one. All the lines are written identically.
This is the full error I get (sourcepath obfuscated for security), and thank you in advance for any assistance:
Move-Item : Cannot move item because the item at 'F:\Downloads\Downloaded Recipes\[1]
Coffee Recipe - 11[1].txt' does not exist.
At Path-to-powershell-script-file:153 char:13
+ Move-Item -LiteralPath $RecipesFolder$File -Destina ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Move-Item], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.MoveItemCommand
When I receive this error, the file disappears, and doesn't get moved to the folder, it just vanishes.

Powershell Archive script win2008r2 problems

I created a ps-script to move MS SCCM backup folder to another location and delete folders older than 2 days :
$Date = Get-Date -format d.M.yyyy
$BackupDir = "\\Source_Servername\Folder1\Folder2"
$ArchiveDir = "\\Destination_Servername\Folder1\Folder2"
set-alias 7za "$ArchiveDir\7za.exe"
Get-Item "$ArchiveDir\*" |? {$_.psiscontainer -and $_.lastwritetime -le (get-date).adddays(-2)} |% {remove-item $_ -Recurse -Confirm:$false}
7za a -r "$ArchiveDir\$Date\$BackupDir.7z" $BackupDir
I created this using Win 8 and when i try to apply it on win2008r2 servers it fails with the following error :
Bad numeric constant: 7.
At E:\xxxxx\xxxxx\xxxx\Afterbackup.ps1:9 char:2
+ 7 <<<< za a -r "$ArchiveDir\$Date\$BackupDir.7z" $BackupDir
+ CategoryInfo : ParserError: (7:String) [], ParseException
+ FullyQualifiedErrorId : BadNumericConstant
It works when i enter the full path to 7za.exe like this :
\Destination_Servername\Folder1\Folder2\7za a -r "$ArchiveDir\$Date\$BackupDir.7z" $BackupDir
I'm new to powershell so i would appriciate any help :)
PowerShell v1 & v2 do not like commands that start with numbers. The issue seems to have been addressed in v3 and that's probably why it works on your workstation. You can work around this by placing a backtick in front of the alias when you execute it:
`7za a -r "$ArchiveDir\$Date\$BackupDir.7z" $BackupDir
Alternately, you can change the alias to not start with a number.