Powershell Script to write M3U playlists

Nearly 20 years ago, I came upon a VB script that would recursively traverse through a folder tree and create a M3U playlist for each folder respectively. I slightly modified the script over the years to fit my requirements, and have since ported it to PowerShell. This script will look for MP3 and WMA files and create a M3U playlist file for each folder.

For the desired results, put the script in the root folder of the folder tree where playlists will be created.

For example: Put WriteM3u.ps1 into D:\My Music\Elvis to generate playlists for each subfolder of Elvis.

D:\My Music\Elvis\WriteM3u.ps1
D:\My Music\Elvis\Elvis\elvis.m3u
D:\My Music\Elvis\Clambake\clambake.m3u

Create WriteM3u.ps1

param([switch]$d)

function Write-M3u {
    param($path, $delete)
    
    $count = 0
    $folder = Get-Item $path
    $subfolders = Get-ChildItem $path -Directory
    
    # Recurse into subfolders first
    foreach ($sub in $subfolders) {
        $count += Write-M3u $sub.FullName $delete
    }
    
    # Only write m3u if no files were found in subfolders
    if ($count -eq 0) {
        Write-Host "Scanning `"$path`""
        
        $files = Get-ChildItem $path -File | Where-Object { $_.Extension -match '^\.(mp3|wma)$' }
        
        if ($files.Count -gt 0) {
            # Multi-disc folder handling
            if ($folder.Name -match '^Disc \d$') {
                $m3uName = "$($folder.Parent.Name) ($($folder.Name)).m3u"
            } else {
                $m3uName = "$($folder.Name).m3u"
            }
            
            $m3uPath = Join-Path $path $m3uName
            
            # Existing m3u handling
            if (Test-Path $m3uPath) {
                if ($delete) {
                    Write-Host "... deleting existing file"
                    Remove-Item $m3uPath
                } else {
                    Write-Host "... renaming existing file"
                    Rename-Item $m3uPath "$m3uPath.old"
                }
            }
            
            Write-Host "... writing `"$m3uName`""
            $files.Name | Set-Content $m3uPath -Encoding UTF8
            $count = 1
            
        } else {
            Write-Host "... no mp3/wma files found"
        }
    }
    
    return $count
}

$total = Write-M3u (Get-Location).Path $d
Write-Host "$total files written"
```

**Usage is the same as before**, just save it as `WriteM3u.ps1` and run from the folder:
```
# Normal run (renames existing .m3u to .m3u.old)
.\WriteM3u.ps1

# Delete existing m3u files instead of renaming
.\WriteM3u.ps1 -d