Windows PowerShell is an object-oriented automation engine and scripting language with an interactive command-line shell designed to help IT professionals configure systems and automate administrative tasks. You can find it in every modern Windows OS starting with Windows 2008R2. Every desktop operating system allows its users to run scripts. On Windows 10, you can run a batch script, a PowerShell script, an AHK script, a VBS script, and more. One script type you can’t run out of the box is a Shell script. A Shell script is written and used on Linux systems.
This will create an event triggered scheduled task that will run a powershell script. The powershell script will be able to accept data from the event that triggered the task
The example I am using here runs a powershell script every time a 4624 Logon event occurs in the Security log where the user logging in is either 'king' or 'tuser'. The powershell script illustrates how to both accept data directly from the event and/or to pull in the event with Get-WinEvent.
18 Steps total
Step 1: Attach a task to an event
From the windows event viewer, right click the task you want and select 'Attach Task To This Event...'
In this example, I am going to run a script for logon events, 4624, in the Security Log.
Step 2: Select Start A Program as an Action
Click through the fist few screens of the Create a Basic Task Wizard, and on the Action section select 'Start a Program'. Click Next.
Script Windows Backup
Step 3: Add Powershell.exe and the path to your script.
Put Powershell.exe as the program and the full path to the script in the arguments list.
If you have issues getting the script to run, check out the following how to on additional items that can be put in the arguments list: http://community.spiceworks.com/how_to/17736-run-powershell-scripts-from-task-scheduler
Step 4: (Optional, Event Selection) Select open the properties, and finish.
If you wanted to run the script on all occurrences of your event, continue to Step 10.
If you want to add more complicated selection criteria then select 'Open the Properties...' checkbox and Finish.
Step 5: (Optional, Event Selection) Edit the event trigger.
On the triggers tab, select the event trigger, and click edit.
Step 6: (Optional, Event Selection) Select custom and New Event Filter.
Step 7: (Optional, Event Selection) Fill out your Log and Event ID, and click the XML tab.
For the example, I am entering the Security log and event id 4624.
Step 8: (Optional, Event Selection) Enter your XPath filter between the Select tags.
The XPath you enter here is the same syntax used to create custom views. I suggest that you test what you put here in a custom view in the event viewer to make sure it is selecting the right events first.
The example xpath here is selecting all 4624 events where the users 'king' or 'tuser' logon. I should note here that this will create a lot of events. It might be a good idea to limit this to only certain logon types, too, but for this example, I wanted to keep the XPath as simple as possible, yet still illustrate something you can do beyond the options provided in the standard dialog box.
For more information on XPath filters for winevents see: http://www.powershellish.com/blog/2014/12/09/get-winevent-filterxpath/
For my XPath generator script: http://community.spiceworks.com/scripts/show/3238-powershell-xpath-generator-for-windows-events
Step 9: (Optional, Event Selection) Hit OK, twice to set the custom trigger, and save the task.
Step 10: (Optional, Concurrent Events) Set options for concurrent events
Sometimes multiple events will happen before the event trigger can call the script and the script to finish execution. In those cases, the default setting of the event trigger will opt not to start the task.
To ensure that the script runs for each event choose to either queue the event if the task is already running, or to run them in parallel.
Script Windows 10
Keep in mind that for frequent events, parallel might bog the system down. And, either option could possibly cause a condition where the scheduled task might not be able to keep up with the number of events. It's a good idea, for frequent events, to try to limit the event selection to be as narrow as is possible. See steps (Optional, Event Selection).
Step 11: Export the Scheduled Task Configuration as an XML file.
Find the scheduled task created and right click the task and click export and save the task definition as an xml file.
Step 12: Add ValueQueries to the Scheduled Task XML file.
Before the closing tag of EventTrigger, put in a ValueQueries tag. This is where you tell the scheduled task what data from the event you want to pass to your powershell script. Inside ValueQueries, you'll have a Value tag for each value you want passed to the powershell script.
In my example, I want to get the event's channel (i.e. Log Name), the unique event identifier (i.e. EventRecordID), and to illustrate the possibilities, the account name of the user who logged in. The following is the ValueQueries tag for the example:
NOTE: Capitalization is significant here.
Event/EventData/Data[@Name='TargetUserName']
Event/System/Channel
Event/System/EventRecordID
Step 13: Add Values using XPath Syntax based on the Event's XML
The value tag's text is xpath syntax derived from the event's XML. If you open up an event in the event log and switch to XML view, you can see how the xml is laid out.
Step 14: In your powershell script, add parameters for each value you want passed in.
In your powershell script, create a param block and add a parameter for each of the values you want passed in to the script.
Step 15: Back in the XML file, change the argument list
Back in the XML file, change the argument list to pass the values from the event to the powershell script. The values from the event will be defined like. '$(eventChannel)' This looks similar to powershell syntax, it isn't. It is specific to the passing of data from the event to your script.
Step 16: Delete the original task.
Yes the task we created was a dummy task, just to get the initial xml file created.
Step 17: Save and Import the XML file back into Scheduled Tasks
Step 18: Set the task with an account with appropriate permissions and set to run if logged out.
Set up the scheduled task so that the powershell script has the permissions it needs, and set it so that it runs if the user isn't logged in.
References
- A missing piece
- TechNet Blogs
10 Comments
- Ghost ChiliMichael (Netwrix) Oct 8, 2015 at 03:46pm
You need to mention that this doesn't work on Windows Server 2012R2.
- Macecduff Oct 8, 2015 at 04:04pm
Are you referring to the send an email action as opposed to the start a program action? Because, this still works.
- DatilNicolas1847 Oct 9, 2015 at 06:30am
Great How-To Cduff. I used the same technique to log efficiently (without asking for a painfully slow Get-EventLog) the bad login attemps over the domain, and the only thing that misses for me is a way to have a feedback on why it does not work, as when you manipulate the xml files and have a single syntax error, you don't have anything that tells you why it does not work.
And Michael, I had it working on a 2012 server, is there something specific on R2 version? - Ghost ChiliMichael (Netwrix) Oct 9, 2015 at 10:26am
cduff, Yeah, probably I did something wrong, sorry. I've tested it once again and it worked!
- Macecduff Oct 9, 2015 at 12:12pm
Nicolas, yeah its a bit troublesome like that. It took me over an hour of trial and error until I was able to get it all sorted out for this how-to. It is really hard to code it blind, but once its working, its great.
- DatilThomas0311 Feb 5, 2016 at 11:22am
I believe that's how it is with any coding experience, cduff. ;-)
- Pimientokortex Jul 1, 2017 at 10:56am
Thank you for this post. You really helped me a lot!
- Pimientothatguy4 Feb 22, 2018 at 01:22am
This post was fantastic. One thing i couldnt get working however was getting the systemtime. Any ideas on where im going wrong below?
Event/System/TimeCreated[@Name='SystemTime']
Thanks
- Macecduff Feb 22, 2018 at 02:33am
Event/System/TimeCreated/@SystemTime
That should do it.
Explanation:
The square braces I had in Event/EventData/Data[@Name='TargetUserName'] are a conditional of the Data element, but it still is trying to get the text inside Data, but only the Data that has a Name attribute equal to TargetUserName.
Since you are after what is directly inside the SystemTime attribute you just select it after another slash.
Take for example this snippet from the XML of an event:
SYSTEM
NT AUTHORITYThe Xpath:
Data[@Name='TargetUserName']
Says to get SYSTEM, but pass over NT AUTHORITY, since that is the only Data element that has a Name attribute that is equal to TargetUserName.
So the XML for system time is:
Note that there is nothing inside of TimeCreated; its a self closing tag. The XPath:
TimeCreated/@SystemTime
Says to get the actual value of the attribute SystemTime that is inside of TimeCreated.
- Pimientothatguy4 Feb 22, 2018 at 04:38am
Worked like a charm and the explanation cleared my confusion up as well.
Thank you again cduff
Script Windows 10
Windows Script Host provides an environment in which users can execute scripts in a variety of languages that use a variety of object models to perform tasks.
Syntax
Parameters
Script Windows Sandbox
Parameter | Description |
---|---|
scriptname | Specifies the path and file name of the script file. |
/b | Specifies batch mode, which does not display alerts, scripting errors, or input prompts. This is the opposite of /i. |
/d | Starts the debugger. |
/e | Specifies the engine that is used to run the script. This lets you run scripts that use a custom file name extension. Without the /e parameter, you can only run scripts that use registered file name extensions. For example, if you try to run this command:cscript test.admin You will receive this error message: Input Error: There is no script engine for file extension .admin. One advantage of using nonstandard file name extensions is that it guards against accidentally double-clicking a script and running something you really did not want to run. This does not create a permanent association between the .admin file name extension and VBScript. Each time you run a script that uses a .admin file name extension, you will need to use the /e parameter. |
/h:cscript | Registers cscript.exe as the default script host for running scripts. |
/h:wscript | Registers wscript.exe as the default script host for running scripts. This is the default when the /h option is omitted. |
/i | Specifies interactive mode, which displays alerts, scripting errors, and input prompts. This is the default and the opposite of /b. |
/job:<identifier> | Runs the job identified by identifier in a .wsf script file. |
/logo | Specifies that the Windows Script Host banner is displayed in the console before the script runs. This is the default and the opposite of /nologo. |
/nologo | Specifies that the Windows Script Host banner is not displayed before the script runs. This is the opposite of /logo. |
/s | Saves the current command prompt options for the current user. |
/t:<number> | Specifies the maximum time the script can run (in seconds). You can specify up to 32,767 seconds. The default is no time limit. |
/x | Starts the script in the debugger. |
ScriptArguments | Specifies the arguments passed to the script. Each script argument must be preceded by a slash (/). |
/? | Displays Help at the command prompt. |
Remarks
- Performing this task does not require you to have administrative credentials. Therefore, as a security best practice, consider performing this task as a user without administrative credentials.
- To open a command prompt, on the Start screen, type cmd, and then click command prompt.
- Each parameter is optional; however, you cannot specify script arguments without specifying a script. If you do not specify a script or any script arguments, wscript.exe displays the Windows Script Host Settings dialog box, which you can use to set global scripting properties for all scripts that wscript.exe runs on the local computer.
- The /t parameter prevents excessive running of scripts by setting a timer. When the time exceeds the specified value, wscript interrupts the script engine and ends the process.
- Windows script files usually have one of the following file name extensions: .wsf, .vbs, .js.
- If you double-click a script file with an extension that has no association, the Open With dialog box appears. Select wscript or cscript, and then select Always use this program to open this file type. This registers wscript.exe or cscript.exe as the default script host for files of this file type.
- You can set properties for individual scripts. See Windows Script Host overview for more information.
- Windows Script Host can use .wsf script files. Each .wsf file can use multiple scripting engines and perform multiple jobs.