From e8128fb05f0f727a0555a3d6ddcbccc66046efe2 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 21:34:01 -0400 Subject: [PATCH 1/7] Adds Get-VerkadaHelixEvent function This new function retrieves a specific Helix event. It takes camera ID, event type UID, and timestamp as input and retrieves the corresponding event data from the Verkada API. Includes parameter validation and error handling. Updates the module manifest to export the new function and its alias. closes #266 --- .../Public/Get-VerkadaHelixEvent.ps1 | 103 ++++++++++++++++++ verkadaModule/verkadaModule.psd1 | 15 +-- 2 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 verkadaModule/Public/Get-VerkadaHelixEvent.ps1 diff --git a/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 new file mode 100644 index 0000000..b153717 --- /dev/null +++ b/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 @@ -0,0 +1,103 @@ +function Get-VerkadaHelixEvent{ + <# + .SYNOPSIS + Gets a specific Helix event using https://apidocs.verkada.com/reference/getvideotaggingeventviewv1 + + .DESCRIPTION + This method can be used to retrieve a Helix Event that has already been posted to Command. In the return message, the users will be able to see the corresponding attribute values for that unique event. To successfully retrieve a Helix Event, users will need to input the associated Camera ID, API Token with Helix permissions, Event Type UID, and the exact event epoch time in milliseconds. + The org_id and reqired token can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. + + .LINK + https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Get-VerkadaHelixEvent.md + + .EXAMPLE + Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -attributes $attributes + This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, event ID, and submitted attributes. The org_id and token will be populated from the cached created by Connect-Verkada. + + .EXAMPLE + Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -attributes $attributes -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' + This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, event ID, and submitted attributes. The org_id and token are submitted as parameters in the call. + #> + [CmdletBinding(PositionalBinding = $true)] + [Alias("Get-VrkdaHlxEvt","g-VrkdaHlxEvt")] + param ( + #The UUID of the organization the user belongs to + [Parameter(ValueFromPipelineByPropertyName = $true)] + [ValidateNotNullOrEmpty()] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$org_id = $Global:verkadaConnection.org_id, + #The UUID of the camera who's name is being changed + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [Alias("cameraId")] + [String]$camera_id, + #The UID of the event type to be used when creating the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$event_type_uid, + #The the epoch time of the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [datetime]$timeStamp, + #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway + [Parameter()] + [ValidateNotNullOrEmpty()] + [String]$x_verkada_auth_api = $Global:verkadaConnection.x_verkada_auth_api, + #The region of the public API to be used + [Parameter()] + [ValidateSet('api','api.eu','api.au')] + [String]$region='api', + #Switch to write errors to file + [Parameter()] + [switch]$errorsToFile + ) + + begin { + $url = "https://$($region).verkada.com/cameras/v1/video_tagging/event" + #parameter validation + if ([string]::IsNullOrEmpty($org_id)) {throw "org_id is missing but is required!"} + if ([string]::IsNullOrEmpty($x_verkada_auth_api)) {throw "x_verkada_auth_api is missing but is required!"} + $myErrors = @() + } #end begin + + process { + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + $body_params = @{} + + $query_params = @{ + 'camera_id' = $camera_id + 'event_type_uid' = $event_type_uid + 'time_ms' = $epoch_time + } + + try { + $response = Invoke-VerkadaRestMethod $url $org_id $x_verkada_auth_api $query_params -body_params $body_params -method GET + return $response + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + $err = $_.ErrorDetails | ConvertFrom-Json + $errorMes = $_ | Convertto-Json -WarningAction SilentlyContinue + $err | Add-Member -NotePropertyName StatusCode -NotePropertyValue (($errorMes | ConvertFrom-Json -Depth 100 -WarningAction SilentlyContinue).Exception.Response.StatusCode) -Force + $msg = "$($err.StatusCode) - $($err.message)" + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + catch [VerkadaRestMethodException] { + $msg = $_.ToString() + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + } #end process + + end { + if ($errorsToFile.IsPresent){ + if (![string]::IsNullOrEmpty($myErrors)){ + Get-Date | Out-File ./errors.txt -Append + $myErrors | Out-File ./errors.txt -Append + } + } + } #end end +} #end function \ No newline at end of file diff --git a/verkadaModule/verkadaModule.psd1 b/verkadaModule/verkadaModule.psd1 index d7de101..f2726cf 100644 --- a/verkadaModule/verkadaModule.psd1 +++ b/verkadaModule/verkadaModule.psd1 @@ -3,7 +3,7 @@ # # Generated by: Verkada SE Community # -# Generated on: 10/21/2025 +# Generated on: 10/20/2025 # @{ @@ -89,7 +89,7 @@ FunctionsToExport = 'Add-VerkadaAccessGroup', 'Add-VerkadaAccessSiteAdmin', 'Get-VerkadaAlarmsSiteContacts', 'Get-VerkadaCameraConfig', 'Get-VerkadaCameraGroup', 'Get-VerkadaCameras', 'Get-VerkadaCloudBackupSettings', 'Get-VerkadaCommandUser', - 'Get-VerkadaLicensePlatesOfInterest', + 'Get-VerkadaHelixEvent', 'Get-VerkadaLicensePlatesOfInterest', 'Get-VerkadaWorkplaceEmployee', 'Read-VerkadaAccessEntities', 'Read-VerkadaAccessGroups', 'Read-VerkadaAccessSchedules', 'Read-VerkadaAccessUsers', 'Read-VerkadaAlarmsSites', @@ -141,11 +141,12 @@ AliasesToExport = 'a-VrkdaAcGrp', 'Add-VrkdaAcGrp', 'a-VrkdaAcUsrCrd', 'Export-VrkdaAcUsrPrflPic', 'g-VrkdaAcUsrPrflPic', 'Get-VrkdaAcUsrPrflPic', 'g-VrkdAlrmDevs', 'Get-VrkdAlrmDevs', 'Get-VerkadaCameraSite', 'Get-VrkdaCmdUsr', 'gt-VrkdaCmdUsr', - 'Get-VerkadaLPoI', 'Get-VrkdaWrkEmp', 'gt-VrkdaWrkEmp', - 'rd-VrkdaAcGrps', 'Read-VrkdaAcGrps', 'rd-VrkdaCamArchv', - 'Read-VrkdaCamArchv', 'rd-VrkdaGstSte', 'Read-VrkdaGstSte', - 'rd-VrkdaWrkEmp', 'Read-VrkdaWrkEmp', 'Remove-VrkdaAcGrp', - 'rm-VrkdaAcGrp', 'Remove-VrkdaAcUsrBtUnlk', 'rm-VrkdaAcUsrBtUnlk', + 'g-VrkdaHlxEvt', 'Get-VrkdaHlxEvt', 'Get-VerkadaLPoI', + 'Get-VrkdaWrkEmp', 'gt-VrkdaWrkEmp', 'rd-VrkdaAcGrps', + 'Read-VrkdaAcGrps', 'rd-VrkdaCamArchv', 'Read-VrkdaCamArchv', + 'rd-VrkdaGstSte', 'Read-VrkdaGstSte', 'rd-VrkdaWrkEmp', + 'Read-VrkdaWrkEmp', 'Remove-VrkdaAcGrp', 'rm-VrkdaAcGrp', + 'Remove-VrkdaAcUsrBtUnlk', 'rm-VrkdaAcUsrBtUnlk', 'Remove-VrkdaAcUsrCrd', 'rm-VrkdaAcUsrCrd', 'Remove-VrkdaAcUsrEntryCo', 'rm-VrkdaAcUsrEntryCo', 'Remove-VrkdaAcUsrFrGrp', 'rm-VrkdaAcUsrFrGrp', From d4dee7900487155bc727fa173ef54ab1fe69b355 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 21:49:28 -0400 Subject: [PATCH 2/7] Updates examples in Get-VerkadaHelixEvent Updates the examples in the Get-VerkadaHelixEvent function documentation to remove the `-attributes` parameter to match the actual parameter set. --- verkadaModule/Public/Get-VerkadaHelixEvent.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 index b153717..1d29e9d 100644 --- a/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 +++ b/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 @@ -11,12 +11,12 @@ function Get-VerkadaHelixEvent{ https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Get-VerkadaHelixEvent.md .EXAMPLE - Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -attributes $attributes - This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, event ID, and submitted attributes. The org_id and token will be populated from the cached created by Connect-Verkada. + Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' + This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, and event ID. The org_id and token will be populated from the cached created by Connect-Verkada. .EXAMPLE - Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -attributes $attributes -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' - This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, event ID, and submitted attributes. The org_id and token are submitted as parameters in the call. + Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' + This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, and event ID. The org_id and token are submitted as parameters in the call. #> [CmdletBinding(PositionalBinding = $true)] [Alias("Get-VrkdaHlxEvt","g-VrkdaHlxEvt")] From 0efaa1dbdb9e41ad7047c0e149f29a7e051ff6bc Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 21:49:55 -0400 Subject: [PATCH 3/7] Adds Set-VerkadaHelixEvent function. Adds the `Set-VerkadaHelixEvent` function, which enables users to update existing Helix events in Command. This function allows users to modify event attributes, such as adding additional key-value pairs, by providing the camera ID, event type UID, timestamp, and the attributes to update. The function leverages the Verkada API to perform the update. closes #267 --- .../Public/Set-VerkadaHelixEvent.ps1 | 111 ++++++++++++++++++ verkadaModule/verkadaModule.psd1 | 9 +- 2 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 verkadaModule/Public/Set-VerkadaHelixEvent.ps1 diff --git a/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 new file mode 100644 index 0000000..3838558 --- /dev/null +++ b/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 @@ -0,0 +1,111 @@ +function Set-VerkadaHelixEvent{ + <# + .SYNOPSIS + Updates a Helix event using https://apidocs.verkada.com/reference/patchvideotaggingeventviewv1 + + .DESCRIPTION + This method can be used to update a Helix Event that has already been posted to Command. This is especially useful if a user needs to add an additional attribute key to the existing event, along with its new corresponding value. To successfully update a Helix Event, users will need to input the associated Camera ID, API Token with Helix permissions, Event Type UID, exact event epoch time in milliseconds, as well as the new attribute key and attribute value that is being updated. + The org_id and reqired token can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. + + .LINK + https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Set-VerkadaHelixEvent.md + + .EXAMPLE + Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -attributes $attributes + This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, event ID, and submitted attributes. The org_id and token will be populated from the cached created by Connect-Verkada. + + .EXAMPLE + Get-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -attributes $attributes -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' + This will get the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, event ID, and submitted attributes. The org_id and token are submitted as parameters in the call. + #> + [CmdletBinding(PositionalBinding = $true)] + [Alias("Set-VrkdaHlxEvt","st-VrkdaHlxEvt")] + param ( + #The UUID of the organization the user belongs to + [Parameter(ValueFromPipelineByPropertyName = $true)] + [ValidateNotNullOrEmpty()] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$org_id = $Global:verkadaConnection.org_id, + #The UUID of the camera who's name is being changed + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [Alias("cameraId")] + [String]$camera_id, + #The UID of the event type to be used when creating the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$event_type_uid, + #The the epoch time of the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [datetime]$timeStamp, + #The parameters to be submitted for the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [object]$attributes, + #Boolean if the event should be flagged + [bool]$flagged=$false, + #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway + [Parameter()] + [ValidateNotNullOrEmpty()] + [String]$x_verkada_auth_api = $Global:verkadaConnection.x_verkada_auth_api, + #The region of the public API to be used + [Parameter()] + [ValidateSet('api','api.eu','api.au')] + [String]$region='api', + #Switch to write errors to file + [Parameter()] + [switch]$errorsToFile + ) + + begin { + $url = "https://$($region).verkada.com/cameras/v1/video_tagging/event" + #parameter validation + if ([string]::IsNullOrEmpty($org_id)) {throw "org_id is missing but is required!"} + if ([string]::IsNullOrEmpty($x_verkada_auth_api)) {throw "x_verkada_auth_api is missing but is required!"} + $myErrors = @() + } #end begin + + process { + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + $body_params = @{ + 'attributes' = $attributes + 'flagged' = $flagged + } + + $query_params = @{ + 'camera_id' = $camera_id + 'event_type_uid' = $event_type_uid + 'time_ms' = $epoch_time + } + + try { + Invoke-VerkadaRestMethod $url $org_id $x_verkada_auth_api $query_params -body_params $body_params -method PATCH + return return "Event updated successfully" + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + $err = $_.ErrorDetails | ConvertFrom-Json + $errorMes = $_ | Convertto-Json -WarningAction SilentlyContinue + $err | Add-Member -NotePropertyName StatusCode -NotePropertyValue (($errorMes | ConvertFrom-Json -Depth 100 -WarningAction SilentlyContinue).Exception.Response.StatusCode) -Force + $msg = "$($err.StatusCode) - $($err.message)" + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + catch [VerkadaRestMethodException] { + $msg = $_.ToString() + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + } #end process + + end { + if ($errorsToFile.IsPresent){ + if (![string]::IsNullOrEmpty($myErrors)){ + Get-Date | Out-File ./errors.txt -Append + $myErrors | Out-File ./errors.txt -Append + } + } + } #end end +} #end function \ No newline at end of file diff --git a/verkadaModule/verkadaModule.psd1 b/verkadaModule/verkadaModule.psd1 index f2726cf..20f7a74 100644 --- a/verkadaModule/verkadaModule.psd1 +++ b/verkadaModule/verkadaModule.psd1 @@ -117,9 +117,9 @@ FunctionsToExport = 'Add-VerkadaAccessGroup', 'Add-VerkadaAccessSiteAdmin', 'Set-VerkadaCameraOrientation', 'Set-VerkadaCameraSite', 'Set-VerkadaCameraTamperSensitivity', 'Set-VerkadaCloudBackupSettings', 'Set-VerkadaCommandPermissions', - 'Set-VerkadaCommandUser', 'Set-VerkadaLicensePlateOfInterest', - 'Set-VerkadaSitePermissions', 'Set-VerkadaWorkplaceEmployee', - 'Unlock-VerkadaAccessDoor' + 'Set-VerkadaCommandUser', 'Set-VerkadaHelixEvent', + 'Set-VerkadaLicensePlateOfInterest', 'Set-VerkadaSitePermissions', + 'Set-VerkadaWorkplaceEmployee', 'Unlock-VerkadaAccessDoor' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() @@ -167,7 +167,8 @@ AliasesToExport = 'a-VrkdaAcGrp', 'Add-VrkdaAcGrp', 'a-VrkdaAcUsrCrd', 's-VrkdAlrmBr33Setgs', 's-VrkdAlrmPancSetgs', 'Set-VrkdAlrmPancSetgs', 'Set-VrkdaCamOrnt', 'VrkdaCamOrnt', 'Set-VrkdaCamTmprSen', 'VrkdaCamTmprSen', 'Set-VrkdaCmdUsr', 'st-VrkdaCmdUsr', - 'Set-VerkadaLPoI', 'Set-VrkdaWrkEmp', 'st-VrkdaWrkEmp', 'uk-VrkdAcDoor', + 'Set-VrkdaHlxEvt', 'st-VrkdaHlxEvt', 'Set-VerkadaLPoI', + 'Set-VrkdaWrkEmp', 'st-VrkdaWrkEmp', 'uk-VrkdAcDoor', 'Unlock-VrkdAcDoor' # DSC resources to export from this module From 792d5c83b30f70d6105ad9a4eef4ea5ed8f8ad98 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 21:59:29 -0400 Subject: [PATCH 4/7] Adds Remove-VerkadaHelixEvent cmdlet Adds a new cmdlet to delete Helix events using the Verkada API, enabling users to manage and remove specific events from Command. Includes parameter validation, error handling, and the ability to write errors to a file. Also updates the module manifest to export the new function and its aliases. closes #268 --- .../Public/Remove-VerkadaHelixEvent.ps1 | 103 ++++++++++++++++++ verkadaModule/verkadaModule.psd1 | 34 +++--- 2 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 diff --git a/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 new file mode 100644 index 0000000..dee6dff --- /dev/null +++ b/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 @@ -0,0 +1,103 @@ +function Remove-VerkadaHelixEvent{ + <# + .SYNOPSIS + Deletes a Helix event using https://apidocs.verkada.com/reference/deletevideotaggingeventviewv1 + + .DESCRIPTION + This method can be used to delete a Helix event from Command. The required parameter to successfully delete a Helix event are the associated Camera ID, API Token with Helix permissions, Event Type UID, and the exact event epoch time in milliseconds. + The org_id and reqired token can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. + + .LINK + https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Remove-VerkadaHelixEvent.md + + .EXAMPLE + Remove-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' + This will delete the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, and event ID. The org_id and token will be populated from the cached created by Connect-Verkada. + + .EXAMPLE + Remove-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -timeStamp '1/1/2025 08:35:00 -06' -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' + This will delete the helix event for Jan 1, 2025 at 8:35 AM CST for the sepcified camera, and event ID. The org_id and token are submitted as parameters in the call. + #> + [CmdletBinding(PositionalBinding = $true)] + [Alias("Remove-VrkdaHlxEvt","rm-VrkdaHlxEvt")] + param ( + #The UUID of the organization the user belongs to + [Parameter(ValueFromPipelineByPropertyName = $true)] + [ValidateNotNullOrEmpty()] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$org_id = $Global:verkadaConnection.org_id, + #The UUID of the camera who's name is being changed + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [Alias("cameraId")] + [String]$camera_id, + #The UID of the event type to be used when creating the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$event_type_uid, + #The the epoch time of the event + [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + [datetime]$timeStamp, + #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway + [Parameter()] + [ValidateNotNullOrEmpty()] + [String]$x_verkada_auth_api = $Global:verkadaConnection.x_verkada_auth_api, + #The region of the public API to be used + [Parameter()] + [ValidateSet('api','api.eu','api.au')] + [String]$region='api', + #Switch to write errors to file + [Parameter()] + [switch]$errorsToFile + ) + + begin { + $url = "https://$($region).verkada.com/cameras/v1/video_tagging/event" + #parameter validation + if ([string]::IsNullOrEmpty($org_id)) {throw "org_id is missing but is required!"} + if ([string]::IsNullOrEmpty($x_verkada_auth_api)) {throw "x_verkada_auth_api is missing but is required!"} + $myErrors = @() + } #end begin + + process { + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + $body_params = @{} + + $query_params = @{ + 'camera_id' = $camera_id + 'event_type_uid' = $event_type_uid + 'time_ms' = $epoch_time + } + + try { + Invoke-VerkadaRestMethod $url $org_id $x_verkada_auth_api $query_params -body_params $body_params -method DELETE + return "Event deleted successfully" + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + $err = $_.ErrorDetails | ConvertFrom-Json + $errorMes = $_ | Convertto-Json -WarningAction SilentlyContinue + $err | Add-Member -NotePropertyName StatusCode -NotePropertyValue (($errorMes | ConvertFrom-Json -Depth 100 -WarningAction SilentlyContinue).Exception.Response.StatusCode) -Force + $msg = "$($err.StatusCode) - $($err.message)" + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + catch [VerkadaRestMethodException] { + $msg = $_.ToString() + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + } #end process + + end { + if ($errorsToFile.IsPresent){ + if (![string]::IsNullOrEmpty($myErrors)){ + Get-Date | Out-File ./errors.txt -Append + $myErrors | Out-File ./errors.txt -Append + } + } + } #end end +} #end function \ No newline at end of file diff --git a/verkadaModule/verkadaModule.psd1 b/verkadaModule/verkadaModule.psd1 index 20f7a74..a4c2d90 100644 --- a/verkadaModule/verkadaModule.psd1 +++ b/verkadaModule/verkadaModule.psd1 @@ -102,7 +102,7 @@ FunctionsToExport = 'Add-VerkadaAccessGroup', 'Add-VerkadaAccessSiteAdmin', 'Remove-VerkadaAccessUserProfilePicture', 'Remove-VerkadaAccessUserRemoteUnlock', 'Remove-VerkadaCameraArchive', 'Remove-VerkadaCommandUser', - 'Remove-VerkadaLicensePlateOfInterest', + 'Remove-VerkadaHelixEvent', 'Remove-VerkadaLicensePlateOfInterest', 'Remove-VerkadaWorkplaceEmployee', 'Send-VerkadaPassInvite', 'Set-VerkadaAccessDoorName', 'Set-VerkadaAccessDoorScheduleOverride', @@ -154,22 +154,22 @@ AliasesToExport = 'a-VrkdaAcGrp', 'Add-VrkdaAcGrp', 'a-VrkdaAcUsrCrd', 'Remove-VrkdaAcUsrPrflPic', 'rm-VrkdaAcUsrPrflPic', 'Remove-VrkdaAcUsrRmtUnlk', 'rm-VrkdaAcUsrRmtUnlk', 'Remove-VrkdaCamArchv', 'rm-VrkdaCamArchv', 'Remove-VrkdaCmdUsr', - 'rm-VrkdaCmdUsr', 'Remove-VerkadaLPoI', 'Remove-VrkdaWrkEmp', - 'rm-VrkdaWrkEmp', 'sd-VrkdaPssInv', 'Send-VrkdaPssInv', - 'Set-VrkdaAcDrNm', 'st-VrkdaAcDrNm', 's-VrkdAcDrSchOvrd', - 'Set-VrkdAcDrSchOvrd', 'Set-VrkdaAcUsrBtUnlk', 'st-VrkdaAcUsrBtUnlk', - 'Set-VrkdaAcUsrEndDt', 'st-VrkdaAcUsrEndDt', 'Set-VrkdaAcUsrEntryCo', - 'st-VrkdaAcUsrEntryCo', 'Set-VrkdaAcUsrGrp', 'st-VrkdaAcUsrGrp', - 's-VrkdaAcUsrPrflPic', 'Set-VrkdaAcUsrPrflPic', - 'Set-VrkdaAcUsrRmtUnlk', 'st-VrkdaAcUsrRmtUnlk', - 'Set-VrkdaAcUsrStrtDt', 'st-VrkdaAcUsrStrtDt', 's-VrkdAlrmBr31Setgs', - 's-VrkdAlrmDrSenSetgs', 'Set-VrkdAlrmDrSenSetgs', - 's-VrkdAlrmBr33Setgs', 's-VrkdAlrmPancSetgs', 'Set-VrkdAlrmPancSetgs', - 'Set-VrkdaCamOrnt', 'VrkdaCamOrnt', 'Set-VrkdaCamTmprSen', - 'VrkdaCamTmprSen', 'Set-VrkdaCmdUsr', 'st-VrkdaCmdUsr', - 'Set-VrkdaHlxEvt', 'st-VrkdaHlxEvt', 'Set-VerkadaLPoI', - 'Set-VrkdaWrkEmp', 'st-VrkdaWrkEmp', 'uk-VrkdAcDoor', - 'Unlock-VrkdAcDoor' + 'rm-VrkdaCmdUsr', 'Remove-VrkdaHlxEvt', 'rm-VrkdaHlxEvt', + 'Remove-VerkadaLPoI', 'Remove-VrkdaWrkEmp', 'rm-VrkdaWrkEmp', + 'sd-VrkdaPssInv', 'Send-VrkdaPssInv', 'Set-VrkdaAcDrNm', + 'st-VrkdaAcDrNm', 's-VrkdAcDrSchOvrd', 'Set-VrkdAcDrSchOvrd', + 'Set-VrkdaAcUsrBtUnlk', 'st-VrkdaAcUsrBtUnlk', 'Set-VrkdaAcUsrEndDt', + 'st-VrkdaAcUsrEndDt', 'Set-VrkdaAcUsrEntryCo', 'st-VrkdaAcUsrEntryCo', + 'Set-VrkdaAcUsrGrp', 'st-VrkdaAcUsrGrp', 's-VrkdaAcUsrPrflPic', + 'Set-VrkdaAcUsrPrflPic', 'Set-VrkdaAcUsrRmtUnlk', + 'st-VrkdaAcUsrRmtUnlk', 'Set-VrkdaAcUsrStrtDt', 'st-VrkdaAcUsrStrtDt', + 's-VrkdAlrmBr31Setgs', 's-VrkdAlrmDrSenSetgs', + 'Set-VrkdAlrmDrSenSetgs', 's-VrkdAlrmBr33Setgs', + 's-VrkdAlrmPancSetgs', 'Set-VrkdAlrmPancSetgs', 'Set-VrkdaCamOrnt', + 'VrkdaCamOrnt', 'Set-VrkdaCamTmprSen', 'VrkdaCamTmprSen', + 'Set-VrkdaCmdUsr', 'st-VrkdaCmdUsr', 'Set-VrkdaHlxEvt', + 'st-VrkdaHlxEvt', 'Set-VerkadaLPoI', 'Set-VrkdaWrkEmp', + 'st-VrkdaWrkEmp', 'uk-VrkdAcDoor', 'Unlock-VrkdAcDoor' # DSC resources to export from this module # DscResourcesToExport = @() From d78180ee3c7ab2a3a84c1ddca555e834073b9cb7 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 22:16:44 -0400 Subject: [PATCH 5/7] Updates Remove-VerkadaHelixEvent parameters Adds epoch time as a parameter for removing Helix events. Also updates timestamp parameter to be optional and includes validation logic. If neither parameter is supplied the script will throw an error Related to 260-add-helix-endpoints --- .../Public/Remove-VerkadaHelixEvent.ps1 | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 index dee6dff..a640ce8 100644 --- a/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 +++ b/verkadaModule/Public/Remove-VerkadaHelixEvent.ps1 @@ -35,9 +35,13 @@ function Remove-VerkadaHelixEvent{ [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [String]$event_type_uid, - #The the epoch time of the event - [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + #The the timestamp of the event + [Parameter(ValueFromPipelineByPropertyName = $true)] [datetime]$timeStamp, + #The the epoch time of the event in milliseconds + [Parameter(ValueFromPipelineByPropertyName = $true)] + [Alias("time_ms")] + [Int64]$epoch_time, #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway [Parameter()] [ValidateNotNullOrEmpty()] @@ -60,7 +64,14 @@ function Remove-VerkadaHelixEvent{ } #end begin process { - $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + if ($PSBoundParameters.ContainsKey('epoch_time')){ + + } elseif ($PSBoundParameters.ContainsKey('timeStamp')){ + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + } else { + throw "timestamp or epoch_time (time_ms) are required" + } + $body_params = @{} $query_params = @{ From ddb1db2969af353f0fc89df8d725c22c6793429f Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 22:28:47 -0400 Subject: [PATCH 6/7] Adds epoch time parameter option. Allows users to provide epoch time instead of datetime. Adds epoch_time parameter and alias time_ms. Datetime is now optional as epoch time can be used instead. Adds exception if neither datetime nor epoch_time is provided. --- verkadaModule/Public/Add-VerkadaHelixEvent.ps1 | 16 +++++++++++++--- verkadaModule/Public/Get-VerkadaHelixEvent.ps1 | 16 +++++++++++++--- verkadaModule/Public/Set-VerkadaHelixEvent.ps1 | 16 +++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/verkadaModule/Public/Add-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Add-VerkadaHelixEvent.ps1 index e77423e..07f92e5 100644 --- a/verkadaModule/Public/Add-VerkadaHelixEvent.ps1 +++ b/verkadaModule/Public/Add-VerkadaHelixEvent.ps1 @@ -35,9 +35,13 @@ function Add-VerkadaHelixEvent{ [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [String]$event_type_uid, - #The the epoch time of the event - [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + #The the timestamp of the event + [Parameter(ValueFromPipelineByPropertyName = $true)] [datetime]$timeStamp, + #The the epoch time of the event in milliseconds + [Parameter(ValueFromPipelineByPropertyName = $true)] + [Alias("time_ms")] + [Int64]$epoch_time, #The parameters to be submitted for the event [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [object]$attributes, @@ -65,7 +69,13 @@ function Add-VerkadaHelixEvent{ } #end begin process { - $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + if ($PSBoundParameters.ContainsKey('epoch_time')){ + + } elseif ($PSBoundParameters.ContainsKey('timeStamp')){ + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + } else { + throw "timestamp or epoch_time (time_ms) are required" + } $body_params = @{ 'camera_id' = $camera_id 'event_type_uid' = $event_type_uid diff --git a/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 index 1d29e9d..cf1a96d 100644 --- a/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 +++ b/verkadaModule/Public/Get-VerkadaHelixEvent.ps1 @@ -35,9 +35,13 @@ function Get-VerkadaHelixEvent{ [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [String]$event_type_uid, - #The the epoch time of the event - [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + #The the timestamp of the event + [Parameter(ValueFromPipelineByPropertyName = $true)] [datetime]$timeStamp, + #The the epoch time of the event in milliseconds + [Parameter(ValueFromPipelineByPropertyName = $true)] + [Alias("time_ms")] + [Int64]$epoch_time, #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway [Parameter()] [ValidateNotNullOrEmpty()] @@ -60,7 +64,13 @@ function Get-VerkadaHelixEvent{ } #end begin process { - $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + if ($PSBoundParameters.ContainsKey('epoch_time')){ + + } elseif ($PSBoundParameters.ContainsKey('timeStamp')){ + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + } else { + throw "timestamp or epoch_time (time_ms) are required" + } $body_params = @{} $query_params = @{ diff --git a/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 index 3838558..c59fc6a 100644 --- a/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 +++ b/verkadaModule/Public/Set-VerkadaHelixEvent.ps1 @@ -35,9 +35,13 @@ function Set-VerkadaHelixEvent{ [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [String]$event_type_uid, - #The the epoch time of the event - [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] + #The the timestamp of the event + [Parameter(ValueFromPipelineByPropertyName = $true)] [datetime]$timeStamp, + #The the epoch time of the event in milliseconds + [Parameter(ValueFromPipelineByPropertyName = $true)] + [Alias("time_ms")] + [Int64]$epoch_time, #The parameters to be submitted for the event [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [object]$attributes, @@ -65,7 +69,13 @@ function Set-VerkadaHelixEvent{ } #end begin process { - $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + if ($PSBoundParameters.ContainsKey('epoch_time')){ + + } elseif ($PSBoundParameters.ContainsKey('timeStamp')){ + $epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $timeStamp.ToUniversalTime()).TotalMilliseconds + } else { + throw "timestamp or epoch_time (time_ms) are required" + } $body_params = @{ 'attributes' = $attributes 'flagged' = $flagged From 56a5857613a065373bfe6a2993bad83959e6e179 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 20 Oct 2025 23:39:54 -0400 Subject: [PATCH 7/7] Adds Find-VerkadaHelixEvent function Adds a new function to find Helix events based on specified criteria. This function allows users to search for Helix events by camera ID, event type UID, start and end times, and attribute keys/values. It leverages the Verkada API to retrieve and filter events based on the provided parameters, enhancing the module's event search capabilities. closes #269 --- .../Public/Find-VerkadaHelixEvent.ps1 | 146 ++++++++++++++++++ verkadaModule/verkadaModule.psd1 | 20 +-- 2 files changed, 156 insertions(+), 10 deletions(-) create mode 100644 verkadaModule/Public/Find-VerkadaHelixEvent.ps1 diff --git a/verkadaModule/Public/Find-VerkadaHelixEvent.ps1 b/verkadaModule/Public/Find-VerkadaHelixEvent.ps1 new file mode 100644 index 0000000..8d73791 --- /dev/null +++ b/verkadaModule/Public/Find-VerkadaHelixEvent.ps1 @@ -0,0 +1,146 @@ +function Find-VerkadaHelixEvent{ + <# + .SYNOPSIS + Finds Helix event using https://apidocs.verkada.com/reference/postvideotaggingeventsearchviewv1 + + .DESCRIPTION + This method can be used to search for either a single or multiple Helix Events that have already been posted to Command. In the return message, the users will be able to see the corresponding attribute keys and attribute values for those specific Helix Events. + + The only required parameters to search for Helix Events is a Verkada API Token with Helix permissions. Users will be returned a complete list of all Helix Events that are currently available in Command. Users can further narrow down their search by adding: + + Camera ID: returns all Helix Events linked to that specific camera or list of cameras. + Event Type UID: returns all Helix Events that share that specific Event Type UID. + Start and End Times: returns all Helix Events that have occurred during that time range. + Attributes Keys and Values: returns all Helix Events that have attributes keys and values matching the user's entered parameters. + The org_id and reqired token can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. + + .LINK + https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Find-VerkadaHelixEvent.md + + .EXAMPLE + Find-VerkadaHelixEvent -camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc + This will get the helix events for camera_id 6b8731d7-d991-4206-ba71-b5446fa617fc. The org_id and token will be populated from the cached created by Connect-Verkada. + + .EXAMPLE + Find-VerkadaHelixEvent -event_type_uid cf918b16-26cd-4c01-a672-5a91b79311e1 -startTimeStamp '1/1/2025 08:35:00 -06' -endTimeStamp '1/7/2025 17:00:00 -06' -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' + This will find the helix events for from Jan 1, 2025 at 8:35 AM CST to Jan 7, 2025 at 5:00 APM CST for the sepcified event ID. The org_id and token are submitted as parameters in the call. + #> + [CmdletBinding(PositionalBinding = $true)] + [Alias("Find-VrkdaHlxEvt","fd-VrkdaHlxEvt")] + param ( + #The UUID of the organization the user belongs to + [Parameter(ValueFromPipelineByPropertyName = $true)] + [ValidateNotNullOrEmpty()] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$org_id = $Global:verkadaConnection.org_id, + #The UUID of the camera who's name is being changed + [Parameter()] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [Alias("cameraId","cameraIds","camera_id")] + [String[]]$camera_ids, + #The UID of the event type to be used when creating the event + [Parameter()] + [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] + [String]$event_type_uid, + #The the start timestamp of the events being serached + [Parameter()] + [datetime]$startTimeStamp, + #The the epoch start time of the events being serached in milliseconds + [Parameter()] + [Alias("start_time_ms")] + [Int64]$start_epoch_time, + #The the end timestamp of the events being serached + [Parameter()] + [datetime]$endTimeStamp, + #The the epoch end time of the events being serached in milliseconds + [Parameter()] + [Alias("end_time_ms")] + [Int64]$end_epoch_time, + #The attribute filters to be used in the search query + [Parameter()] + [object[]]$attribute_filters, + #The keyword/s to be used in the search query + [Parameter()] + [Alias("keyword")] + [string[]]$keywords, + #Boolean if the event should be flagged + [bool]$flagged=$false, + #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway + [Parameter()] + [ValidateNotNullOrEmpty()] + [String]$x_verkada_auth_api = $Global:verkadaConnection.x_verkada_auth_api, + #The region of the public API to be used + [Parameter()] + [ValidateSet('api','api.eu','api.au')] + [String]$region='api', + #Switch to write errors to file + [Parameter()] + [switch]$errorsToFile + ) + + begin { + $url = "https://$($region).verkada.com/cameras/v1/video_tagging/event/search" + #parameter validation + if ([string]::IsNullOrEmpty($org_id)) {throw "org_id is missing but is required!"} + if ([string]::IsNullOrEmpty($x_verkada_auth_api)) {throw "x_verkada_auth_api is missing but is required!"} + $myErrors = @() + } #end begin + + process { + if (!($PSBoundParameters.ContainsKey('start_epoch_time')) -and $PSBoundParameters.ContainsKey('startTimeStamp')){ + $start_epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $startTimeStamp.ToUniversalTime()).TotalMilliseconds + } + if (!($PSBoundParameters.ContainsKey('end_epoch_time')) -and $PSBoundParameters.ContainsKey('endTimeStamp')){ + $end_epoch_time = (New-TimeSpan -Start (Get-Date "01/01/1970") -End $endTimeStamp.ToUniversalTime()).TotalMilliseconds + } + + $body_params = @{ + 'flagged' = $flagged + } + + $query_params = @{} + + #add any of the optional query parameters to the body + if (!([string]::IsNullOrEmpty($keywords))){$body_params.keywords = $keywords} + if ($PSBoundParameters.ContainsKey('start_epoch_time') -or $PSBoundParameters.ContainsKey('startTimeStamp')){ + $body_params.start_time_ms = $start_epoch_time + } + if ($PSBoundParameters.ContainsKey('end_epoch_time') -or $PSBoundParameters.ContainsKey('endTimeStamp')){ + $body_params.end_time_ms = $end_epoch_time + } + if (!([string]::IsNullOrEmpty($camera_ids))){$body_params.camera_ids = $camera_ids} + if (!([string]::IsNullOrEmpty($event_type_uid))){$body_params.event_type_uid = $event_type_uid} + if ($PSBoundParameters.ContainsKey('attribute_filters')){$body_params.attribute_filters = $attribute_filters} + + try { + $response = Invoke-VerkadaRestMethod $url $org_id $x_verkada_auth_api $query_params -body_params $body_params -pagination -propertyName events -page_size 100 -method POST + return $response + } + catch [Microsoft.PowerShell.Commands.HttpResponseException] { + $err = $_.ErrorDetails | ConvertFrom-Json + $errorMes = $_ | Convertto-Json -WarningAction SilentlyContinue + $err | Add-Member -NotePropertyName StatusCode -NotePropertyValue (($errorMes | ConvertFrom-Json -Depth 100 -WarningAction SilentlyContinue).Exception.Response.StatusCode) -Force + $msg = "$($err.StatusCode) - $($err.message)" + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + catch [VerkadaRestMethodException] { + $msg = $_.ToString() + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + } #end process + + end { + if ($errorsToFile.IsPresent){ + if (![string]::IsNullOrEmpty($myErrors)){ + Get-Date | Out-File ./errors.txt -Append + $myErrors | Out-File ./errors.txt -Append + } + } + } #end end +} #end function \ No newline at end of file diff --git a/verkadaModule/verkadaModule.psd1 b/verkadaModule/verkadaModule.psd1 index a4c2d90..e8c0e3c 100644 --- a/verkadaModule/verkadaModule.psd1 +++ b/verkadaModule/verkadaModule.psd1 @@ -78,12 +78,12 @@ FunctionsToExport = 'Add-VerkadaAccessGroup', 'Add-VerkadaAccessSiteAdmin', 'Disable-VerkadaAccessUserLicensePlate', 'Disconnect-Verkada', 'Enable-VerkadaAccessUserCard', 'Enable-VerkadaAccessUserLicensePlate', 'Find-VerkadaCommandUser', - 'Find-VerkadaUserId', 'Get-Otp', 'Get-VerkadaAccessCredential', - 'Get-VerkadaAccessDoorConfigReport', 'Get-VerkadaAccessDoors', - 'Get-VerkadaAccessDoorSchedules', 'Get-VerkadaAccessEvents', - 'Get-VerkadaAccessGroup', 'Get-VerkadaAccessLevels', - 'Get-VerkadaAccessSite', 'Get-VerkadaAccessUser', - 'Get-VerkadaAccessUserProfilePicture', + 'Find-VerkadaHelixEvent', 'Find-VerkadaUserId', 'Get-Otp', + 'Get-VerkadaAccessCredential', 'Get-VerkadaAccessDoorConfigReport', + 'Get-VerkadaAccessDoors', 'Get-VerkadaAccessDoorSchedules', + 'Get-VerkadaAccessEvents', 'Get-VerkadaAccessGroup', + 'Get-VerkadaAccessLevels', 'Get-VerkadaAccessSite', + 'Get-VerkadaAccessUser', 'Get-VerkadaAccessUserProfilePicture', 'Get-VerkadaAccessUserReport', 'Get-VerkadaAccessUserViaGraphql', 'Get-VerkadaAlarmsDevices', 'Get-VerkadaAlarmsSiteConfig', 'Get-VerkadaAlarmsSiteContacts', 'Get-VerkadaCameraConfig', @@ -134,10 +134,10 @@ AliasesToExport = 'a-VrkdaAcGrp', 'Add-VrkdaAcGrp', 'a-VrkdaAcUsrCrd', 'Add-VerkadaLPoI', 'a-VrkdaWrkEmp', 'Add-VrkdaWrkEmp', 'd-VrkdaAcUsrCrd', 'Disable-VrkdaAcUsrCrd', 'd-VrkdaAcUsrLPR', 'Disable-VrkdaAcUsrLPR', 'e-VrkdaAcUsrCrd', 'Enable-VrkdaAcUsrCrd', - 'e-VrkdaAcUsrLPR', 'Enable-VrkdaAcUsrLPR', 'otp', 'Get-VrkdaAcEvnts', - 'gt-VrkdaAcEvnts', 'Get-VrkdaAcGrp', 'gt-VrkdaAcGrp', 'Get-VrkdaAcUsr', - 'gt-VrkdaAcUsr', 'ep-VrkdaAcUsrPrflPic', - 'Export-VerkadaAccessUserProfilePicture', + 'e-VrkdaAcUsrLPR', 'Enable-VrkdaAcUsrLPR', 'fd-VrkdaHlxEvt', + 'Find-VrkdaHlxEvt', 'otp', 'Get-VrkdaAcEvnts', 'gt-VrkdaAcEvnts', + 'Get-VrkdaAcGrp', 'gt-VrkdaAcGrp', 'Get-VrkdaAcUsr', 'gt-VrkdaAcUsr', + 'ep-VrkdaAcUsrPrflPic', 'Export-VerkadaAccessUserProfilePicture', 'Export-VrkdaAcUsrPrflPic', 'g-VrkdaAcUsrPrflPic', 'Get-VrkdaAcUsrPrflPic', 'g-VrkdAlrmDevs', 'Get-VrkdAlrmDevs', 'Get-VerkadaCameraSite', 'Get-VrkdaCmdUsr', 'gt-VrkdaCmdUsr',