2024-07-25 02:31:34 +01:00
|
|
|
function Search-Graylog {
|
|
|
|
<#
|
|
|
|
.SYNOPSIS
|
|
|
|
Queries Graylog for log data using the provided query and log stream name.
|
|
|
|
.DESCRIPTION
|
|
|
|
Query Graylog for log data using the provided query and log stream name. The query should contain the key:value pairs to search for, and the key should be the CASE-SENSITIVE field name to search within.
|
|
|
|
.PARAMETER Query
|
|
|
|
The search query to execute, should contain the key:value pairs to search for.
|
|
|
|
Example: "EventID:4740 && TargetUserName:ab123456" will search for all account lockouts for the user ab123456.
|
|
|
|
(Note that the LogId would need to be changed to the unique identifier for the Active Directory log stream in the above example)
|
|
|
|
.PARAMETER TimeSpan
|
|
|
|
The time span to search within, defaults to 7 days.
|
|
|
|
.PARAMETER LogName
|
|
|
|
The name of the log stream to search within, defaults to "Windows Security".
|
|
|
|
.PARAMETER Limit
|
|
|
|
The maximum number of results to return, defaults to 150.
|
|
|
|
.PARAMETER SortField
|
|
|
|
The field to sort the results by, defaults to "timestamp".
|
|
|
|
.PARAMETER SortOrder
|
|
|
|
The order to sort the results by, defaults to "desc".
|
|
|
|
.PARAMETER AsJob
|
|
|
|
An optional switch to run the search job as a background job.
|
|
|
|
.PARAMETER Detailed
|
|
|
|
An optional switch to return the search job details instead of the results (only does anything when -AsJob is not used).
|
|
|
|
.OUTPUTS
|
|
|
|
A PSCustomObject containing the SearchId, QueryId, and FilterId of the search job.
|
|
|
|
.EXAMPLE
|
|
|
|
Start-GraylogJob -Query "EventID:4740 && TargetUserName:ab123456"
|
|
|
|
Starts a search job for all account lockouts for the user ab123456.
|
|
|
|
.NOTES
|
|
|
|
A identifier for various parts of the search job (SearchId, QueryId, FilterId) are generated and returned in a PSCustomObject, which can be used to retrieve the results of the search job.
|
|
|
|
The SearchId, QueryId, and FilterId are used to retrieve the results of the search job using the Receive-GraylogJob function.
|
|
|
|
#>
|
2024-07-25 03:11:42 +01:00
|
|
|
[Alias("sg")]
|
2024-07-25 02:31:34 +01:00
|
|
|
param (
|
|
|
|
[Parameter(Mandatory)]
|
|
|
|
[ValidateNotNullOrEmpty()]
|
|
|
|
[string]
|
|
|
|
$Query,
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[TimeSpan]
|
|
|
|
$TimeSpan = [TimeSpan]::FromDays(7),
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[ValidateSet("Infoblox", "Infoblox DNS", "Windows Application", "Windows Security", "Windows System")]
|
|
|
|
[string]
|
|
|
|
$LogName = "Windows Security",
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[int]
|
|
|
|
$Limit = 150,
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[string]
|
|
|
|
$SortField = "timestamp",
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[ValidateSet("desc", "asc")]
|
|
|
|
[string]
|
|
|
|
$SortOrder = "desc",
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[switch]
|
|
|
|
$AsJob,
|
|
|
|
|
|
|
|
[Parameter()]
|
|
|
|
[switch]
|
|
|
|
$Detailed
|
|
|
|
)
|
|
|
|
|
2024-07-25 03:11:15 +01:00
|
|
|
$LogId = Get-GraylogStreamId -LogName $LogName
|
2024-07-25 02:31:34 +01:00
|
|
|
if ($null -eq $LogId) { throw "The log stream '$LogName' does not exist." }
|
|
|
|
$SearchId = [String]::Join('', [GUID]::NewGUID().GUID.Replace("-", "")[0..23]) # Generate a unique identifier for the search
|
|
|
|
$QueryId = [GUID]::NewGUID().GUID.ToString() # Generate a unique identifier for the query
|
|
|
|
$FilterId = [GUID]::NewGUID().GUID.ToString() # Generate a unique identifier for the filter
|
|
|
|
|
|
|
|
$Request = @{
|
|
|
|
Method = "POST"
|
|
|
|
Path = "/views/search"
|
|
|
|
Body = ConvertTo-JSON -Depth 7 @{
|
|
|
|
id = $SearchId
|
|
|
|
queries = @(
|
|
|
|
@{
|
|
|
|
id = $QueryId
|
|
|
|
query = @{
|
|
|
|
type = "elasticsearch"
|
|
|
|
query_string = $Query
|
|
|
|
}
|
|
|
|
timerange = @{
|
|
|
|
type = "relative"
|
|
|
|
from = $TimeSpan.TotalSeconds
|
|
|
|
}
|
|
|
|
filter = @{
|
|
|
|
type = "or"
|
|
|
|
filters = @(@{
|
|
|
|
type = "stream"
|
|
|
|
id = $LogId
|
|
|
|
})
|
|
|
|
}
|
|
|
|
filters = @()
|
|
|
|
search_types = @(@{
|
|
|
|
id = $FilterId
|
|
|
|
query = $null
|
|
|
|
timerange = $null
|
|
|
|
offset = 0
|
|
|
|
streams = @()
|
|
|
|
decorators = @()
|
|
|
|
type = "messages"
|
|
|
|
limit = $Limit
|
|
|
|
filters = @()
|
|
|
|
sort = @(@{
|
|
|
|
field = $SortField.ToLower()
|
|
|
|
order = $SortOrder.ToUpper()
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
)
|
|
|
|
parameters = @()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$QuerySuccess = $true
|
|
|
|
try { $null = Invoke-GraylogRequest @Request }
|
|
|
|
catch { $QuerySuccess = $false }
|
|
|
|
|
|
|
|
if ($AsJob) {
|
|
|
|
return [PSCustomObject]@{
|
|
|
|
Success = $QuerySuccess
|
|
|
|
SearchId = $SearchId
|
|
|
|
QueryId = $QueryId
|
|
|
|
FilterId = $FilterId
|
|
|
|
Request = $Request
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$RetrievalSuccess = $true
|
|
|
|
try { $Data = Receive-GraylogSearchJob -SearchId $SearchId -QueryId $QueryId -FilterId $FilterId }
|
|
|
|
catch { $RetrievalSuccess = $false }
|
|
|
|
if (-NOT $Detailed) { return $Data }
|
|
|
|
else {
|
|
|
|
return [PSCustomObject]@{
|
|
|
|
QuerySuccess = $QuerySuccess
|
|
|
|
RetrievalSuccess = $RetrievalSuccess
|
|
|
|
Data = $Data
|
|
|
|
SearchId = $SearchId
|
|
|
|
QueryId = $QueryId
|
|
|
|
FilterId = $FilterId
|
|
|
|
Request = $Request
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|