This is a surprisingly messy problem.
Unfortunately, I don't think that mvindex will work, because the multivalue field isn't going to contain duplicates -- each value for employee_id would only show up once.
Option 1: Regex Search and Backreference
Try this:
sourcetype=file_withdata | transaction maxspan=1h workstation_ip
| eval distinctusers=mvcount(userid)
| search distinctusers>1
| regex _raw="(?s).*?LOGON\s+\S+\s+(?<a>\S+)\s.*LOGON\s+\S+\s+(?<b>\1)"
This does a few things:
Runs your original transaction search to get the users logging on to each machine
Removes entries that don't have at least two different user IDs logging on
Pares the results down further, to just those whose first and last login lines have the same user ID
Unfortunately, it's not generalized to other log types, but it's a start.
Instead of the backreference, you could also use rex instead of regex to pull the first and last match into separate fields, then use eval to check that they're the same.
Option 2: Write a Custom Search Command
This sort of tracking would lend itself pretty well to a custom search script. Essentially, you'd be rolling your own version of the transaction command, but adding the checks to make sure you have at least one different employee id in the middle.
Overall, this may end up being the best option. It also has the fringe benefit of being more generic (you can base it on field values rather than raw text) and producing much shorter/simpler search strings.
Take a look here for more detail on that option.
Option 3: Simplify Your Requirements
If all you really care about is whether more than one user logged in to a given machine in a short period of time, you may be better off using stats :
sourcetype=file_withdata
| stats dc(employee_id) as dc first(employee_id) as a
last(employee_id) as b list(employee_id)
| eval is_same=if(a==b,1,0)
| search is_same=1 dc>0
This should work with smaller samples, but won't scale well as you increase the time span.
Option 4: Map command
The map command iterates over multiple search results. In theory you ought to be able to use an initial search and dedup to get a list of unique employee_id . Then use map to iterate over that list and look for your transactions, setting startswith=(employee_id=$employee_id$) and the same for endswith . In practice, I've never been able to get this to work, but not sure why.
... View more