This artifact enables grep of IISLogs.
Parameters include SearchRegex and WhitelistRegex as regex terms and MoreRecentThan as timestamp.
Hint: Make sure to get the right location of the log files as they are often stored at different non-default locations.
Hint 2: MoreRecentThan filter is only applied to the Last Modified Time of files returned by the IISLogFiles glob. This improves the artefact’s performance on systems with many log files. Use the SearchRegex filter for filtering on a per line basis.
For example, a regex like 2025-07-2[1-5]
will efficiently
recover lines with ISO times between the 21st and 25th July 2025.
name: Windows.Applications.IISLogs
description: |
This artifact enables grep of IISLogs.
Parameters include SearchRegex and WhitelistRegex as regex terms and
MoreRecentThan as timestamp.
**Hint:** Make sure to get the right location of the log files as
they are often stored at different non-default locations.
**Hint 2:** MoreRecentThan filter is only applied to the Last
Modified Time of files returned by the IISLogFiles glob. This
improves the artefact's performance on systems with many log
files. Use the SearchRegex filter for filtering on a per line
basis.
For example, a regex like `2025-07-2[1-5]` will efficiently
recover lines with ISO times between the 21st and 25th July 2025.
author: "Matt Green - @mgreen27, Updated by Stephan Mikiss"
parameters:
- name: IISLogFiles
default: '*:/inetpub/logs/**3/*.log'
- name: MoreRecentThan
default: ""
type: timestamp
- name: SearchRegex
description: "Regex of strings to search in line."
default: ' POST '
type: regex
- name: WhitelistRegex
description: "Regex of strings to leave out of output."
default:
type: regex
sources:
- precondition: SELECT OS From info() where OS = 'windows'
query: |
LET files = SELECT OSPath,Mtime AS MTime FROM glob(globs=IISLogFiles)
LET more_recent = SELECT * FROM if(
condition=MoreRecentThan,
then={
SELECT * FROM files
WHERE MTime > MoreRecentThan
}, else=files)
SELECT * FROM foreach(row=more_recent,
query={
SELECT Line, OSPath FROM parse_lines(filename=OSPath)
WHERE
Line =~ SearchRegex
AND NOT if(condition= WhitelistRegex,
then= Line =~ WhitelistRegex,
else= FALSE)
})
notebook:
- type: vql_suggestion
name: IIS Groks
template: |
/*
### IIS grok
Note: IIS doesn't have a standard logging format so we have added some
suggestions. Comment in preferred or add / modify your own.
*/
LET target_grok = "%{TIMESTAMP_ISO8601:LogTimeStamp} %{IPORHOST:Site} %{WORD:Method} %{URIPATH:UriPath} %{NOTSPACE:QueryString} %{NUMBER:Port} %{NOTSPACE:Username} %{IPORHOST:Clienthost} %{NOTSPACE:Useragent} %{NOTSPACE:Referrer} %{NUMBER:Response} %{NUMBER:Subresponse} %{NUMBER:Win32status} %{NUMBER:Timetaken:int}"
--LET target_grok = "%{TIMESTAMP_ISO8601:log_timestamp} %{IPORHOST:site} %{WORD:method} %{URIPATH:page} %{NOTSPACE:querystring} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clienthost} %{NOTSPACE:useragent} %{NOTSPACE:referer} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:scstatus} %{NUMBER:timetaken:int}"
--LET target_grok = "%{TIMESTAMP_ISO8601:log_timestamp} %{WORD:iisSite} %{NOTSPACE:computername} %{IPORHOST:site} %{WORD:method} %{URIPATH:page} %{NOTSPACE:querystring} %{NUMBER:port} %{NOTSPACE:username} %{IPORHOST:clienthost} %{NOTSPACE:protocol} %{NOTSPACE:useragent} %{NOTSPACE:referer} %{IPORHOST:cshost} %{NUMBER:response} %{NUMBER:subresponse} %{NUMBER:scstatus} %{NUMBER:bytessent:int} %{NUMBER:bytesrecvd:int} %{NUMBER:timetaken:int}"
LET parsed = SELECT Fqdn, ClientId as _ClientId, Line as _Raw,
grok(data=Line,grok=target_grok) as GrokParsed
FROM source()
SELECT * FROM foreach(row=parsed,
query={ SELECT *, Fqdn, _Raw FROM GrokParsed })