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

Advertisment to support michlstechblog.info

Add a comment »9 comments to this article

  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

    Reply

    • 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 and the nodes of the altered Taskfile. The exact property names of the Eventlog entry can be found in the XML view of the event.

      Michael

      Reply

  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!

    Reply

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

    Reply

    • Hi Pandaranum,

      makes this sence 🙂 ? What were you aiming to achieve with an empty parameter?

      Michael

      Reply

      • 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

        Reply

        • 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

          Reply

  4. I have an event that just writes:

    fubar

    How would that be referenced in the scheduled task XML?

    Reply

  5. Michael,
    I’m in love with you.
    Thank you for great description!!!

    Reply

Time limit is exhausted. Please reload CAPTCHA.

Original Theme by Schiy · Powered by WordPress