Powershell,  Splunk

Access splunk API with powershell

Faced with Splunk (automatic data collection and processing system). Wrote several powershell functions to automate access to splunk search queries via rest api.

As usual we will use cmdlet invoke-webrequest to access the rest api. The logic is as follows:

  • log in, get a token, which we will use in the future searches;
  • activate splunk search and get search sid;
  • check if the search job on the splunk server has been completed;
  • get the result.

Enter splunk credentials and url of splunk server:

$Credential= New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList 'username',('password' | ConvertTo-SecureString -AsPlainText -Force)

$url = "https://splunk.server.com:8089"

Powershell function to authorize on splunk server. This function returns token, wich we will use in next function:

function Splunk-Auth {
 [CmdletBinding()]
    
    Param
    (
        [Parameter(Mandatory=$true)]        
        [Uri]$Url,
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential = [System.Management.Automation.PSCredential]::Empty
    )

$UserName = $Credential.UserName
$Password = $Credential.GetNetworkCredential().Password

$Headers = @{
'username'=$UserName
'password'=$Password}

$Loginurl = $url.AbsoluteUri + "services/auth/login"
[regex]$sessionKey = "(?<=<sessionKey>)(.*)(?=<\/sessionKey>)"

try {
$Content = (Invoke-WebRequest -uri $Loginurl -Method Post -Body ($Headers) -ContentType "application/json" -UseBasicParsing -ErrorAction Stop).content
}
catch {
return $Error[0].Exception
}

if($Content) {
$Key = "Splunk " + $sessionKey.Match($content).Value
}
if (!$Content -OR !$Key) {
return "Error. No valid key returned by $Loginurl"
}
return $Key
}

Powershell function to activate splunk search via rest api. This function creates new search job on splunk server and returns the sid of this job. Mandatory parameters:

  • url – splunk server url;
  • key – token we get in first step;
  • search – a search expression may contain * and be quite complex. For a better understanding, I advise you to study the splunk documentation;
function Splunk-Search {
 [CmdletBinding()]
    
    Param
    (
        [Parameter(Mandatory=$true)]
        [Uri]$Url,
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [string]$Key,
        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [string]$Search,        
        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [datetime]$Startdt=(get-date).addhours(-1),
        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [datetime]$Enddt=(get-date)
    )
$Search = 'search ' + $Search
$Searchurl = $url.AbsoluteUri + "services/search/jobs"
[regex]$Jobsid = "(?<=<sid>)(.*)(?=<\/sid>)"

$Startdtunix = [int64](($Startdt.ToUniversalTime()) - (get-date "1/1/1970")).TotalSeconds
$Enddtunix = [int64](($Enddt.ToUniversalTime()) - (get-date "1/1/1970")).TotalSeconds

$Auth = @{'Authorization'=$Key}
$Body = @{'search'= $Search
          'earliest_time' = $Startdtunix
          'latest_time' = $Enddtunix          
          }

try {
$Content = (Invoke-WebRequest -uri $Searchurl -Method Post -Headers $Auth -Body $Body -ContentType "application/json" -UseBasicParsing -ErrorAction Stop).content
}
catch {
return $Error[0].Exception
}

if($Content) {
$Sid = $Jobsid.Match($Content).Value.ToString()
}
if (!$Content -OR !$Sid) {
return "Error. No valid sid returned by $Searchurl"
}
return $Sid
}

Powershell function to check splunk search job status. Accepts sid and token that we received in the previous steps. Returns the percentage of completed job. This percent, in my opinion, is rather approximate. When the job is finished, the function will return “DONE”.

function Splunk-JobStatus {
 [CmdletBinding()]
    
    Param
    (
        [Parameter(Mandatory=$true)]
        [Uri]$Url,
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [string]$Key,
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [string]$Sid     
    )

$Joburl = $url.AbsoluteUri + "services/search/jobs/" + $Sid
$Auth = @{'Authorization'=$Key}

try {
$Content = (Invoke-WebRequest -uri $Joburl -Method Get -Headers $Auth -UseBasicParsing -ErrorAction Stop).content
}
catch {
return $Error[0].Exception
}

if($Content) {
$State =  (([xml]$Content).entry.content.dict.key | ? {$_.name -eq 'isdone'}).innertext
if ($State) {
if ($State -eq 1){return "DONE"}
else {
return ((([xml]$Content).entry.content.dict.key | ? {$_.name -eq 'dispatchState'}).innertext + " - " + [math]::Round([float]((([xml]$Content).entry.content.dict.key | ? {$_.name -eq 'doneProgress'}).innertext) * 100))
}
}
}

if (!$Content -OR !$State) {
return "Error. No valid jobstate returned by $Joburl"
}
}

Powershell function to get splunk search job results. Accepts job sid and authorization token. Returns the result and immediately converts it from the JSON format.

function Splunk-JobResult {
 [CmdletBinding()]
    
    Param
    (
        [Parameter(Mandatory=$true)]
        [Uri]$Url,
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [string]$Key,
        [Parameter(Mandatory=$true)]
        [ValidateNotNull()]
        [string]$Sid     
    )

$JobResultUrl = $url.AbsoluteUri + ("services/search/jobs/{0}/results?output_mode=json&count=0" -f $Sid)

$Auth = @{'Authorization'=$Key}

try {
$Content = (Invoke-WebRequest -uri $JobResultUrl -Method Get -Headers $Auth -UseBasicParsing -ErrorAction Stop).content
}
catch {
return $Error[0].Exception
}

if($Content) {
return ($Content | ConvertFrom-Json).results
}
else {
"Error. No valid jobstate returned by $JobResultUrl"
}
}

Leave a Reply