Public/Reports/Get-CameraRecordingStats.ps1
function Get-CameraRecordingStats { <# .SYNOPSIS Get statistics on the recordings of one or more cameras including the number of recording or motion sequence, the amount of time in the given time period with recordings or motion, and the percent of time in the given time period with recordings or motion. .DESCRIPTION Long description .EXAMPLE PS C:\> Select-Camera | Get-CameraRecordingStats Opens a camera selection dialog and the selected camera will be sent to Get-CameraRecordingStats. The result will be a PSCustomObject with the DeviceID and a nested PSCustomObject under the RecordingStats property name. #> [CmdletBinding()] param( # Specifies the Id's of cameras for which to retrieve recording statistics [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [guid[]] $Id, # Specifies the timestamp from which to start retrieving recording statistics. Default is 7 days prior to 12:00am of the current day. [Parameter()] [datetime] $StartTime = (Get-Date).Date.AddDays(-7), # Specifies the timestamp marking the end of the time period for which to retrieve recording statistics. The default is 12:00am of the current day. [Parameter()] [datetime] $EndTime = (Get-Date).Date, # Specifies the type of sequence to get statistics on. Default is RecordingSequence. [Parameter()] [ValidateSet('RecordingSequence', 'MotionSequence')] [string] $SequenceType = 'RecordingSequence', # Specifies that the output should be provided in a complete hashtable instead of one pscustomobject value at a time [Parameter()] [switch] $AsHashTable, # Specifies the runspacepool to use. If no runspacepool is provided, one will be created. [Parameter()] [System.Management.Automation.Runspaces.RunspacePool] $RunspacePool ) process { if ($EndTime -le $StartTime) { throw "EndTime must be greater than StartTime" } $disposeRunspacePool = $true if ($PSBoundParameters.ContainsKey('RunspacePool')) { $disposeRunspacePool = $false } $pool = $RunspacePool if ($null -eq $pool) { Write-Verbose "Creating a runspace pool" $pool = [runspacefactory]::CreateRunspacePool(1, ([int]$env:NUMBER_OF_PROCESSORS + 1)) $pool.Open() } $scriptBlock = { param( [guid]$Id, [datetime]$StartTime, [datetime]$EndTime, [string]$SequenceType ) $sequences = Get-SequenceData -Path "Camera[$Id]" -SequenceType $SequenceType -StartTime $StartTime -EndTime $EndTime -CropToTimeSpan $recordedMinutes = $sequences | Foreach-Object { ($_.EventSequence.EndDateTime - $_.EventSequence.StartDateTime).TotalMinutes } | Measure-Object -Sum | Select-Object -ExpandProperty Sum [pscustomobject]@{ DeviceId = $Id StartTime = $StartTime EndTime = $EndTime SequenceCount = $sequences.Count TimeRecorded = [timespan]::FromMinutes($recordedMinutes) PercentRecorded = [math]::Round(($recordedMinutes / ($EndTime - $StartTime).TotalMinutes * 100), 1) } } try { $threads = New-Object System.Collections.Generic.List[pscustomobject] foreach ($cameraId in $Id) { $ps = [powershell]::Create() $ps.RunspacePool = $pool $asyncResult = $ps.AddScript($scriptBlock).AddParameters(@{ Id = $cameraId StartTime = $StartTime EndTime = $EndTime SequenceType = $SequenceType }).BeginInvoke() $threads.Add([pscustomobject]@{ DeviceId = $cameraId PowerShell = $ps Result = $asyncResult }) } if ($threads.Count -eq 0) { return } $hashTable = @{} $completedThreads = New-Object System.Collections.Generic.List[pscustomobject] while ($threads.Count -gt 0) { foreach ($thread in $threads) { if ($thread.Result.IsCompleted) { if ($AsHashTable) { $hashTable.$($thread.DeviceId.ToString()) = $null } else { $obj = [ordered]@{ DeviceId = $thread.DeviceId.ToString() RecordingStats = $null } } try { $result = $thread.PowerShell.EndInvoke($thread.Result) | ForEach-Object { Write-Output $_ } if ($AsHashTable) { $hashTable.$($thread.DeviceId.ToString()) = $result } else { $obj.RecordingStats = $result } } catch { Write-Error $_ } finally { $thread.PowerShell.Dispose() $completedThreads.Add($thread) if (!$AsHashTable) { Write-Output ([pscustomobject]$obj) } } } } $completedThreads | Foreach-Object { [void]$threads.Remove($_)} $completedThreads.Clear() if ($threads.Count -eq 0) { break; } Start-Sleep -Milliseconds 250 } if ($AsHashTable) { Write-Output $hashTable } } finally { if ($threads.Count -gt 0) { Write-Warning "Stopping $($threads.Count) running PowerShell instances. This may take a minute. . ." foreach ($thread in $threads) { $thread.PowerShell.Dispose() } } if ($disposeRunspacePool) { Write-Verbose "Closing runspace pool in $($MyInvocation.MyCommand.Name)" $pool.Close() $pool.Dispose() } } } } |