Get-WinEvent 4625 password spray
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4625;StartTime=(Get-Date).AddHours(-1)} | Group-Object {$_.Properties[5].Value}
Group failed logons (Event 4625) from the last hour by user to detect password spraying in the domain.
Run it when you want to detect password spraying: the attacker tries one or two passwords against many users to avoid locking accounts. The signature is the inverse pattern of brute force: few failures per user, many distinct users, same password. Grouping the 4625s by user (Properties[5] in the event) and looking at the total volume gives you the picture: if in one hour there are failures on 40 distinct accounts from the same source IP, it's spray. It's the first query a level 1 analyst runs on an alert of massive failed logons.
Don't use it as a definitive detection: the 4625 doesn't include the password tried, so grouping by user only gives you the volume, not the proof that it's the same password. To confirm the spray you need the source IP (Properties[13]) and temporal correlation. And watch out for noise: in networks with applications using expired credentials (services with poorly rotated accounts), there are constant failures that dirty the signal. Filter by logon type (Properties[8]: 3 network, 8/10 for services) and by IP before alerting. Also, sprays against Kerberos escape you if the attacker uses AS-REP or brute force on 4768.