Public/Reports/Get-CameraReport.ps1
function Get-CameraReport { <# .SYNOPSIS Gets a detailed report containing information about all cameras on one or more Recording Servers .DESCRIPTION Gets a [PSCustomObject] with a wide range of properties for each camera found on one or more Recording Servers. When the -RecordingServer parameter is omitted, all cameras on all servers in the currently selected site will be included in the report. Otherwise, only the server(s) included in the -RecordingServer array will enumerated for cameras to include in the report. A number of switches can optionally be included to add information to the default result set. For example, camera passwords are only included when the -IncludePasswords switch is present. .PARAMETER RecordingServer Specifies one Recording Server, or an array of Recording Servers. All cameras on the specified servers will be included in the report. If omitted, all cameras from all Recording Servers on the currently selected site will be included in the report. To include only cameras from a subset of Recording Servers, use Get-RecordingServer to select and filter for the desired servers. .PARAMETER IncludeNetworkState When this switch is present, the host and port from the hardware address of all cameras will be used in a call to Test-NetConnection to determine if a device is reachable or unreachable. Note that if the camera network is unreachable from the location where this command is executed, it will always return 'Offline'. If camera networks are segmented and accessible only by Recording Servers, then you should run this cmdlet directly on the Recording Servers. You can use the RecordingServer parameter to ensure each Recording Server produces a report for only the cameras added to itself. .PARAMETER IncludeActualResolutions When this switch is present, a live and playback image will be requested from the Recording Server for every enabled camera in the report. The resolution in the format WidthxHeight for a single image will be included columns named ActualLiveResolution and ActualRecordingResolution. .PARAMETER IncludeDisabledCameras Disabled cameras, which are considered to be any camera where either the camera, or it's parent Hardware object are disabled in Milestone, are excluded from the report by default. To include properties from disabled cameras in addition to enabled cameras, you must supply this switch. For disabled cameras, we will not attempt to retrieve the Actual*Resolution values or the first and last image timestamps from the media database. .PARAMETER IncludePasswords Passwords are only included in the report when this switch is present. Otherwise, only the UserName value will be included. .PARAMETER IncludePlaybackInfo When present, the IncludePlaybackInfo switch will cause the Get-PlaybackInfo command to be executed on each enabled camera and the first and last image timestamps from the media database will be included in the report. .PARAMETER AdditionalHardwareProperties Specifies an array of setting keys which should be included as columns in the report. The available keys vary by hardware driver. You can discover the available columns using the Get-HardwareSetting command. .PARAMETER AdditionalCameraProperties Specifies an array of setting keys which should be included as columns in the report. The available keys vary by hardware driver. You can discover the available columns using the Get-CameraSetting -General command. .EXAMPLE Get-RecordingServer -Name NVR01 | Get-CameraReport -IncludePasswords -AdditionalHardwareProperties HTTPSEnabled Generates a report including all cameras on NVR01, and the report will include hardware passwords, and the HTTPSEnabled value for all hardware devices which have this setting available. #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline)] [VideoOS.Platform.ConfigurationItems.RecordingServer[]] $RecordingServer, [Parameter()] [switch] $IncludeNetworkState, [Parameter()] [switch] $IncludeActualResolutions, [Parameter()] [switch] $IncludeDisabledCameras, [Parameter()] [switch] $IncludePasswords, [Parameter()] [switch] $IncludePlaybackInfo, [Parameter()] [string[]] $AdditionalHardwareProperties, # Additional camera setting values to retrieve using exact key names [Parameter()] [string[]] $AdditionalCameraProperties ) process { $states = Get-ItemState -CamerasOnly $networkStates = @{} $storageRetention = @{} $RecordingServer = if ($null -eq $RecordingServer) { Get-RecordingServer } else { $RecordingServer } foreach ($rec in $RecordingServer) { foreach ($hw in $rec | Get-Hardware) { if ($hw.Enabled -or $IncludeDisabledCameras) { $driver = $hw | Get-HardwareDriver $hwSettings = $hw | Get-HardwareSetting $pass = if ($IncludePasswords) { $hw | Get-HardwarePassword } else { $null } } foreach ($cam in $hw | Get-Camera) { $enabled = $hw.Enabled -and $cam.Enabled if (-not $enabled -and -not $IncludeDisabledCameras) { continue } $camSettings = $cam | Get-CameraSetting -General $liveSize = $null $playbackSize = $null if ($enabled -and $IncludeActualResolutions) { $live = $cam | Get-Snapshot -Live -LiveTimeoutMS 10000 $playback = $cam | Get-Snapshot -Behavior GetEnd $liveSize = if ($null -ne $live.Content -and $live.Content.Length -gt 0) { "$($live.Width)x$($live.Height)" } else { $null } $playbackSize = if ($null -ne $playback.Bytes -and $playback.Bytes.Length -gt 0) { "$($playback.Width)x$($playback.Height)" } else { $null } } $liveStream = $cam | Get-Stream -LiveDefault $recordedStream = $cam | Get-Stream -Recorded $liveStreamName = $liveStream.StreamReferenceIdValues.Keys | ForEach-Object { if ($liveStream.StreamReferenceId -eq $liveStream.StreamReferenceIdValues[$_]) { $_ } } $recordedStreamName = $recordedStream.StreamReferenceIdValues.Keys | ForEach-Object { if ($recordedStream.StreamReferenceId -eq $recordedStream.StreamReferenceIdValues[$_]) { $_ } } $liveStreamSettings = $cam.DeviceDriverSettingsFolder.DeviceDriverSettings[0].StreamChildItems | Where-Object DisplayName -eq $liveStreamName $recordedStreamSettings = $cam.DeviceDriverSettingsFolder.DeviceDriverSettings[0].StreamChildItems | Where-Object DisplayName -eq $recordedStreamName $motion = $cam.MotionDetectionFolder.MotionDetections[0] $storage = $rec.StorageFolder.Storages | Where-Object Path -eq $cam.RecordingStorage if (!$storageRetention.ContainsKey($cam.RecordingStorage)) { if ($storage.ArchiveStorageFolder.ArchiveStorages.Count -eq 0) { $storageRetention.$($cam.RecordingStorage) = $storage.RetainMinutes } else { $storageRetention.$($cam.RecordingStorage) = $storage.ArchiveStorageFolder.ArchiveStorages | Sort-Object RetainMinutes -Descending | Select-Object -First 1 -ExpandProperty RetainMinutes } } $retention = $storageRetention.$($cam.RecordingStorage) $state = ($states | Where-Object { $_.FQID.ObjectId -eq $cam.Id }).State $networkState = $networkStates.($hw.Id) if ($IncludeNetworkState -and $null -eq $networkState) { $networkState = 'Online' if ($state -ne 'Responding') { $uri = [Uri]$hw.Address $responding = Test-NetConnection -ComputerName $uri.Host -Port $uri.Port -InformationLevel Quiet if (-not $responding) { $networkState = 'Offline' } } $networkStates.($hw.Id) = $networkState } $obj = [PSCustomObject]@{ CameraName = $cam.Name Channel = $cam.Channel Enabled = $hw.Enabled -and $cam.Enabled State = $state NetworkState = $networkState LastModified = $cam.LastModified CameraId = $cam.Id HardwareName = $hw.Name HardwareId = $hw.Id RecorderName = $rec.Name RecorderHostName = $rec.HostName RecorderId = $rec.Id Model = $hw.Model Driver = $driver.Name Address = $hw.Address UserName = $hw.UserName Password = $pass MAC = $hwSettings.MacAddress LiveStream = $liveStreamName LiveCodec = GetCodecValueFromStream $liveStreamSettings LiveResolution = GetResolutionValueFromStream $liveStreamSettings LiveFPS = GetFpsValueFromStream $liveStreamSettings RecordingStream = $recordedStreamName RecordingCodec = GetCodecValueFromStream $recordedStreamSettings RecordingResolution = GetResolutionValueFromStream $recordedStreamSettings RecordingFPS = GetFpsValueFromStream $recordedStreamSettings ActualLiveResolution = $liveSize ActualRecordingResolution = $playbackSize RecordingEnabled = $cam.RecordingEnabled RecordKeyframesOnly = $cam.RecordKeyframesOnly PreBufferEnabled = $cam.PrebufferEnabled PreBufferSeconds = $cam.PrebufferSeconds PreBufferInMemory = $cam.PrebufferInMemory StorageName = $storage.Name StoragePath = [IO.Path]::Combine($storage.DiskPath, $storage.Id) StorageRetentionMinutes = $retention MotionEnabled = $motion.Enabled MotionKeyframesOnly = $motion.KeyframesOnly MotionDetectionMethod = $motion.DetectionMethod MotionProcessTime = $motion.ProcessTime MotionManualSensitivity = $motion.ManualSensitivityEnabled MotionMetadataEnabled = $motion.GenerateMotionMetadata MotionHardwareAcceleration = $motion.HardwareAccelerationMode } if ($IncludePlaybackInfo) { $obj | Add-Member -MemberType NoteProperty -Name "OldestImageUtc" -Value $null $obj | Add-Member -MemberType NoteProperty -Name "LatestImageUtc" -Value $null $obj | Add-Member -MemberType NoteProperty -Name "MeetsRetentionPolicy" -Value $null try { $info = $cam | Get-PlaybackInfo -ErrorAction Stop $obj.OldestImageUtc = $info.Begin $obj.LatestImageUtc = $info.End $expectedRetention = [datetime]::UtcNow.AddMinutes(($retention * -1)) $obj.MeetsRetentionPolicy = $info.Begin -le $expectedRetention } catch { Write-Warning "Get-PlaybackInfo failed: $($_.Exception.Message)" } } foreach ($p in $AdditionalHardwareProperties) { $obj | Add-Member -MemberType NoteProperty -Name "Custom_$p" -Value $hwSettings.$p } foreach ($p in $AdditionalCameraProperties) { $obj | Add-Member -MemberType NoteProperty -Name "Custom_$p" -Value $camSettings.$p } $obj } } } } } |