Public/Compare-PatLibraryContent.ps1
|
function Compare-PatLibraryContent { <# .SYNOPSIS Compares library content before and after a scan to identify changes. .DESCRIPTION Takes two collections of library items (typically from Get-PatLibraryItem) and identifies what was added, removed, or modified between them. Useful for validating that a library scan actually had the expected effect. .PARAMETER Before The collection of library items before the scan. Typically captured with: $before = Get-PatLibraryItem -SectionName 'Movies' .PARAMETER After The collection of library items after the scan. .PARAMETER KeyProperty The property to use as the unique identifier for items. Default: 'ratingKey' (Plex's unique item ID). .EXAMPLE $before = Get-PatLibraryItem -SectionName 'Movies' Update-PatLibrary -SectionName 'Movies' -Path '/mnt/media/Movies/NewMovie' Wait-PatLibraryScan -SectionName 'Movies' $after = Get-PatLibraryItem -SectionName 'Movies' Compare-PatLibraryContent -Before $before -After $after Captures library state, triggers scan, waits, and compares to find changes. .EXAMPLE $changes = Compare-PatLibraryContent -Before $before -After $after $changes | Where-Object ChangeType -eq 'Added' Filters to show only newly added items. .EXAMPLE $changes = Compare-PatLibraryContent -Before $before -After $after $changes | Where-Object ChangeType -eq 'Removed' Filters to show items that were removed (e.g., after deleting files and rescanning). .EXAMPLE $changes = Compare-PatLibraryContent -Before $before -After $after -KeyProperty 'title' Uses title instead of ratingKey for comparison (useful for testing). .OUTPUTS PSCustomObject[] with properties: - ChangeType: 'Added', 'Removed', or 'Unchanged' - Item: The library item object - Title: The item's title (for convenience) - RatingKey: The item's unique ID #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [AllowNull()] [AllowEmptyCollection()] [object[]] $Before, [Parameter(Mandatory = $true)] [AllowNull()] [AllowEmptyCollection()] [object[]] $After, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $KeyProperty = 'ratingKey' ) # Handle null/empty inputs $beforeItems = if ($Before) { @($Before) } else { @() } $afterItems = if ($After) { @($After) } else { @() } Write-Verbose "Comparing $($beforeItems.Count) items (before) with $($afterItems.Count) items (after)" # Build lookup hashtables for efficient comparison $beforeLookup = @{} foreach ($item in $beforeItems) { $key = $item.$KeyProperty if ($key) { $beforeLookup[$key.ToString()] = $item } } $afterLookup = @{} foreach ($item in $afterItems) { $key = $item.$KeyProperty if ($key) { $afterLookup[$key.ToString()] = $item } } $results = @() # Find added items (in After but not in Before) foreach ($key in $afterLookup.Keys) { if (-not $beforeLookup.ContainsKey($key)) { $item = $afterLookup[$key] $results += [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.LibraryChange' ChangeType = 'Added' Item = $item Title = $item.title RatingKey = $item.ratingKey } } } # Find removed items (in Before but not in After) foreach ($key in $beforeLookup.Keys) { if (-not $afterLookup.ContainsKey($key)) { $item = $beforeLookup[$key] $results += [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.LibraryChange' ChangeType = 'Removed' Item = $item Title = $item.title RatingKey = $item.ratingKey } } } # Log summary $added = ($results | Where-Object ChangeType -eq 'Added').Count $removed = ($results | Where-Object ChangeType -eq 'Removed').Count Write-Verbose "Found $added added items and $removed removed items" # Return results (may be empty if no changes) $results } |