Posterizarr PowerShell Scripts Architecture & Documentation
This document provides a comprehensive technical overview of all .ps1 (PowerShell) scripts within the Posterizarr project. It is intended for developers and contributors looking to understand the codebase architecture, the purpose of each module, and where to add or modify features when submitting Pull Requests.
Note: Scripts located in
node_modules(under thewebuifolder) are excluded from this documentation as they belong to third-party Node.js dependencies.
Architecture Overview
Posterizarr relies on a modular PowerShell architecture:
- Entry Points (
Root&modes): Scripts that initialize the environment and dictate the operational flow (e.g., processing an entire library vs. a single item from an Arr webhook). - Core Settings (
core): Setup prerequisites and define global configuration state ($global:variables). - Business Logic (
functions): Reusable modules split by domain (API integrations, Image Processing, System Utilities, Notifications).
1. Root Execution Scripts
Posterizarr.ps1
Purpose: The primary entry point for manual execution or scheduled tasks. It bootstraps the application, dot-sources the required modules, and launches the appropriate mode script based on user arguments or configuration.
Start.ps1
Purpose: An initialization and maintenance wrapper, commonly used in Docker or scheduled environments. Key Functions:
ScriptSchedule: Keeps the script running in a loop based on the user's configured schedule interval.GetLatestScriptVersion/CompareScriptVersion: Checks the GitHub API for new releases and compares it against the local version.CopyAssetFiles: Ensures that default assets (like borders or overlay images) are copied to the active directory.CheckJson/Ensure-WebUIConfig: Validates and repairs theconfig.jsonschema and Web UI configurations before the main process starts.
2. Core Modules (modules\core\)
PrerequisitesCheck.ps1
Purpose: A linear script that validates the host environment before execution. It ensures that necessary commands (like magick), environment variables, and folder structures exist.
Contribution Tip: If you introduce a new binary dependency or require a specific OS permission, add the check here.
Variables.ps1
Purpose: Initializes and defines the $global: scope variables and configuration paths. It reads the user's config.json and maps it to variables used throughout the script.
Contribution Tip: If you add a new configuration parameter to config.json, map it to a global variable in this script so other modules can consume it safely.
3. Domain Functions (modules\functions\)
ApiHandlers.ps1
Purpose: The integration layer for external metadata providers. Handles HTTP requests to TMDB, TVDB, Fanart, and IMDB to fetch raw images and logos. Key Functions:
GetTMDBLogo,GetTVDBLogo,GetFanartLogo: Queries the respective APIs for clearlogos. They handle language priorities and vote sorting based on global configs (uses theCelerium.FanartTVmodule for Fanart integrations).GetTMDBMoviePoster,GetTMDBShowBackground, etc.: Functions specifically tailored to endpoint structures for fetching raw posters and backgrounds.GetPlexArtwork: Fetches metadata and current artwork URLs from Plex.
BackupRestore.ps1
Purpose: Contains massive library iteration operations for backup, restore, and reset features. Key Functions:
MassDownloadPlexArtwork,MassDownloadJellyEmbyArtwork: Loops over media libraries to pull down existing artwork for local processing.MassRestorePlexArtwork,MassRestoreJellyEmbyArtwork: Pushes artwork from the local backup directory directly to the media server.
JellyEmby.ps1
Purpose: Core logic and API integration for Jellyfin and Emby media servers. Key Functions:
CheckJellyfinAccess,CheckEmbyAccess: Validates connection and API keys for the respective servers.
Plex.ps1
Purpose: Core logic and API integration for the Plex media server. Key Functions:
CheckPlexAccess: Validates API keys and connection to the Plex server.GetPlexArtworkUrl: Fast-scans Plex URLs for existing EXIF data.
AssetReset.ps1
Purpose: Handles library-wide asset resets, deleting custom metadata to restore defaults. Key Functions:
Reset-PlexLibraryPictures,Reset-PlexLibraryLogos: Triggers library-wide resets to default metadata.
AssetUpload.ps1
Purpose: Consolidates the asset pushing logic across different media servers. Key Functions:
Push-PlexAsset,Push-EmbyAsset: Direct asset pushing to individual items on Plex/Emby.UploadOtherMediaServerArtwork: Handles pushing generated image assets to Jellyfin or Emby.
Sync.ps1
Purpose: Cross-server syncing logic to keep multiple media servers consistent. Key Functions:
SyncPlexArtwork: Compares artwork between Plex and Jellyfin/Emby and pushes missing/updated assets across servers.
AssetCache.ps1
Purpose: Responsible for rapidly indexing the asset directory. Key Functions:
Get-AssetHashtable: Centralized, highly optimized function that uses native.NETEnumerateFilesto recursively build a hashtable of all available local posters and artworks. It calculates total sizes and determines whether artwork exists without triggering slow file-system scans.
CoreGeneration.ps1
Purpose: The orchestration engine for image creation. It glues together ApiHandlers and ImageMagick.
Key Functions:
Invoke-MoviePosterCreation: Orchestrates the movie poster workflow: Fetches the raw background -> Determines text/logo overlay -> CallsImageMagickto apply borders/text -> Returns the path to the completed poster.Invoke-ShowPosterCreation: Similar orchestration for TV Shows and Season posters.Invoke-TitleCardCreation: Orchestrates episode-level Title Card generation. Searches for TMDB/TVDB/Plex artwork with provider fallbacks, processes the image (resizing, text rendering, borders), and pushes the result to the media server.
ImageMagick.ps1
Purpose: A wrapper around the magick CLI. It abstracts the complex ImageMagick arguments into reusable PowerShell functions.
Key Functions:
InvokeMagickCommand: The central wrapper that actually executesmagick.exe. Captures stdout/stderr for logging.Get-OptimalPointSize: Dynamically calculates the maximum font size that will fit a given text string within a constrained pixel bounding box. Very useful for title generation.New-TextSizeCacheKey,Set-TextSizeCacheEntry: Caches calculated font sizes to speed up future runs for the same titles.CheckOverlayDimensions,Test-Dimension: Ensures that user-provided border or overlay images match the aspect ratio and resolution of the base poster before combining them.
Notifications.ps1
Purpose: Manages all outbound communications and telemetry. Key Functions:
SendMessage: A router function that determines which notification channels (Discord, Webhooks) are enabled.Build-DiscordPayload,Push-ObjectToDiscord: Constructs the rich embed JSON for Discord webhooks and sends it.Send-UptimeKumaWebhook: Pings a health check endpoint.Send-PosterizarrTelemetry: Sends anonymized usage statistics (if opted-in).
System.ps1
Purpose: General utility and helper functions. Key Functions:
Test-PathPermissions: Validates read/write access to media folders before attempting generation.CheckJson,CheckJsonPaths: Schema validation and path sanitization for config files.RotateLogs,Write-Entry: Centralized logging engine with color-coded console output and file rotation.RedactUrl,RedactKey: Strips API keys and tokens from strings before writing them to log files to ensure security.
4. Operation Modes (modules\modes\)
These scripts represent the different "Modes" the application can run in. They do not define functions but instead represent linear logic flows that dot-source and call the functions described above.
NormalMode.ps1: The default mode. Iterates through all configured media server libraries and processes every item sequentially.ArrMode.ps1: Designed to be triggered by Radarr/Sonarr custom scripts or webhooks. It reads the specific TMDB/TVDB ID passed by the Arr application and processes only that single item.TautulliMode.ps1: Specifically designed to be triggered by Tautulli webhooks (e.g., on 'Recently Added' events) to process newly added items without scanning the entire library.ManualMode.ps1: Processes a specific ID or Title provided manually by the user via CLI arguments.SyncMode.ps1: Syncs generated artwork between different connected media servers (e.g., copying posters from Plex to Jellyfin).EmbyJellyMode.ps1: Logic flow specifically optimized for iterating through Emby/Jellyfin libraries (as opposed to Plex).BackupMode.ps1: Downloads existing artwork from media servers to the local filesystem for backup.RestoreMode.ps1: Pushes existing artwork from the local backup folder directly to your media server, skipping Posterizarr image generation. Note: Running this mode directly (e.g.,pwsh /app/Posterizarr.ps1 -Restore) without any additional filters will automatically attempt to restore ALL assets for ALL items across ALL included libraries.LogoUpdaterMode.ps1: Bypasses poster generation and purely runs a check to fetch and update clearlogos.PosterresetMode.ps1: Deletes Posterizarr-generated images and reverts the media server items back to their default scraped posters.TestingMode.ps1: Used in the Web UI for live previews. It generates test images without connecting to Media Servers, allowing users to safely test border and text configurations. Contains helper functions:New-TestImage-IfNotExistsGet-BorderOverlay-ArgumentsGet-TextOverlay-Arguments
Contribution Guidelines
When making a Pull Request:
- New API sources (like adding Trakt or OMDB) should be placed in
modules\functions\ApiHandlers.ps1. - New Image manipulation logic (like adding a drop-shadow effect) should be added to
modules\functions\ImageMagick.ps1. - If you add a new CLI parameter or Config item, ensure it is parsed in
modules\core\Variables.ps1and validated inmodules\functions\System.ps1. - Use
Write-Entryfor all logging; avoid usingWrite-HostorWrite-Outputdirectly to ensure logs are captured to the log files safely.
Reading Logs (Parallel Processing)
When reading the Scriptlog.log file, especially during parallel execution, you will see entries like:
[2026-07-20 08:33:01] [INFO] [T32] |ApiHandlers.ps1:L.439 | Searching on TMDB for a movie poster - TMDBID: 599960
[INFO]: The log severity level.
- [T32]: The Worker ID (Runspace ID). Because multiple media items are processed in parallel, logs from different items will be mixed together. To track the execution flow of a single item, look for lines that share the exact same Worker ID (e.g., all lines with [T32]).
- |ApiHandlers.ps1:L.439 |: The source script and line number where the log entry was generated.