functions/public/Update-SplunkLookup.ps1
<# .Synopsis Updates a Splunk lookup table with the provided CSV. This function requires loading the CSV into memory and should not be used with large files. .DESCRIPTION Updates a Splunk lookup table with the provided CSV. This function requires loading the CSV into memory and should not be used with large files. .PARAMETER Credential Service account username and password with access to the search index being used in Splunk .PARAMETER CloudDeploymentName Name of your Splunk cloud deployment name ie 'illinois' for illinois.splunkcloud.com .PARAMETER LookupName Name of your lookup in Splunk ie 'test.csv' .PARAMETER NewCSVPath Path to the CSV that will replace the lookup at the lookup name provided ie '.\test_2022-14-03.csv' .PARAMETER App Specify the Splunk app to use if required ie 'illinois-urbana-security-techsvc-APP' .EXAMPLE Update-SplunkLookup -Credential $Credential -CloudDeploymentName 'illinois' -LookupName 'test.csv' -NewCSVPath '.\test_2022-14-03.csv' -App 'illinois-urbana-security-techsvc-APP' #> function Update-SplunkLookup { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory=$true)] [System.Management.Automation.PSCredential]$Credential, [Parameter(Mandatory=$true)] [String]$CloudDeploymentName, [Parameter(Mandatory=$true)] [String]$LookupName, [Parameter(Mandatory=$true)] [String]$NewCSVPath, [String]$App ) process { #Set the Base URI depending on whether or not an app was specified If($App){ $BaseURI = "https://$($CloudDeploymentName).splunkcloud.com:8089/servicesNS/$($Credential.UserName)/$($App)" } Else{ $BaseURI = "https://$($CloudDeploymentName).splunkcloud.com:8089/services" } #Support -WhatIf feature of this function because it makes system changes If($PSCmdlet.ShouldProcess("$($BaseURI)/data/lookup-table-files/$($LookupName)")){ #Test that the lookup exists $IVRSplat = @{ Credential = $Credential Method = 'GET' #Use a different URI depending on if an App is specified or not URI = "$($BaseURI)/data/lookup-table-files/" Body = @{ count = 0 } } $Lookups = Invoke-RestMethod @IVRSplat If($Lookups.Title -contains $LookupName){ Write-Verbose -Message "Lookup $($LookupName) found. Proceeding to update." } Else{ Throw "Lookup $($LookupName) not found. Please try again. You may need to specify a Splunk app to search within." } #Update the lookup, which requires transformation of the CSV file $CSVJson = Import-Csv $NewCSVPath -Encoding 'utf8BOM' | ConvertTo-Json #Escapes any escapes \ and escaped quotes \" in the json elements, then escapes any quotes in the json body #Solution from dmarling here: https://community.splunk.com/t5/Getting-Data-In/how-to-upload-csv-data-file-into-splunk-by-using-REST-API-Can/td-p/442884 $EscapingEscapedEscapes = $CSVJson -replace '\\\\', '\\\\\\' $EscapingEscapedQuotes = $EscapingEscapedEscapes -replace '([^\\])\\"','$1\\\"' $FileEscaped = $EscapingEscapedQuotes -replace '([\n\r]\s+)"(.*)":(\s+)"(.*)"(,?[\n\r])','$1\"$2\":$3\"$4\"$5' $Search = '| makeresults count=1 | fields - _time | eval data="'+$FileEscaped+'" | eval data=trim(data, "[]") | rex field=data mode=sed "s/(\s+)\},/\1}█/g" | makemv data delim="█" | mvexpand data | eval data="[".data."]" | spath input=data | fields - data | rename "{}.*" as * | outputlookup '+$LookupName+'' $IVRSplat = @{ Credential = $Credential Method = 'POST' #Use a different URI depending on if an App is specified or not URI = "$($BaseURI)/search/jobs" Body = @{ output_mode = 'csv' exec_mode = 'oneshot' count = 0 search = "$($Search)" } } $Results = Invoke-RestMethod @IVRSplat Write-Verbose -Message "$($Results)" } } end { } } |