Created
February 27, 2026 02:58
-
-
Save joshooaj/281be38af1daee5bcef1250fc215a512 to your computer and use it in GitHub Desktop.
Rename XProtect media database tables by replacing the old device id with a new id in folder and config.xml files.
This file contains hidden or 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
| <# | |
| .SYNOPSIS | |
| Replace an old device ID with a new ID in a media database folder | |
| .DESCRIPTION | |
| If you have old XProtect recordings that you want to be able to playback in | |
| XProtect, but the old recordings were made under a different device ID than | |
| your cameras have now, you MIGHT be able to use this script to replace the | |
| old device ID with the new device ID. | |
| Before using this, you should have a secure backup of the recordings you want | |
| to modify. You should not continue until you have a secure backup. | |
| This script replaces the old ID with the new ID in folder names, and in | |
| config.xml files. You must take care of discovering the old and new ID's | |
| prior to using this script. It's likely you can do this by exporting the | |
| camera addresses and ID's from the old and new systems using MilestonePSTools | |
| and writing a script to look up the new ID for each old ID before passing | |
| them to this script. | |
| You may or may not have success if your media database(s) | |
| are signed or encrypted. | |
| After running this script, you will need to force the destination recording | |
| server to reindex the recordings in the media database. | |
| .PARAMETER Path | |
| Specifies the path to a folder containing media database tables to be renamed. | |
| .PARAMETER OldId | |
| Specifies the old device ID to be replaced. | |
| .PARAMETER NewId | |
| Specifies the new device ID to substitute where the old device ID is found in | |
| folder names or within config.xml files. | |
| .NOTES | |
| USE AT YOUR OWN RISK. Milestone Systems accepts no responsibility for damages | |
| caused as a result of using this script either as intended, or not as intended. | |
| You should NOT use this script unless you have a secure backup of the recordings | |
| you intend to use this on. If you cause irreversible damage to your media database | |
| files without a secure backup of them, you may permanently lose access to your | |
| recordings. | |
| .EXAMPLE | |
| .\Rename-MediaDBTables.ps1 -Path E:\testing\archive\ -OldId 125d032d-0866-4e49-b959-e7d478d5320f -NewId 47ceabcd-4332-4eaf-a99a-6236bfbe56a5 | |
| Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines | |
| #> | |
| [CmdletBinding(SupportsShouldProcess)] | |
| param( | |
| [Parameter(Mandatory)] | |
| [string] | |
| $Path, | |
| [Parameter(Mandatory)] | |
| [guid] | |
| $OldId, | |
| [Parameter(Mandatory)] | |
| [guid] | |
| $NewId | |
| ) | |
| $ErrorActionPreference = 'Stop' | |
| $InformationPreference = 'Continue' | |
| Write-Information "Replacing $OldId with $NewId in all directory names where $OldId is found..." | |
| Get-ChildItem $Path -Directory -Recurse | Where-Object { | |
| $_.Name -match $OldId | |
| } | ForEach-Object { | |
| $newName = $_.Name -replace $OldId.ToString(), $NewId.ToString() | |
| $_ | Rename-Item -NewName $newName -WhatIf:$WhatIfPreference -Verbose:($VerbosePreference -eq 'Continue') | |
| } | |
| Write-Information "Replacing $OldId with $NewId in all config.xml files where $OldId is found..." | |
| Get-ChildItem (Join-Path $Path 'config.xml') -File -Recurse | Where-Object { | |
| $_ | Select-String -SimpleMatch $OldId.ToString() | |
| } | ForEach-Object { | |
| $content = $_ | Get-Content -Raw | |
| $content = $content -replace $OldId.ToString(), $NewId.ToString() | |
| Set-Content -LiteralPath $_.FullName -Value $content -WhatIf:$WhatIfPreference -Verbose:($VerbosePreference -eq 'Continue') | |
| } | |
| Write-Information "Next, you should copy the renamed directories into the destination media database directory unless '$Path' IS the destination media database directory." | |
| Write-Information "Then, you must stop the recording server service, and delete the following files to force a full media reindex:" | |
| Write-Information "- In the root of the media database directory:" | |
| Write-Information " - cache.xml" | |
| Write-Information " - storage.passwords.sqlite3" | |
| Write-Information " - synckey" | |
| Write-Information "- In C:\ProgramData\Milestone\XProtect Recording Server\Secure\TablesDb\:" | |
| Write-Information " - All files" | |
| Write-Information "" | |
| Write-Information "On the next start of the recording server service, it will scan the content of the media database and rebuild the index from scratch and make the reintegrated recordings available for playback." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment