Getting Data In

[powershell://...] input working example and some pitfalls

ololdach
Builder

Hi Splunkerds,

I have struggled with powershell for a while and thought that after all the great tips I got from you, I'd repay you by posting a solution. The problem is, that the documentation for the inputs.conf section on powershell offers little to none help to actually get things right. Some things to note that the documentation seems to miss are:

- If your script returns strings, then every line of output will be a single event and it will bypass anything that you do in order to reassemble the events. Forget SHOULD_LINEMERGE and LINE_BREAKER. They are simply ignored as if the UF using the powershell input actually passes cooked events to splunk.

- Consequently, as a result of the above: If you want to pass anything more complex than a single line, you have to pass the events as powershell objects

Now for a practical and working example, let's pull the output of the certutil.exe into splunk using powershell:

First, test the command in powershell to see the raw data: 

 

 

# certutil -view -out 'NotBefore,NotAfter,SerialNumber,RequestID,CertificateTemplate,DistinguishedName'

 

 

Now, for the solution, let's take a look at inputs.conf:

 

 

[powershell://CertStore-LocalUser]
disabled = 0
script = . "$SplunkHome\etc\apps\<yourappname>\bin\Get-LocalUserCertificates.ps1"
schedule = */30 * * * *
sourcetype = windows:certs

 

 

Note the script line: It's taken me some time to get the invocation right. The docs could be clearer.

Here is the content of the Get-LocalUserCertificates.ps1 script located in the <yourappname>/bin directory as an example/template of how to take a linear (string) based input, iterate over the lines, cut them with regexes and create new objects for every Row or Entry section, assign the keys and pass them to splunk:

 

 

$certutil = "$($env:SystemRoot)\system32\certutil.exe"
$certutilOutput = Invoke-Expression "$certutil -view -out 'NotBefore,NotAfter,SerialNumber,RequestID,CertificateTemplate,DistinguishedName'"
 
$currentKey = $null
$currentValue = $null
$certutilOutput -split [environment]::NewLine | foreach {
 
    switch -regex ($_){
 
        '[Entry|Row] \d+:(.*)' {
            # New Object found
            $currentObject = New-Object psobject
            $currentValue = $null
            continue
        }
 
        '(\s{2})(?<key>[\w\s]+):\s*(?<value>.*)' {
            # Add key / value pair to Object
            if($currentObject){ 
                if( -not $matches.value){
                    $currentKey = $matches.key.Trim()
                    $currentValue = $null
                }
                else {
                    $currentObject | Add-Member -MemberType NoteProperty -Name $($matches.key.Trim()) -Value $($matches.value.trim(@("'",'"','`'))) -Force 
                }
            }
        }
 
        '^$' {
            # if it exists, pass the object to splunk
            if($currentObject){ 
                if($currentKey -and $currentValue){
                    $currentObject | Add-Member -MemberType NoteProperty -Name $($currentKey) -Value $($currentValue) -Force 
                }
                # pass the object to splunk
                $currentObject 
                # reset the object after it has been passed
                $currentObject = $null
                $currentKey = $null
                $currentValue = $null
            }
        }
        default {
            # Save Values of Multiline Parameters if a current Key exists
            if($currentObject -and $currentKey){ 
                $currentValue += $_+"`n"
            }
        }
    }
}
 
# return the last row object
if($currentKey -and $currentValue){
    $currentObject | Add-Member -MemberType NoteProperty -Name $($currentKey) -Value $($currentValue) -Force 
}
$currentObject

 

 

 Note: If your command delivers a list of PS Objects, you just iterate over that list with .Next, passing ever object that your list holds. 

Hope it helps somebody!

Happy splunkin'

Oliver

lithium43
Observer

Thanks for your response and the pieces are starting to fall into place.  It still seems confusing that I'm seeing [script://....] that seems to call PowerShell as well as [powershell://...] also calling PowerShell with one using schedule and the other using interval.  Really looks messy which might explain why .bat and .py scipts seem to work so much better (especially on Unix systems) but this could be my OCD kicking in.

0 Karma

PickleRick
SplunkTrust
SplunkTrust

These are two separate mechanisms. Powershell has some features that script input doesn't (most important being the ability to receive powershell objects, not just text).

0 Karma

lithium43
Observer

This may be a noob question but what is the first line of the inputs.conf entry defining?  Does everything within the brackets, [powershell://CertStore-LocalUser], provide function or is this a commented area?

0 Karma

PickleRick
SplunkTrust
SplunkTrust

It's a stanza defining a type of input (powershell in this case) and a unique name for it. In some cases (for example the monitor inputs) input names also have functional meaning (monitor input name points to monitored files or directories on disk).

0 Karma
Get Updates on the Splunk Community!

Enter the Splunk Community Dashboard Challenge for Your Chance to Win!

The Splunk Community Dashboard Challenge is underway! This is your chance to showcase your skills in creating ...

.conf24 | Session Scheduler is Live!!

.conf24 is happening June 11 - 14 in Las Vegas, and we are thrilled to announce that the conference catalog ...

Introducing the Splunk Community Dashboard Challenge!

Welcome to Splunk Community Dashboard Challenge! This is your chance to showcase your skills in creating ...