Public/Import-PatServerToken.ps1
|
function Import-PatServerToken { <# .SYNOPSIS Migrates plaintext tokens to SecretManagement vault. .DESCRIPTION Scans server configurations for plaintext tokens stored in servers.json and migrates them to a SecretManagement vault for secure storage. After successful migration, removes the plaintext token from the configuration file. Requires Microsoft.PowerShell.SecretManagement module to be installed and at least one vault to be registered. .PARAMETER ServerName Optional name of a specific server to migrate. If not specified, migrates all servers with plaintext tokens. .PARAMETER PassThru Returns migration result objects showing the status of each server. .EXAMPLE Import-PatServerToken Migrates all plaintext tokens to the vault. .EXAMPLE Import-PatServerToken -ServerName 'Home' Migrates only the 'Home' server's token to the vault. .EXAMPLE Import-PatServerToken -PassThru Migrates all tokens and returns status objects for each server. .EXAMPLE Import-PatServerToken -WhatIf Shows which tokens would be migrated without making changes. .OUTPUTS PlexAutomationToolkit.TokenMigrationResult (with -PassThru) Objects with properties: - ServerName: Name of the server - Status: 'Migrated', 'Skipped', or 'Failed' - Message: Description of the result .NOTES Before running this command, ensure you have: 1. Installed Microsoft.PowerShell.SecretManagement: Install-Module Microsoft.PowerShell.SecretManagement 2. Installed a vault extension (e.g., SecretStore): Install-Module Microsoft.PowerShell.SecretStore 3. Registered the vault: Register-SecretVault -Name 'SecretStore' -ModuleName Microsoft.PowerShell.SecretStore #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] param ( [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string] $ServerName, [Parameter(Mandatory = $false)] [switch] $PassThru ) begin { # Check vault availability if (-not (Get-PatSecretManagementAvailable)) { throw "SecretManagement is not available. Install Microsoft.PowerShell.SecretManagement and register a vault first. See help for Import-PatServerToken for setup instructions." } } process { try { $configuration = Get-PatServerConfiguration -ErrorAction Stop $results = @() $modified = $false # Determine which servers to process $serversToMigrate = if ($ServerName) { $server = $configuration.servers | Where-Object { $_.name -eq $ServerName } if (-not $server) { throw "Server '$ServerName' not found in configuration" } @($server) } else { @($configuration.servers) } foreach ($server in $serversToMigrate) { # Check if server has a plaintext token if (-not ($server.PSObject.Properties['token'] -and -not [string]::IsNullOrWhiteSpace($server.token))) { # Check if already in vault if ($server.PSObject.Properties['tokenInVault'] -and $server.tokenInVault) { $results += [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.TokenMigrationResult' ServerName = $server.name Status = 'Skipped' Message = 'Token already stored in vault' } } else { $results += [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.TokenMigrationResult' ServerName = $server.name Status = 'Skipped' Message = 'No plaintext token to migrate' } } continue } if ($PSCmdlet.ShouldProcess($server.name, 'Migrate token to vault')) { try { $secretName = "PlexAutomationToolkit/$($server.name)" Set-Secret -Name $secretName -Secret $server.token -ErrorAction Stop # Remove inline token and add vault flag $server.PSObject.Properties.Remove('token') if (-not $server.PSObject.Properties['tokenInVault']) { $server | Add-Member -NotePropertyName 'tokenInVault' -NotePropertyValue $true } else { $server.tokenInVault = $true } $modified = $true $results += [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.TokenMigrationResult' ServerName = $server.name Status = 'Migrated' Message = 'Token successfully moved to vault' } Write-Verbose "Migrated token for '$($server.name)' to vault" } catch { $results += [PSCustomObject]@{ PSTypeName = 'PlexAutomationToolkit.TokenMigrationResult' ServerName = $server.name Status = 'Failed' Message = $_.Exception.Message } Write-Warning "Failed to migrate '$($server.name)': $($_.Exception.Message)" } } } # Save configuration if modified if ($modified) { Set-PatServerConfiguration -Configuration $configuration -ErrorAction Stop Write-Verbose "Updated configuration file to remove migrated plaintext tokens" } if ($PassThru) { $results } # Summary $migratedCount = ($results | Where-Object { $_.Status -eq 'Migrated' }).Count $skippedCount = ($results | Where-Object { $_.Status -eq 'Skipped' }).Count $failedCount = ($results | Where-Object { $_.Status -eq 'Failed' }).Count if ($migratedCount -gt 0) { Write-Verbose "Migration complete: $migratedCount migrated, $skippedCount skipped, $failedCount failed" } } catch { throw "Failed to migrate tokens: $($_.Exception.Message)" } } } |