Microcode: Cleaning up DVR with Get-RecordedTV

The first simple way we can approach cleaning up DVR is by making the assertion that shows you don't want as much you won't record as often.  Suppose you record a movie once, or a game, or the pilot of a really bad TV show.   After a month or so it's still on your hard drive, taking up space but for some reason avoiding the Windows Media Center's cleanup bots.

Now that we've got a fairly mature Get-RecordedTV, we can use it to delete a certain number of files from your collection until we reach a desired amount of freed space.

function Remove-DVRBySeries($cleanupSize = 1gb, $episodeCount = 1)
{
    $shows = @()
    # Pipe the results of Get-RecordedTV so that we can see progress
    $perc = 0

    Get-RecordedTV | Foreach-Object {
        $perc+=5
        if ($perc -gt 100) { $perc = 0 }
        Write-Progress "Getting DVR Metadata" "$($_.Series) - $($_.Episode) - $($_.Channel)" -perc $perc
        $shows+=$_
    }
    $showsbySeries = $shows | Group-Object Series
    $allSeries = $showsBySeries |
      Where-Object { $_.Count -le $episodeCount} |
      Sort-Object Count
    foreach ($series in $allSeries)
    {       
        foreach ($e in $series.Group) {
            $response =Read-Host "Delete $($e.Series) - $($e.Episode) (Yes/No)"
            if ($response -ilike "*Yes*") {
                if ($e.File) {
                    Write-Progress "Deleting $($e.Series) - $($e.Episode)" `
                       "$($e.Size / 1mb) megabytes saved - $(($cleanupSize - $e.Size)/1mb) remaining"
                    Remove-Item $e.File
                    $cleanupSize-=$e.Size
                } else {
                    Write-Error "$($e.Series) - $($e.Episode) File Not Found"
                }
            } else {
                Write-Progress "Skipping show by user request" "$($e.Series) - $($e.Episode)"           
            }
            if ($cleanupSize -le 0) { return }
        }
    }
}

 

This script will remove shows with one or fewer episodes until it has saved 1gb of space.  If you want to make it save more, use the cleanupSize parameter.  If you want it to check series with more episodes, use the -episodeCount parameter. It will ask to make sure you want to delete each show, and will stop once it has saved you enough space.

The script above uses a lot of simple PowerShell benefits.  Let's take a closer look at each:

  • CleanupSize uses 1gb as its default.  In PowerShell, you can use gb,mb,and kb as numbers, e.g. 1gb, 10mb, or 640kb
  • By piping Get-RecordedTV to ForEach-Object, I am able to store the results of Get-RecordedTV as they come in, instead of waiting for all of them to be completed, I can use Write-Progress to display each show as it comes in.  Since I don't know how long it will take, I can just wrap the progress bar around whenever I get to 100%.
  • Group-Object will group all of the shows by the value of the series property
  • Sort-Object is used to sort the results of Group-Object by the number of items in each group (in our case, the number of recorded episodes of a series)
  • Write-Progress is used again to update the user as files are deleted or skipped
  • Read-Host displays a prompt and asks for user input
  • -ilike is a case insentive like, so $response -ilike will match "Yes", "yeS', or "Yes Sir", sadly, the logic will also catch "Yes, I mean No!"
  • Write-Error politely informs me that a file cannot be deleted, but does not stop execution of the script (this the  important difference between Write-Error and throw)

That's it.  We've brought one train of thought to an end.  With this script, I was able to quickly and easily cleanup almost 40gb of shows that I wasn't watching.  I hope it helps you clean up your hard drive, and I hope that explaining how to get here has increased your understanding of PowerShell scripting and problem solving.

Hope this helps,

James