Windows: Passing parameters to event triggered schedule tasks

Hi,

this week I had the problem on a Windows Server 2008 R2 system that I had to recognize if a network connection to specific closed TCP port is tried to established.

The Windows firewall on the machine is running but logs only packets to the firewall  logfile for tcp and udp ports an which a process is listen to. Also the parsing of the logfile is frequently necessary.

A better way is to enable the firewall audit option “Filtering Platform Packet Drop”. This generates an EventLog entry with EventID 5152 for each incoming packet which is dropped. Windows provides the abiltiy to trigger an schedule task after an eventlog entry is written and pass some event details as parameter to a script defined in the task.  Unfortunataly not with the GUI.

Turn the Windows Firewall on and if not set by a domain policy open the Group policy object editor and enable these two policies:

Computer Configuration Windows Settings Security Settings Local Policies Security Options Audit: Force audit policy subcategory settings: enable Computer Configuration Windows Settings Security Settings Advanced Audit Policy Configuration System Audit Policies Object Access Filtering Platform Packet Drop: Faliure

Check if they are active:

D:\>reg query HKLM\System\CurrentControlSet\Control\Lsa /v SCENoApplyLegacyAuditPolicy HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa SCENoApplyLegacyAuditPolicy REG_DWORD 0x1  D:\>auditpol /get /SubCategory:{0CCE9225-69AE-11D9-BED3-505054503030} System audit policy Category/Subcategory Setting Object Access Filtering Platform Packet Drop Failure

Check if packets were logged. I use nmap. Start a port scan on a second system, bootet with a live linux such as Knoppix or Kali Linux, against your Windows System

root@live # nmap -sT -p 9100-9110 192.168.1.1 9100/tcp filtered jetdirect 9101/tcp filtered jetdirect 9102/tcp filtered jetdirect 9103/tcp filtered jetdirect 9104/tcp filtered jetdirect 9105/tcp filtered jetdirect 9106/tcp filtered jetdirect 9107/tcp filtered jetdirect 9108/tcp filtered unknown 9109/tcp filtered unknown 9110/tcp filtered unknown

Filtered means packet were dropped. Entries with EventID 5152 and Source “Microsoft Windows security auditing.” are logged to the Security EventLog:

The Windows Filtering Platform has blocked a packet. Application Information:	Process ID:	0	Application Name:	- Network Information:	Direction:	Inbound	Source Address:	192.168.1.110	Source Port:	34135	Destination Address:	192.168.1.1	Destination Port:	9110	Protocol:	6 Filter Information:	Filter Run-Time ID:	79299	Layer Name:	Transport	Layer Run-Time ID:	13

Creating a triggered Schedule Task for this Event is quite simple. Select the Eventlog entry and choose “Attach a Task to this event” from the right click menu.

Attach a event triggered task
Attach a event triggered task

Define a name

Define a task name
Define a task name

Start a program

Start a program as action
Start a program as action

I  use a powershell script were you can do further actions.

Define Action script
Define Action script

Now, for each new log entry the script is called one time. But by default no information about the event was passed to the script. The task must be modified.

Export the task by the following command line.

[D:\]schtasks /query /TN "Event Viewer Tasks\EventLog-Action-Drop-Packets-5152" /XML > C:\temp\Export-EventLog-Action-Drop-Packets-5152.xml

Note: The Taskname is the relative path below the C:\Windows\System32\Tasks folder.

 C:\>dir "\Windows\System32\Tasks\Event Viewer Tasks" Volume in drive C is SYSTEM Volume Serial Number is FRD2-865E Directory of C:\Windows\System32\Tasks\Event Viewer Tasks 18.12.2013 15:15 <DIR> . 18.12.2013 15:15 <DIR> .. 18.12.2013 15:16 3.616 EventLog-Action-Drop-Packets-5152 1 File(s) 3.616 bytes 2 Dir(s) 36.972.118.016 bytes free

The export should looks like this

 <?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2013-12-18T19:06:56.6561506</Date> <Author>PC\localadm</Author> </RegistrationInfo> <Triggers> <EventTrigger> <Enabled>true</Enabled> <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Security"&gt;&lt;Select Path="Security"&gt;*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=5152]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription> </EventTrigger> </Triggers> <Principals> <Principal id="Author"> <RunLevel>LeastPrivilege</RunLevel> <UserId>PC\localadm</UserId> <LogonType>InteractiveToken</LogonType> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>P3D</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command> <Arguments>-Command D:\Event5152.ps1</Arguments> </Exec> </Actions> </Task>

You have to determine which parameters should be passed to the script. To get a list all possible values open an event with ID 5152 in event viewer, switch to Details and XML View.

 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event"> <System> <Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-A5BA-3E3B0328C30D}" /> <EventID>5152</EventID> <Version>0</Version> <Level>0</Level> <Task>12809</Task> <Opcode>0</Opcode> <Keywords>0x8010000000000000</Keywords> <TimeCreated SystemTime="2013-12-18T17:14:01.325613300Z" /> <EventRecordID>156715054</EventRecordID> <Correlation /> <Execution ProcessID="4" ThreadID="92" /> <Channel>Security</Channel> <Computer>PC.local</Computer> <Security /> </System> <EventData> <Data Name="ProcessId">0</Data> <Data Name="Application">-</Data> <Data Name="Direction">%%14592</Data> <Data Name="SourceAddress">192.168.1.100</Data> <Data Name="SourcePort">45345</Data> <Data Name="DestAddress">192.168.1.1</Data> <Data Name="DestPort">9100</Data> <Data Name="Protocol">17</Data> <Data Name="FilterRTID">79299</Data> <Data Name="LayerName">%%14597</Data> <Data Name="LayerRTID">13</Data> </EventData> </Event> 

Open the task export xml file with your favorite editor. Define a <ValueQueries> Node as child of the <EventTrigger> node and for each parameter a <Value> node under <ValueQueries>.

The name attribute of the Value Node is the variable name which will be used in the action node later. The text within the value node is the XPath query to select a detail from the event.

 <ValueQueries> <Value name="TimeCreated">Event/System/TimeCreated/@SystemTime</Value> <Value name="SourceAddress">Event/EventData/Data[@Name='SourceAddress']</Value> <Value name="SourcePort">Event/EventData/Data[@Name='SourcePort']</Value> <Value name="DestAddress">Event/EventData/Data[@Name='DestAddress']</Value> <Value name="DestPort">Event/EventData/Data[@Name='DestPort']</Value> </ValueQueries> 

Append these variables as parameters to the task action arguments

<Arguments>-Command D:\Event5152.ps1 '$(SourceAddress)' '$(SourcePort)' '$(DestAddress)' '$(DestPort)' '$(DestPort)' '$(TimeCreated)'</Arguments>

The new complete task definition:

 <?xml version="1.0" encoding="UTF-16"?> <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> <RegistrationInfo> <Date>2013-12-18T19:06:56.6561506</Date> <Author>PC\localadm</Author> </RegistrationInfo> <Triggers> <EventTrigger> <Enabled>true</Enabled> <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Security"&gt;&lt;Select Path="Security"&gt;*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and EventID=5152]]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription> <ValueQueries> <Value name="TimeCreated">Event/System/TimeCreated/@SystemTime</Value> <Value name="SourceAddress">Event/EventData/Data[@Name='SourceAddress']</Value> <Value name="SourcePort">Event/EventData/Data[@Name='SourcePort']</Value> <Value name="DestAddress">Event/EventData/Data[@Name='DestAddress']</Value> <Value name="DestPort">Event/EventData/Data[@Name='DestPort']</Value>	</ValueQueries> </EventTrigger> </Triggers> <Principals> <Principal id="Author"> <RunLevel>LeastPrivilege</RunLevel> <UserId>PC\localadm</UserId> <LogonType>InteractiveToken</LogonType> </Principal> </Principals> <Settings> <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries> <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries> <AllowHardTerminate>true</AllowHardTerminate> <StartWhenAvailable>false</StartWhenAvailable> <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> <IdleSettings> <StopOnIdleEnd>true</StopOnIdleEnd> <RestartOnIdle>false</RestartOnIdle> </IdleSettings> <AllowStartOnDemand>true</AllowStartOnDemand> <Enabled>true</Enabled> <Hidden>false</Hidden> <RunOnlyIfIdle>false</RunOnlyIfIdle> <WakeToRun>false</WakeToRun> <ExecutionTimeLimit>P3D</ExecutionTimeLimit> <Priority>7</Priority> </Settings> <Actions Context="Author"> <Exec> <Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command> <Arguments>-Command D:\Event5152.ps1 '$(SourceAddress)' '$(SourcePort)' '$(DestAddress)' '$(DestPort)' '$(DestPort)' '$(TimeCreated)'</Arguments> </Exec> </Actions> </Task>

Delete the old task
C:\>schtasks /Delete /TN "Event Viewer Tasks\EventLog-Action-Drop-Packets-5152"
WARNING: Are you sure you want to remove the task "Event Viewer Tasks\EventLog-A
ction-Drop-Packets-5152" (Y/N)? y
SUCCESS: The scheduled task "Event Viewer Tasks\EventLog-Action-Drop-Packets-5152" was successfully deleted.

import the new, altered task definition
C:\>schtasks /Create /XML c:\TEMP\Export-EventLog-Action-Drop-Packets-5152.xml /TN "Event Viewer Tasks\EventLog-Action-Drop-Packets-5152"
and create the action script. My script example (D:\Event5152.ps1) simply writes all parameters to a file.

 [string]$sOutput="" [string]$sOutputFile="d:\temp\Event5151.txt" $sOutput=(get-date).ToShortDateString()" "+(get-date).ToLongTimeString() if($args.Length -ge 1){	for($iLoop=0;$iLoop -lt $args.Length;$iLoop++){	$sOutput+=";"+$iLoop.ToString()+":"+$args[$iLoop]	} } Add-Content -path $sOutputFile -value $sOutput 

Thats it.

Michael

15 thoughts on “Windows: Passing parameters to event triggered schedule tasks”

  1. Nice article and it worked for me for AD user creation. I would like to create a scheduled task to notify me when DHCP leases are running low (System Log / Event 1020). Event 1020 doesn’t have names associated with the event data:

    172.18.202.32
    92
    1

    How would this change the parameter passed to the script? I am having trouble wrapping my head around this one. I thought about using $Args[0], $Args[1], etc but that doesn’t seem to work.
    Thank you

    1. Hi Bob,

      your right. The parameter are passed as command line parameter to the script ($argv[0] – $argv[n]).

      But you have to specify which parameter are passed. See the ValueQueries and the Arguments nodes of the altered Taskfile. The exact property names of the Eventlog entry can be found in the XML view of the event.

      Michael

  2. Hi,
    I want to go this for logging and user configuration purposes. I found a technet blog entry (h t t p://blogs.technet.com/b/wincat/archive/2011/08/25/trigger-a-powershell-script-from-a-windows-event.aspx), but it was yours that helped me to get the EventData processed!
    Many thanks for this!

  3. How can I pass an empty argument?
    I would like to pass something like-Command D:\Event5152.ps1 ‘$(SourceAddress)’ ” ‘$(TimeCreated)’
    Is this possible ?

      1. Hi Michael,
        I want to run the same batch file(which takes 3 args) when different events occurs. Now, I have an event which is using 2 parameters and another one which is using 3 parameters. I would like to run that batch file, as follows:

        (Ev.1) .bat $arg1[non-empty] $arg2[empty] $arg3[non-empty]
        (Ev.2) .bat $arg1[non-empty] $arg2[non-empty] $arg3[non-empty]

        I hope you understand !

        Thanks for your answer & BR

        1. Hi Pandoranum

          try

          D:\Event5152.ps1 ‘$(SourceAddress)’ ‘””‘ ‘$(TimeCreated)’

          but not sure if this works within an Scheduletask XML file.

          This should pass an empty argument:
          Test.ps1:
          write-host $Args.Count

          PS D:\Temp> .\test.ps1 f “” rt
          3

          Michael

  4. This is still a very useful article in 2020 and still relative for Windows Server 2016. I’d done something similar following other articles, but this one would have got me going a lot fast if I’d found it first.
    One thing I’ve done to make this work for various types of events is that I only pass along the EventChannel and EventRecordID to my PowerShell script. In my script I query the event log to grab that specific event and that gives my script access to every property of the event without having to specify which properties I want to use.

    This is the ValueQueries that I add to the exported xml

    Event/System/Channel
    Event/System/EventRecordID

    This is the element of the xml:
    -ExecutionPolicy Bypass -file “fully qualified path to script” -EventChannel “$(EventChannel)” -EventRecordID “$(EventRecordID)”

    This is the parameter declaration at the beginning of my PowerShell script:
    param([string]$EventChannel = “”, [string]$EventRecordID = “”)

    And this is the query to give my script access to the event:
    $eventLogEntry = (Get-WinEvent -LogName “$($EventChannel)” -FilterXPath “*[System[(EventRecordID=$($EventRecordID))]]” | Select-Object -First 1)

  5. Absolutely brilliant article, Michael! Thank you so much for all the explanations, the sample XML. I had seen another article that grabs the Event Number and makes a query to retrieve the specifics, but your method is so much better by getting it from the event’s XML and passing it as a variable. Can’t thank you enough for this beautiful method.

  6. Thanks. That’s exactly what I was looking for.
    I want to use this method for multiple different events.
    Is it possible to pass whole ‘EventData’ section to one parameter, or should I use Seth’s approach?

  7. Thanks a lot for all of this, very usefull. I searched for a looonnng time how to forward arguments from event to scheduled task ! 🙂

    I have only a little problem, my argument contains a ‘ in its value and then it is not forwarded correctly (cause arguments are surrounded by ‘ already).
    How to bypass this ?

  8. I have been searching a lot and used ChatGPT to find how to pass the parameters to a powershell script in a Windows Task. After a few hours, your solution worked.
    Thank you for this post.

  9. Thank you, with this info i mange to make a task that run a powershell script and pass the username of the user that logon and not only the user that made the task (on a terminal server).

Leave a Reply