Skip to content

Instantly share code, notes, and snippets.

@joshooaj
Last active May 11, 2026 21:58
Show Gist options
  • Select an option

  • Save joshooaj/8c0ee192dfd91d6bc1541c323ee39a86 to your computer and use it in GitHub Desktop.

Select an option

Save joshooaj/8c0ee192dfd91d6bc1541c323ee39a86 to your computer and use it in GitHub Desktop.
Get a report of which cameras are in which views on an XProtect VMS
function Resolve-VmsViewGroupPath {
[CmdletBinding()]
[MilestonePSTools.RequiresVmsConnection()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[Alias('DeviceGroup')]
[MilestonePSTools.ValidateVmsItemType('ViewGroup')]
[VideoOS.Platform.ConfigurationItems.IConfigurationItem]
$Group
)
begin {
Assert-VmsRequirementsMet
$ctor = $null
$sb = [text.stringbuilder]::new()
}
process {
if ($null -eq $ctor -or $ctor.ReflectedType -ne $Group.GetType()) {
$ctor = $Group.GetType().GetConstructor(@([videoos.platform.serverid], [string]))
}
try {
$current = $Group
$null = $sb.Clear().Insert(0, "/$($current.Name -replace '(?<!`)/', '`/')")
while ($current.ParentItemPath -ne '/') {
$current = $ctor.Invoke(@($current.ServerId, $current.ParentItemPath))
$null = $sb.Insert(0, "/$($current.Name -replace '(?<!`)/', '`/')")
}
$sb.ToString()
} catch {
throw
}
}
}
$resolvedPaths = @{}
Get-VmsViewGroup -Recurse | Get-VmsView | ForEach-Object {
if (!$resolvedPaths.ContainsKey($_.ParentItemPath)) {
$resolvedPaths[$_.ParentItemPath] = $_ | Get-VmsParentItem | Resolve-VmsViewGroupPath
}
$viewLocation = $resolvedPaths[$_.ParentItemPath] + '/' + $_.Name
$record = [ordered]@{
View = $_.Name
Location = $viewLocation
Position = $null
Camera = $null
CameraId = $null
ViewItemType = $null
}
$_.ViewItemChildItems | ForEach-Object {
$id = $cam = $null
$xml = [xml]$_.ViewItemDefinitionXml
$camera = switch ($xml.viewitem.displayname) {
'Camera ViewItem' {
$id = $xml.viewitem.iteminfo.cameraid
if (![string]::IsNullOrEmpty($id)) {
$cam = Get-VmsCamera -Id $xml.viewitem.iteminfo.cameraid -ErrorAction SilentlyContinue
}
if ($null -eq $cam) {
[pscustomobject]@{
Name = 'Not found'
Id = $xml.viewitem.iteminfo.cameraid
}
} else {
$cam
}
}
'Access monitor' {
$config = [xml]($xml.viewitem.iteminfo.viewitem.properties.property | Where-Object name -eq 'Configuration').value
$id = $config.configuration.Camera -as [guid]
if ($id) {
$cam = Get-VmsCamera -Id $id -ErrorAction SilentlyContinue
} else {
Write-Error "Failed to extract the camera ID from Access monitor view item configuration. Inspect the XML document in this ErrorRecord's TargetObject." -TargetObject $xml.OuterXml
}
if ($null -eq $cam) {
[pscustomobject]@{
Name = 'Not found'
Id = ''
}
} else {
$cam
}
}
'Empty ViewItem' {
[pscustomobject]@{
Name = 'Empty'
Id = ''
}
}
default {
[pscustomobject]@{
Name = ''
Id = ''
}
}
}
$record.Position = $_.ViewItemPosition
$record.Camera = $camera.Name
$record.CameraId = $camera.Id
$record.ViewItemType = (($xml.viewitem.type -split ',')[0] -split '\.')[-1]
[pscustomobject]$record
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment