functions/public/Send-SplunkHECEvent.ps1
function Send-SplunkHECEvent { <# .SYNOPSIS Sends one or more PowerShell objects to a Splunk HTTP Event Collector (HEC) endpoint as a json object. .DESCRIPTION Sends one or more PowerShell objects to a Splunk HTTP Event Collector endpoint as a json object. A single HTTP request sends multiple events to Splunk. .PARAMETER HecToken Splunk HEC Token as a PSCredential object. Token must be supplied as the password. .PARAMETER HecUri Splunk HEC URI to which the event will be sent to. Defaults to localhost. .PARAMETER EventData PowerShell object to send to Splunk HEC in json format. .PARAMETER Source Splunk source value that will be set for the event. .PARAMETER Sourcetype Splunk sourcetype value that will be set for the event. .PARAMETER SplunkHost Splunk host value that will be set for the event. .PARAMETER RequestSize Number of PowerShell objects (multiple Splunk events) to include in a single HTTP Request to Splunk HEC. .PARAMETER SkipCertificateCheck Switch to skip the TLS certificate checking. .EXAMPLE Send-SplunkHECEvent -HecToken $Credential -HecUri 'https://splunk.example.com:8088/services/collector' -EventData $ObjectArray -Sourcetype 'vendor:product:type:technology/format' -Source 'script.ps1' .EXAMPLE $EventSplat = @{ HecToken = $Token HecUri = 'https://splunk.example.com:8088/services/collector' EventData = $EventData Source = "script.ps1" SourceType = 'vendor:product:type:technology/format' SplunkHost = 'server.example.com' RequestSize = 25 } Send-SplunkHECEvent @EventSplat #> #Requires -Version 7 [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory = $true,ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()] [PSObject]$EventData, [Parameter(Mandatory = $true)] [PSCredential]$HecToken, [Parameter(Mandatory = $true)] [string]$Source, [Parameter(Mandatory = $true)] [string]$Sourcetype, [string]$SplunkHost = [System.Net.Dns]::GetHostName(), [string]$HecUri = 'https://localhost:8088/services/collector', [int]$RequestSize = 10, [switch]$SkipCertificateCheck ) Begin { [string]$BulkEvent = "" [int]$count = 0 [Array]$EventArray = @() } Process { # process potential objects from the pipeline or passed with a parameter $EventArray += $EventData } End { # Process events into a multi-event json object of size $RequestSize # All events are sent in a single request if $EventArray.Count < $RequestSize for ($i = 0; $i -lt $EventArray.Count; $i++) { $Body = @{ 'host' = $SplunkHost 'sourcetype' = $Sourcetype 'source' = $Source 'event' = $EventArray[$i] } | ConvertTo-Json -Depth 5 -Compress # ConvertTo-Json escapes unicode U+0022 quotes automatically # https://www.ietf.org/rfc/rfc8259.txt # Splunk HEC seems to interpret other unicode quotes as legitimate quotes # Escape these quotes to prevent a HEC error of: text":"Invalid data format","code":6," $Body = $Body -replace "`u{201c}", "\`u{201c}" -replace "`u{201d}", "\`u{201d}" -replace "`u{201f}", "\`u{201f}" $BulkEvent += $Body $count++ if ($count -eq $RequestSize -or ($i+1 -eq $EventArray.Count)) { # Setup parameters for REST call $RestSplat = @{ URI = $HecUri Headers = @{ 'Authorization' = "Splunk $($HecToken.GetNetworkCredential().Password)" } Method = 'POST' MaximumRetryCount = 3 RetryIntervalSec = 5 Body = $BulkEvent } # Send event(s) to Splunk HEC endpoint if ($PSCmdlet.ShouldProcess($RestSplat['Body'], 'Sending')) { Write-Verbose "HTTP Request contains $($count) event(s)" if ($SkipCertificateCheck) { Invoke-RestMethod @RestSplat -SkipCertificateCheck | Out-Null } else { Invoke-RestMethod @RestSplat | Out-Null } } # Reset to create a new multi-event Body $count = 0 $BulkEvent = "" } } } } |