1

I would like to have a Scheduled Task that runs as SYSTEM but is triggered by a user action and is on a delay. That part doesn't seem so hard.

The hard part is that I want the (PoSh) script that runs to be able to identify which user triggered the task. How might I go about doing that?

Because it is on a delay, the action may no longer be in play. Since the task delays are random (with a max delay), I don't have a specific time.

Vomit IT - Chunky Mess Style
  • 40,038
  • 27
  • 84
  • 117
Teknowledgist
  • 358
  • 5
  • 16
  • What is the user action? – harrymc Apr 22 '21 at 14:47
  • How are they executing the task, via the Task Scheduler GUI? Check Event Viewer | Application and Services Logs | Windows PowerShell. Otherwise if you can change it so they execute a script that then programmatically executes the scheduled task and have it log the `$Env:Username` variable to a log file before the task scheduler execution or something like that. Just some quick ideas but I don't have time to test or write an answer at the moment. – Vomit IT - Chunky Mess Style Apr 22 '21 at 14:51
  • Another thought is to add some logic to the script to get the active user that is signed on when it executes e.g. `quser`. This would work if its on a machine that only one user can be logged onto at a time you can see which account is connected and active at the time of execution. – Vomit IT - Chunky Mess Style Apr 22 '21 at 15:02
  • @ITThugNinja they are going to run it as SYSTEM, so $env:Username is going to be NTSYSTEM itself. I don't think this is actually possible unless the delay was scripted and the scheduled task itself ran immediately. That way, calling the script could log to a file: USER x started y with a delay of z... – LPChip Apr 22 '21 at 15:02
  • The trigger is any user logon, and the delay is up to an hour. Thus, the user could log off (and another user logs on) within that span. In Win7 and early Win10, users could be given read/execute rights to all-user tasks so they can't change them but can run them (under their ticket), but Microsoft has blocked that now (Why??) If I can identify the user, I can have SYSTEM create a new task for just the current user to be run immediately. Yes, it's back-asswards, but Microsoft! – Teknowledgist Apr 22 '21 at 15:30
  • To solve this X-Y problem, why don't you tell us what the endgoal is that you are trying to solve? There must be another way to achieve what you want that will work. Why do you need a task with a random delay that runs as SYSTEM? – LPChip Apr 22 '21 at 15:35
  • Okay so the trigger is an event for a user action but the user does not execute it, the triggered event does. For that reason the `$Env:username` won't work. If you has a scheduled task that you execute with logic with a logged on user to execute the task that executes the script as `SYSTEM` then that's what I was talking about. I wasn't sure how a user was executing it I guess. You should keep track of user account login time and correlate that with some log that shows when the task ran as `SYSTEM` after the delay. The delay does seem troublesome in this case for what you're asking. – Vomit IT - Chunky Mess Style Apr 22 '21 at 15:44
  • I don't need a *random* delay, that is a product of the Task Scheduler. I just need a delay. I don't want the script to run at logon, but later. I also don't want the user to mess with the task, so whether it runs or not can't be under the user's control. It also needs to occur regardless of network connectivity, so a user-GPO isn't an option. – Teknowledgist Apr 22 '21 at 16:03
  • Look over an answer here I wrote about and use those options or at least the 10 second delay: https://superuser.com/questions/1640613/how-to-run-a-powershell-script-with-elevated-access-using-task-scheduler/1640675#1640675. Instead of having a random delay, use a standard one that makes sense after login but quick enough before a logoff of the account would typically occur in your environment. The random delay is something you can control. – Vomit IT - Chunky Mess Style Apr 22 '21 at 16:06
  • The setting on a task trigger in the GUI use "Delay task for up to (random delay)", and the xml node in an export is ``. How do you create a "standard one" and control it? `Edit:` I just found there is also a possible xml node of just ``. not sure if it's adjustable in the GUI. – Teknowledgist Apr 22 '21 at 16:45

1 Answers1

1

Scheduled Task that runs as SYSTEM but is triggered by a user action and is on a delay.

Since you are using a random delay and it seems to be troublesome per timing, you should just use an explicit delay per each trigger event. Each trigger has its own setting for the delay this way.

enter image description here

Try the attached XML export from a job I setup on a system on my side changed up a bit to obscure real script and process names.

You can import it and then look over all the setup and configuration to see what all settings were set, make adjustments, etc.

Task Scheduler Job - XML Export

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2019-12-10T13:30:30.3849335</Date>
    <Author>Administrator</Author>
    <URI>\Kill Daemon</URI>
  </RegistrationInfo>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-18</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
  </Settings>
  <Triggers>
    <LogonTrigger>
      <Delay>PT10S</Delay>
    </LogonTrigger>
    <SessionStateChangeTrigger>
      <Delay>PT10S</Delay>
      <StateChange>RemoteConnect</StateChange>
    </SessionStateChangeTrigger>
    <SessionStateChangeTrigger>
      <Delay>PT10S</Delay>
      <StateChange>ConsoleConnect</StateChange>
    </SessionStateChangeTrigger>
  </Triggers>
  <Actions Context="Author">
    <Exec>
      <Command>Powershell</Command>
      <Arguments>-ExecutionPolicy Bypass -File "C:\process\killit.ps1"</Arguments>
      <WorkingDirectory>C:\process</WorkingDirectory>
    </Exec>
  </Actions>
</Task>

I want the (PoSh) script that runs to be able to identify which user triggered the task

Because the trigger of the task is an event and not a user clicking on a script to execute a scheduled task, the PoSH script that executes cannot tell what user it was that logged on per the event that executes it.

This means doing simple logging and using $env:username will not give you the username that logged on causing the event.

How to identify which user triggered task?

You'd likely have to capture data from Event Viewer security logs at the time of execution to get the user account detail that logged on generating the event which triggers the Task Scheduler job, and incorporate that into the PoSH logic to save a log, etc.

You might be able to run the quser command and record the active session username and log it per PoSH logic that way too.

quser example output

C:\Users\ClownMan>quser
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>ClownMan              console             1  Active      none   4/14/2021 7:46 AM

Additional PowerShell

(quser)[1].Split("").Where({$_.Trim() -ne ""})[0] -join " " -replace ">";
(quser)[1].Split("").Where({$_.Trim() -ne ""})[3];
(quser)[1].Split("").Where({$_.Trim() -ne ""})[5..7] -join " ";

Example Output

Note: With these values you could get the name of the user account that is active and then calculate with PowerShell to ensure the date and time is greater than one hour and only if it is to run the script per the hour delay condition.

ClownMan
Active
4/14/2021 7:46 AM

Additional Resources

Vomit IT - Chunky Mess Style
  • 40,038
  • 27
  • 84
  • 117
  • @Teknowledgist Let me know if this helps you formulate something using one of the mentioned approaches is getting that detail is really of great importance. The way the task is scheduled per that xml export I added just works always and the 10 second delay ensures the user is fully logged onto the session before it executes. You can adjust it to 30 second or something more tuned with your system but not a random delay. There are a couple ideas at least for you to play around with that may help get you going in the right direction. – Vomit IT - Chunky Mess Style Apr 22 '21 at 18:43
  • Thanks, that is pretty much the process I was working through myself. I have to quibble a bit with one thing though. The trigger being the, well, trigger to the task is not the reason a PoSh script can't easily identify the user logon. The reason is entirely that Microsoft decided to (quietly) start preventing "all user" scheduled tasks. A single user task is also triggered by an event, no differently, yet it works fine. – Teknowledgist Apr 23 '21 at 14:26
  • Another solution is to not run the task as `SYSTEM` and run it as either `domain users` or `builtin\users` and check the 'Run only when the user is logged on' and then ensure the account(s) has execute access to the PS1 file on the local file system location. Also ensure the the account(s) has access to perform everything the PS1 script executes. I usually test the PowerShell script while logged on as a user from the location the Task Scheduler job will execute it from. Then I work on ironing out the Task Scheduler options but maybe this will help you some too. @Teknowledgist – Vomit IT - Chunky Mess Style Apr 23 '21 at 15:28
  • Also, look over my post here too regarding Task Scheduler as it might have something that you find helpful too for general troubleshooting and information.... https://superuser.com/questions/1214736/windows-10-scheduled-tasks-with-workstation-lock-unlock-not-being-triggered/1217125#1217125 .... FYI... Note, there are ways of running PowerShell silently/hidden and interactively via task scheduler if ensuring its execution is not visible to the end-user that is executing it if that is of importance to you. @Teknowledgist – Vomit IT - Chunky Mess Style Apr 23 '21 at 15:29
  • But that's my original problem! I **want** a task to run as `builtin\users`, but at some point, MS disabled that option. [See here](https://social.technet.microsoft.com/Forums/windows/en-US/6b9b7ac3-41cd-419e-ac25-c15c45766c8e/scheduled-task-that-any-user-can-run). Worse still, using the solution there won't work as a startup script because of [this](https://superuser.com/questions/1643354/startup-script-cant-read-registry). So, I'm stuck trying to identify the user as SYSTEM so I can create a task just for them to run. – Teknowledgist Apr 23 '21 at 19:31
  • I'm curious why you haven't tried user level group policy logon script with the PowerShell script pointed to the local file system that the user(s) has access, etc. as per --> https://i.imgur.com/PaMRFSe.png. Should be able to track correlated registry keys too to set via a registry setting if GP is not available on the local file system. I suspect you are not domain/AD environment? If you are AD there are other ways to run logon scripts too. I think there is another way or too with group policy too even locally. This way should work so have you tried it yet? @Teknowledgist – Vomit IT - Chunky Mess Style Apr 23 '21 at 19:43
  • I am in a domain environment. I don't want a login script because it just slows things down at an already burdened time. I want also to run a script on a significant delay (like an hour) or not at all if someone is logged in for just a few minutes, and I don't want users to be able to just kill a "sleeping" PowerShell. A scheduled task triggered by login but delayed is perfect, but frustratingly blocked for inexplicable reasons. – Teknowledgist Apr 23 '21 at 20:31
  • @Teknowledgist Yah, those are some tricky requirements. You might have to whip something up with more advanced PowerShell logic and incorporate that into some conditional using the output of logged in users and their login time and/or query and parse event viewer security logs. I've written logic to overcome tricky challenges in the past so I'm sure if possible but you might have to get more creative and complex with the logic and use a mixture of things to get the ultimate goal. Too back login scripts wouldn't work, then you satisfy all the requirements other than being killed before an hour. – Vomit IT - Chunky Mess Style Apr 23 '21 at 20:51
  • I added same PowerShell logic to help parse the output of `quser` to the answer but the two techniques with Event Viewer security logs or `quser` output comes down to just trivial stuff figuring out how to put it together to work for your needs. The detail you need for your condition is there even if it runs as `SYSTEM` via a scheduled task so it's possible. I'm sure there are other ways than those two example and other ways to run script than what I listed too. @Teknowledgist – Vomit IT - Chunky Mess Style Apr 23 '21 at 21:11
  • 1
    Thanks for all the feedback. It helps to just bounce ideas. BTW, here is the one-liner for capturing users from quser.exe: `$Folks = (quser) -replace '^[ >]','' -replace ' +',',' | convertfrom-csv` – Teknowledgist Apr 23 '21 at 21:25
  • That's a nice one-line, I never know how advanced PS people are that ask the PS questions. It's cool how well the Q&A platform can work for technical problems and solutions! – Vomit IT - Chunky Mess Style Apr 25 '21 at 16:59