Created
November 18, 2023 19:00
-
-
Save cybersholt/6f3e3fa4f7339393e63cc6420c3ba643 to your computer and use it in GitHub Desktop.
Find Duplicates in Plex for PowerShell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Plex duplicate finder for PowerShell written by Sean W. https://cybersholt.com | |
# Copyright (c) 2023 Sean W. <cybersholt@gmail.com> All rights reserved. | |
# Use of this source code is governed by a BSD-style | |
# license that can be found in the LICENSE file. | |
# SPDX-License-Identifier: BSD-3-Clause | |
# Function to test connectivity to the Plex server | |
Function Test-PlexConnectivity { | |
param( | |
[string]$server, | |
[hashtable]$headers | |
) | |
try { | |
# Attempt to retrieve the main Plex page | |
Invoke-RestMethod -Uri $server -Headers $headers -ErrorAction Stop | |
return $true | |
} | |
catch { | |
Write-Host "β Fatal Error: Failed to connect to Plex Server: $_" | |
return $false | |
} | |
} | |
# Function to extract the Plex token from the network file | |
Function Get-PlexTokenFromNetworkFile { | |
param( | |
[string]$networkFilePath, | |
[string]$fallbackToken | |
) | |
if (Test-Path -Path $networkFilePath) { | |
$fileContent = Get-Content -Path $networkFilePath | |
$tokenLine = $fileContent | Where-Object { $_ -match '^PLEX_OLD_TOKEN="(.*)"$' } | |
if ($null -ne $tokenLine) { | |
$matches[1] | |
Write-Host "π Got Plex token from the network." | |
} | |
else { | |
$fallbackToken | |
Write-Host "βπ Failed parsing Plex token from the network. Using fallback token." | |
} | |
} | |
else { | |
Write-Host "βπ Network path not found or inaccessible. Using fallback token." | |
$fallbackToken | |
} | |
} | |
# Function to get the sections from Plex server | |
Function Get-PlexSections { | |
param( | |
[string]$server, | |
[hashtable]$headers | |
) | |
# Get all library sections | |
$sections = Invoke-RestMethod -Uri "$server/library/sections" -Headers $headers | |
return $sections.MediaContainer.Directory | |
} | |
# Function to get items with more than one file in a section | |
Function Get-MultiFileItems { | |
param( | |
[string]$server, | |
[string]$key, | |
[hashtable]$headers | |
) | |
# Get all items in the section | |
$items = Invoke-RestMethod -Uri "$server/library/sections/$key/all" -Headers $headers | |
$itemCount = $items.MediaContainer.Video.Count | |
$librarySectionTitle = $items.MediaContainer.librarySectionTitle; | |
Write-Host "Found $itemCount items in $librarySectionTitle section." | |
$multiFileItems = @() | |
# Filter items with more than one media part | |
foreach ($item in $items.MediaContainer.Video) { | |
if ($item.Media.Part.Count -gt 1) { | |
$multiFileItems += $item | |
} | |
} | |
return $multiFileItems | |
} | |
Write-Host "π Starting Plex Duplicate Finder" | |
# Network file path | |
$networkFilePath = "\\REDACTED\torrent\config\qBittorrent\move_files.sh" | |
# Fallback Plex token | |
$plexToken = 'YOUR_FALLBACK_PLEX_TOKEN' | |
# Get Plex token from network file or use fallback | |
$plexToken = Get-PlexTokenFromNetworkFile -networkFilePath $networkFilePath -fallbackToken $plexToken | |
# Your Plex server's address, with port if necessary | |
$plexServer = 'http://localhost:32400' | |
# Define the headers with your Plex token | |
$headers = @{ | |
"X-Plex-Token" = $plexToken | |
} | |
# Test connectivity to the Plex server | |
if (-not (Test-PlexConnectivity -server $plexServer -headers $headers)) { | |
Write-Host "β Fatal Error: Exiting script due to failed connectivity test." | |
exit | |
} | |
Write-Host "βοΈ Connection successful, fetching sections..." | |
# Get sections | |
$sections = Get-PlexSections -server $plexServer -headers $headers | |
# Display the number of sections found | |
$sectionCount = $sections.Count | |
Write-Host "π Found $sectionCount sections." | |
# Check each section for multi-file items | |
foreach ($section in $sections) { | |
# Cast the element to [xml] to access the 'key' attribute | |
$key = $section.GetAttribute("key") | |
$multiFileItems = Get-MultiFileItems -server $plexServer -key $key -headers $headers | |
foreach ($item in $multiFileItems) { | |
Write-Host "π Title: $($item.title), Files: $($item.Media.Part.Count)" | |
} | |
} | |
# At the end of the script, ensure there's output even if no duplicates are found | |
if ($sections -eq 0) { | |
Write-Host "βΉ No duplicates found." | |
} | |
Write-Host "β Finished" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment