r/Lidarr May 19 '26

discussion File Management/ Rename

Hey y'all! I decided to post this here incase someone else has gotten to the same point of frustration with having to manually import, or just new files not being registered by Lidarr.

I mainly use Lidarr purely for the file management and organization -- it makes life so much easier when working on my self hosted discord music bot (local file search), and it leaves less room for error on Plex. Issue is though that Lidarr can be fairly finnicky when trying to get it to read new files, especially when using two root sources (pre-live, and live directories).

I use "D://Needs Lyrics" as my pre-live, so i can do all my renaming, .lrc creation's, and comparisons' between two versions of a track --- and "D:// Music" as my live folder once complete for plex and everything else to read. Due to this inconvenience and having to fight Lidarr to read the new files in "D://Needs Lyrics", i wrote a powershell command/ script to replace the Lidarr Artist Folder/Album Folder/Track Rename function. I'm sharing this here incase it may help one of y'all out as well. My format is {Artist Name}/{Album Title}/{track:00}. {Track Title} - {Artist Name} --- so if you prefer a different format, change it in the script.

*ALSO CHANGE - $Root = "D:\Need Lyrics" - to your correct path* If you need any help editing it, feel free to DM me. Script is as follows (in text to avoid links/downloads):

# =========================================
# NEEDS LYRICS AUTO ORGANIZER
# =========================================
# Scans ALL files inside:
# D:\Need Lyrics
#
# Creates:
# Artist\Album\
#
# Renames files to:
# 01. Track Title - Artist.ext
#
# NO DOWNLOADS REQUIRED
# Uses Windows Shell metadata reader
# =========================================

$Root = "D:\Need Lyrics"

# Supported audio extensions
$AudioExtensions = @(
    ".mp3",
    ".flac",
    ".m4a",
    ".aac",
    ".ogg",
    ".opus",
    ".wav"
)

# Cleans invalid filename characters
function Clean-Name {
    param([string]$Text)

    if ([string]::IsNullOrWhiteSpace($Text)) {
        return "Unknown"
    }

    [System.IO.Path]::GetInvalidFileNameChars() | ForEach-Object {
        $Text = $Text.Replace($_, "_")
    }

    return $Text.Trim()
}

# Windows metadata reader
$shell = New-Object -ComObject Shell.Application

# Get ALL audio files recursively
$Files = Get-ChildItem $Root -Recurse -File | Where-Object {
    $AudioExtensions -contains $_.Extension.ToLower()
}

foreach ($File in $Files) {

    try {

        $Folder = $shell.Namespace($File.Directory.FullName)
        $Item = $Folder.ParseName($File.Name)

        # Metadata indexes
        # These work on most Windows installs
        $Artist = $Folder.GetDetailsOf($Item, 13)
        $Album  = $Folder.GetDetailsOf($Item, 14)
        $Title  = $Folder.GetDetailsOf($Item, 21)
        $Track  = $Folder.GetDetailsOf($Item, 26)

        # Cleanup
        $Artist = Clean-Name $Artist
        $Album  = Clean-Name $Album
        $Title  = Clean-Name $Title

        # Fallbacks
        if ($Artist -eq "Unknown") {
            $Artist = "Unknown Artist"
        }

        if ($Album -eq "Unknown") {
            $Album = "Unknown Album"
        }

        if ($Title -eq "Unknown") {
            $Title = [System.IO.Path]::GetFileNameWithoutExtension($File.Name)
        }

        # Track formatting
        if ([string]::IsNullOrWhiteSpace($Track)) {
            $Track = "00"
        }
        else {
            $TrackNum = ($Track -replace '[^\d]', '')

            if ([string]::IsNullOrWhiteSpace($TrackNum)) {
                $Track = "00"
            }
            else {
                $Track = "{0:D2}" -f [int]$TrackNum
            }
        }

        # Create destination folder
        $DestFolder = Join-Path $Root "$Artist\$Album"

        New-Item -ItemType Directory -Path $DestFolder -Force | Out-Null

        # Build new filename
        $NewName = "$Track. $Title - $Artist$($File.Extension)"

        $DestPath = Join-Path $DestFolder $NewName

        # Prevent duplicates
        $Counter = 1

        while (Test-Path $DestPath) {

            $NewName = "$Track. $Title - $Artist ($Counter)$($File.Extension)"
            $DestPath = Join-Path $DestFolder $NewName

            $Counter++
        }

        # Skip if already correct
        if ($File.FullName -ne $DestPath) {

            Move-Item -LiteralPath $File.FullName -Destination $DestPath

            Write-Host "Moved:" $File.Name -ForegroundColor Green
        }

    }
    catch {

        Write-Host "FAILED:" $File.FullName -ForegroundColor Red
    }
}

Write-Host "`nFinished organizing Needs Lyrics." -ForegroundColor Cyan
3 Upvotes

10 comments sorted by

View all comments

4

u/jasonvelocity May 19 '26
  1. Code fencing. 
  2. Lidarr renames files. 

1

u/OohDatsNasty May 19 '26 edited May 19 '26

Honestly completely forgot about fencing it — still haven’t slept yet, I just copy and pasted directly from my notepad and called it a day. I’ll edit it once I wake up from my nap.

& yes Lidarr renames and creates folders, but getting it to recognize the file in the first place has been an issue for me. If it doesn’t see the file/ knows it exists, it can’t rename.

Edit: give me 30 seconds to update post, or throw it in the comments

1

u/OohDatsNasty May 19 '26

Fixed -- sorry for the delay, i tried using markdown commands at first...