Powershell: Rename a folder when only partial name is known - powershell

I need to rename a folder without knowing the full folder name.
For Example C:\myfolder-2021-5-1 (I know the first part of the folder name)
I would like to rename it to c:\myfolder... Again, the script wont always know the full folder name.
Edit: I am new to Powershell. I have spent a few hours looking on Google and I don't see examples of people trying to rename a folder using a wildcard. There are very few folder renaming examples that I could find. Most of what I find pertains to renaming files not folders.
I get it people wanting me to "try" first and then ask questions. But, sometimes, especially for us newbies, we don't even know where to start.
I tried using several filename examples and just using a directory name with a wildcard and that did not work.
Don't know what else to say.
Any ideas?
Thanks!

You cant rename a directory if you dont know it's name - thats just not how files and directories work. What you can do is search for a directory that matches your criteria, then you can rename it.
(I'm assuming the reason you dont know the exact name is because its a date, but im also assuming the format of the directory name is consistent)
At its most basic level, this would work for your example:
get-childitem -Path c:\ -Directory -Filter "myfolder-????-*-*" | Move-Item -Destination "renamed-myfolder"
This will search for directories in C:\ that match the pattern "myfolder-????-*-*" - so this pattern would match your example folder C:\myfolder-2021-5-1. Then pass that Directory down the pipeline (|) into Move-Item where the directory is renamed to c:\renamed-myfolder.
This code has some major drawbacks though! It doesnt check if the new name exists before trying to rename the directory so it might fail. Also if more than 1 folder matches the filter only the first rename (Move-Item) will succeed. Its upto you to think about these edge cases and add suitable logic to detect/prevent them.
Its a good idea to use Test-Path command to check if the destination name already exists or not:
if(Test-Path -Path c:\renamed-myfolder){
throw "ERROR - c:\renamed-myfolder already exists!";
}
NOTE: Get-ChildItem filters * means "any characters" and ? means "one character" so "myfolder-*-*-*" would also work, but if the year is always 4 digits then use the ???? as its more specific. Ive used the filter "myfolder-????-*-*" as im assuming some days/months will be 2 digits like myfolder-2021-12-12.

Related

Compare 2 large folders

I know there are a lot of questions asked/answered related to this but my question has twists.
So I'm comparing 2 folders that has huge amount of data (over 20gb and can go up to 40gb) one of them being OneDrive.
I'm trying to compare and find the missing ones along with which ones are newer. I can accomplish either or but regardless which one I try because the folders are huge, it takes a long time and sometimes even crashes. On top of that, when you run the script, it tries to download the files on OneDrive (even tho they are present when you do Test-Path.
I found a post that does both (link below) but wondering if there is an easier way to accomplish this without downloading or putting it in a variable?
Thank you everyone in advance!
https://serverfault.com/questions/532065/how-do-i-diff-two-folders-in-windows-powershell/637776?newreg=b08ad3ef3c8e45d48ac0d17676a28df4
you can try with compare-object but you have to get all child items before like this:
$gci1 = Get-ChildItem -Recurse "Path to Folder"
$gci2 = Get-ChildItem -Recurse "Path to Folder"
Compare-Object $gci1 $gci2

Strange Powershell GCI Recurse Results with Wildcard

I'm trying to use GCI with the Recurse argument to get a list of all files WITHIN the subfolders of a specified path.
I'm using the following line:
gci 'C:\temp\TestRecurse\*\*' -Recurse
Underneath the TestRecurse folder, I have the following:
TestRecurse
|---b.txt
|---dir1
|------a.txt
I expect a.txt to be returned. However, I'm getting a.txt and b.txt. Stranger still to me, if I put a.txt into another subfolder:
TestRecurse
|---b.txt
|---dir1
|------dir2
|---------a.txt
The same statement above only returns a.txt. I'm baffled as to how messing with the location of a.txt changes when b.txt is returned. Can someone explain to me why this happens, and why b.txt is ever returned at all?
Update
I should mention, while they're appreciated, I'm not necessarily looking for a workaround. This is part of a larger script in our environment that is in charge of moving files around in various ways while trying stay flexible. It's not behaving as I expected it would, so I'm trying to understand why it's working the way it is. As pointed out by PetSerAl, understanding Get-ChildItem may be more trouble than it's worth.
Thanks!
You're including a wildcard for the parent directory (TestRecurse\*), so you are getting files contained in it as well. Try getting the folder list of the TestRecurse, then iterating through them.
Structure:
TestRecurse\b.txt
TestRecurse\dir1
TestRecurse\dir1\a.txt
Code:
Get-ChildItem 'C:\tmp\TestRecurse\' | ` # Get the list of items within TestRecurse
? {$_.PSIsContainer} | ` # Filter items that are folders
% {Get-ChildItem $_.FullName -Recurse} # Iterate through and get all items within those folders
This only returns folders and files within dir1, but not dir1 itself.

Powershell : Quickly count containers

I think we all know the PsIsContainer method to check if the current file is a folder or not. But in my project I need a way to quickly know the number of folders in a folder. All I need is to quickly get their number. I want to write in a .txt lines which would look like C:\folder;12. It would mean in the folder, with the -recurse argument, there would be 12 folders.
To explain why, I need to save the progress of my work when i cut off the program which is used to analyse some folders. When a folder's analysed, the result is written in a second .txt. For example, if a folder is called C:\folder\folder1, folder will be analysed and then folder1 will be too. Which makes folder appear 2 times in the file because the full name always is written. What i want to do is to count the number of lines where C:\folder is written. If it equals the number next it's path in the first .txt, it means the file already has been analysed and the function doesnt need to do it again.
Does someone have a solution ? Or maybe an another idea to save the progress ? Cause i really have the feeling this is taking too long to do this.
Thank you for your help.
Another approach, which i find much faster is using cmd built-in 'dir' command
of course this is in case you don't need the subfolders(which you can then run the function in a foreach loop, or change the function if this is the case)
Function Get-FolderCount($path)
{
$Dir = cmd /c dir $path /a:d
Return ($Dir[-1] -csplit 'Dir' -replace '\s')[0]
}
I use this as well for measuring folder size with /s switch and take the total size which is much faster then powershell, also much faster then run it on interactive shell...

How to rename files in batch, remove all characters after ".mp3" in file name?

I think that windows powershell can be used to do this. I have a stack of mp3 files which have problem with their file name. There is a stream of characters in file name of each file after the terms ".mp3" which prevents them from being identified as mp3 files. I have tried renaming each file manually but am fed up now. I want to automate the process.
It should be possible to use powershell for this and perhaps there are other options which I am not aware of. The script needs to read each file name in the folder and if the name has any more characters after ".mp3" in the filename, all the subsequent characters shall be deleted. How to do this?
$files=ls -Name *.mp3*
foreach ($file in $files) {
Rename-Item $file $file.Substring(0, $file.LastIndexOf(".mp3")+4)
}
However, it's too long solution.
First I'm sure the Community would have liked to have seen you try something so that we could have helped you fix it. However other users have provided solutions so I would like to chime in from a PowerShell perspective
Get-ChildItem C:\temp -Filter "*.mp3*" | Rename-Item -NewName {$_.Name -replace "\.mp3.*",".mp3"}
This will take all files with ".mp3" somewhere in the file name. Then it will rename them by taking everything after and including ".mp3" with just that. If you have a file with ".mp3" more than once this would be an issue. Easily fixed but I will keep it terse by accepting that potential.
UPDATE
ok. so the wildcards are weird with the rename command.
this DOES work
ren "*.mp3*" "??????????????????????????????????????????????????????????.mp3"
as long as there are as many ? as the longest filename
refer to this if you want details
https://superuser.com/questions/475874/how-does-the-windows-rename-command-interpret-wildcards

Insert Username in to file path Powershell

We are in the process of trying to tidy up our users home directories and speed up some office 2007 performance by moving all their templates in to a new directory on their user drive (U:). During my initial tests I can get the below script to work fine though it has the obvious problem of only working for my username. Is there a way to get it to take the currently logging in user? Before this would be handled by %username% and from a brief scan of the internet apparently:
$[Environment]::UserName
Should work. However I seem to be getting errors. Is there a better way to achieve the current logging in users name in to the file path?
if (!(Test-Path -path '\\SERVER\PATH\TO FILES\$[Environment]::UserName\Normal\'))
{
New-Item '\\SERVER\PATH\TO FILES\$[Environment]::UserName\Normal\' -type directory
##Move-Item \\SERVER\PATH\TO FILES\$env:username\Normal.dot \\\SERVER\PATH\TO FILES\$env:username\Normal\
## Move-Item \\SERVER\PATH\TO FILES\$env:username\*.dotm \\SERVER\PATH\TO FILES\%username%\Normal\
}
else
{
"No work to do"
}
Two problems. If you want variable/expression substitution to take place in a string, you need to use quotation-marks, not apostrophes, to enclose the string. In this case, you also need to add some parenthesis to denote an expression within the string.
"\\SERVER\PATH\TO FILES\$([Environment]::UserName)\Normal\"