TOC
So I recently wanted to look through some tutorial videos I’d purchased online, but I wanted to view them easily on the TV, and realised that although I had them all saved on my Plex Media Server, it turns out Plex didn’t like the names/format, and just listed all the individual videos in one big mess of a library. I wanted to follow them in order, so this wasn’t ideal.
So I then looked into how I can go about grouping these videos for easier viewing/finding, and came across this plex article stating that the folders and files needed to be in a very particular format for Plex to understand how to group them. Given the number of videos there were in the tutorial library, I really didn’t want to be doing this manually, so I set out to create a quick Powershell script to do the laborious work for me.
This isn’t really an article intended on how to organize your personal library for plex, it’s more about some sample code to show you how to perform large-scale file/folder renaming, which isn’t that uncommon in the IT world.
Requirements
So in my particular scenario, I had a folder structure that looked similar to the following:
- Tutorial
- 1. Intro
- 1. Video.mp4
- 2. Video.mp4
- 3. Video.mp4
- etc
- 2. First Topic
- 1. Video.mp4
- 2. Video.mp4
- 3. Video.mp4
- etc
- 3. etc
- etc
- etc
So as per the Plex article, I needed the names to be changed to the following in order to them to be grouped correctly:
- Tutorial
- 01
- Tutorial - S01E01 - Video.mp4
- Tutorial - S01E02 - Video.mp4
- Tutorial - S01E03 - Video.mp4
- etc
- 02
- Tutorial - S02E01 - Video.mp4
- Tutorial - S02E02 - Video.mp4
- Tutorial - S02E03 - Video.mp4
- etc
- 03
- etc
- etc
Solution
So I started out by setting my variables up for the parent directory, etc
$parentname = "Tutorial"
$parentpath = "\\myplexserver\Tutorials\$parentname"
As I’m doing this on a remote Windows machine, I needed to use the Plex Server remote shares as above.
Next, the simple Get-ChildItem
(or gci
for short) to get the sub-folders of my Tutorial directory
$folders = gci $parentpath
So at this point, if we were to run the command, we’d have our $folders
variable populated with all of the sub-folders such as “1. Intro”, “2. First Section”, etc
We now need to write some code to iterate through each of these sub-folders, and prepare to rename them to “01”, “02”, etc. As we already have the number at the beginning of each folder, we can reuse that to make things easier:
foreach ($folder in $folders) {
$foldername = $folder.Name
$foldernumber = $foldername.split('.')[0]
$newfoldername = "$foldernumber"
So what we’re doing here is grabbing the folder name ($foldername
), stripping everything after the “.” ($foldernumber
), then setting this as our $newfoldername
. Easy stuff.
However, to maximse compatability, I wanted the folders to consist of two digits, so “01”, instead of “1”, etc. Another bit of code to do this for us is as follows:
if ($newfoldername.Length -lt 2) {
$newfoldername = "0$newfoldername"
"new folder name = $newfoldername"
}
Notice that the penultimate line here of
"new folder name = $newfoldername"
simply outputs the new folder name to the screen. I use this technique just to make sure I get the intended outcome
So this simply looks at the $newfoldername
we populated earlier, and if it’s less than (-lt
) two digits long, it places a “0” in front, and sets that as our new folder name ($newfoldername = "0$newfoldername"
)
So that’s our Foldername’s sorted for now (notice I’ve not actually performed the rename yet, I just wanted to set the new name for us to use later). We now need to look at renaming each file within the sub-folders.
First, we need to get the contents of the sub-folders. Note we’re still within the foreach
loop here:
$seriesfolder = gci "$parentpath\$foldername"
Then we need to loop through each file within the sub-folder, and generate our new file names similar to what we did with the folders
foreach ($file in $seriesfolder) {
$fullstop = $file.Name.IndexOf(".")
$number = $file.Name.SubString(0,$fullstop)
if ($number.Length -lt 2) {
$number = "0$number"
}
$newname = $parentname + " - S" + $newfoldername + "E" + $number + " - $($file.Name)"
"new file name = $newname"
I use another console output line here
"new file name = $newname"
to make sure the new file name is what I expect it to be
You’ll also notice here that instead of using a
.split('.')[0]
command to retrieve the number at the beginning of the file name, I’ve used a different method which combines.IndexOf(".")
and.SubString
. This is purely to show that there are multiple methods, as there often are with scripting, of doing the same/similar things.
So same as before, what we’ve done here is grab the number from the file name, prefix it with a “0” if it’s less than two digits long, then compiled our new name by using the $newname = $parentname + " - S" + $newfoldername + "E" + $number + " - $($file.Name)"
line, which will result in the file name looking something like this:
Tutorial - S01E01 - Video.mp4
Perfect! The only thing that’s left to do now is actually apply the rename to the files and folders. For the file rename, we simply add:
$file | Rename-Item -NewName $newname
And for the folder, we need to come out of our foreach ($file in $seriesfolder)
loop, then rename the folder (otherwise, the rename folder operation would repeat itself every time it moves onto a new file, but we only need to rename the folder once).
}
$folder | Rename-Item -NewName $newfoldername
A final closing }
will close the original foreach($folder in $folders)
loop, and then we’re done.
The end result should look something like this:
$parentname = "Tutorial"
$parentpath = "\\myplexserver\Tutorials\$parentname"
$folders = gci $parentpath
foreach ($folder in $folders) {
$foldername = $folder.Name
$foldernumber = $foldername.split('.')[0]
$newfoldername = "$foldernumber"
if ($newfoldername.Length -lt 2) {
$newfoldername = "0$newfoldername"
"new folder name = $newfoldername"
}
$seriesfolder = gci "$parentpath\$foldername"
foreach ($file in $seriesfolder) {
$fullstop = $file.Name.IndexOf(".")
$number = $file.Name.SubString(0,$fullstop)
if ($number.Length -lt 2) {
$number = "0$number"
}
$newname = $parentname + " - S" + $newfoldername + "E" + $number + " - $($file.Name)"
"new file name = $newname"
$file | Rename-Item -NewName $newname
}
$folder | Rename-Item -NewName $newfoldername
}
And there you have it, all folders/files renamed within a matter of seconds, instead of the however-long it would have taken to manually go through each one.
comments powered by Disqus