Public/Get-PSDVTableWebHook.ps1
|
function Get-PSDVTableWebHook { <# .SYNOPSIS Retrieves registered webhooks for a Dataverse table. .DESCRIPTION Get-PSDVTableWebHook queries the Dataverse environment to find webhook registrations for a specified table. It returns detailed information about each webhook including the service endpoint details, execution settings, and associated SDK message information. By default, system and hidden webhooks are filtered out to show only user-created webhooks. This function is useful for auditing webhook configurations and troubleshooting issues. .PARAMETER Table The logical name of the Dataverse table to retrieve webhook registrations for. .PARAMETER Operation Optional filter to return webhooks for a specific operation only. Valid values are Create, Update, Delete, or Retrieve. .PARAMETER Url Optional filter to return webhooks for a specific endpoint URL only. .PARAMETER Stage Optional filter to return webhooks for a specific execution stage only. Valid values are PreValidation, PreOperation, MainOperation, or PostOperation. .PARAMETER Name Optional filter to return webhooks with names containing the specified text (case-insensitive partial match). .PARAMETER IncludeSystemWebHooks When specified, includes system-level and hidden webhooks in the results. By default, these are filtered out. .EXAMPLE Get-PSDVTableWebHook -Table "account" Retrieves user-created webhook registrations for the Account table (excludes system webhooks). .EXAMPLE Get-PSDVTableWebHook -Table "contact" -Operation "Create" Retrieves only user-created webhooks that trigger on Contact creation. .EXAMPLE Get-PSDVTableWebHook -Table "account" -Url "https://myapp.azurewebsites.net/api/webhook" Retrieves webhooks for the Account table that target a specific URL. .EXAMPLE Get-PSDVTableWebHook -Table "contact" -Stage "PreOperation" -Name "validation" Retrieves webhooks for the Contact table that run in PreOperation stage and have 'validation' in their name. .EXAMPLE Get-PSDVTableWebHook -Table "account" -IncludeSystemWebHooks Retrieves all webhook registrations for the Account table, including system-level webhooks. .EXAMPLE Get-PSDVTableWebHook -Table "spork_sporkuserrequest" | Select-Object Name, Url, Stage, Mode Retrieves webhooks for a custom table and displays specific properties. #> [CmdletBinding()] param( [Parameter(Mandatory)] [String] $Table, [Parameter()] [ValidateSet('Create', 'Update', 'Delete', 'Retrieve')] [String] $Operation, [Parameter()] [String] $Url, [Parameter()] [ValidateSet('PreValidation', 'PreOperation', 'MainOperation', 'PostOperation')] [String] $Stage, [Parameter()] [String] $Name, [Parameter()] [Switch] $IncludeSystemWebHooks ) try { Write-Verbose "Retrieving webhook registrations for table: $Table" # Build the query to get SDK message processing steps with webhook service endpoints $select = "sdkmessageprocessingstepid,name,description,stage,rank,mode,statuscode,supporteddeployment,filteringattributes" $expand = "eventhandler_serviceendpoint(`$select=serviceendpointid,name,url,authtype,iscustomizable),sdkmessagefilterid(`$select=sdkmessagefilterid,primaryobjecttypecode),sdkmessageid(`$select=sdkmessageid,name)" # Filter for webhook steps (eventhandler_serviceendpoint exists) and specific table $tableLiteral = ConvertTo-PSDVODataStringLiteral -Value $Table $filter = "eventhandler_serviceendpoint ne null and eventhandler_serviceendpoint/serviceendpointid ne null and sdkmessagefilterid/primaryobjecttypecode eq $tableLiteral" # Add operation filter if specified if ($PSBoundParameters.ContainsKey('Operation')) { $operationLiteral = ConvertTo-PSDVODataStringLiteral -Value $Operation $filter += " and sdkmessageid/name eq $operationLiteral" } # Add URL filter if specified if ($PSBoundParameters.ContainsKey('Url')) { $urlLiteral = ConvertTo-PSDVODataStringLiteral -Value $Url $filter += " and eventhandler_serviceendpoint/url eq $urlLiteral" } # Add stage filter if specified if ($PSBoundParameters.ContainsKey('Stage')) { $stageValue = switch ($Stage) { 'PreValidation' { 10 } 'PreOperation' { 20 } 'MainOperation' { 30 } 'PostOperation' { 40 } } $filter += " and stage eq $stageValue" } # Add name filter if specified (use 'contains' for partial matching) if ($PSBoundParameters.ContainsKey('Name')) { $nameLiteral = ConvertTo-PSDVODataStringLiteral -Value $Name $filter += " and contains(name,$nameLiteral)" } # Filter out system webhooks by default (more efficient than filtering locally) if (-not $IncludeSystemWebHooks.IsPresent) { $filter += " and eventhandler_serviceendpoint/iscustomizable/Value eq true" } $webhookSteps = Invoke-PSDVWebRequest -WebUri 'sdkmessageprocessingsteps' -Select $select -Expand $expand -Filter $filter if (-not $webhookSteps -or $webhookSteps.Count -eq 0) { Write-Verbose "No webhook registrations found for table '$Table'" return $null } Write-Verbose "Found $($webhookSteps.Count) webhook registration(s) for table '$Table'" # Convert to more user-friendly objects $results = foreach ($step in $webhookSteps) { [PSCustomObject]@{ WebHookStepId = $step.sdkmessageprocessingstepid Name = $step.name Description = $step.description Table = $step.sdkmessagefilterid.primaryobjecttypecode Operation = $step.sdkmessageid.name ColumnFilter = if ($step.filteringattributes) { $step.filteringattributes.Split(',') } else { $null } Url = $step.eventhandler_serviceendpoint.url ServiceEndpointName = $step.eventhandler_serviceendpoint.name ServiceEndpointId = $step.eventhandler_serviceendpoint.serviceendpointid Stage = switch ($step.stage) { 10 { 'PreValidation' } 20 { 'PreOperation' } 30 { 'MainOperation' } 40 { 'PostOperation' } default { $step.stage } } Rank = $step.rank Mode = switch ($step.mode) { 0 { 'Synchronous' } 1 { 'Asynchronous' } default { $step.mode } } Status = switch ($step.statuscode) { 1 { 'Enabled' } 2 { 'Disabled' } default { $step.statuscode } } SupportedDeployment = switch ($step.supporteddeployment) { 0 { 'ServerOnly' } 1 { 'ClientOnly' } 2 { 'Both' } default { $step.supporteddeployment } } AuthType = $step.eventhandler_serviceendpoint.authtype IsSystemWebHook = $step.eventhandler_serviceendpoint.iscustomizable.Value -eq $false IsCustomizable = $step.eventhandler_serviceendpoint.iscustomizable.Value -eq $true #HasAuthSecret = if ($step.eventhandler_serviceendpoint.authvalue -and $step.eventhandler_serviceendpoint.authvalue.Contains('x-dv-webhook-secret')) { $true } else { $false } } } # Update verbose message to reflect filtering if (-not $IncludeSystemWebHooks.IsPresent) { Write-Verbose "Returning $(@($results).Count) user webhook(s) (system webhooks filtered at API level)" } else { Write-Verbose "Returning $(@($results).Count) webhook(s) (including system webhooks)" } return $results } catch { throw "Error retrieving webhooks for table '$Table': $($_.Exception.Message)" } } |