Search code examples
windowspowershellscheduled-tasks

Unable to capture query user output via PowerShell script via Task scheduler as SYSTEM context


I am trying to execute the below PowerShell script as a scheduler job as SYSTEM context on Windows machine.

$AllSessions = C:\WINDOWS\system32\query.exe user 2>&1
$UserSessions = $AllSessions | Select-String -Pattern '^>(?!Testuser1)(\w+)'
$UserSessions | Out-File "D:\output.txt"

While I execute this script locally, I get the result as below in the output file,

>Domain_user              console             1  Active      none   10/3/2024 11:47 AM

While I execute this as part of scheduler task job, the output file does not capture anything.

Can someone please suggest why I am unable to capture the output and how can I achieve this?


Solution

  • tl;dr

    • It looks like you're looking for the currently interactively logged-on user(s) and associated session information, via the output from query.exe user (or, equivalently, quser.exe)

    • For the reasons explained in the next section, you can not find the relevant output line by looking for > as the first character when running from a scheduled task that runs whether or not a user is currently logged on (often, but not necessarily with the built-in
      NT AUTHORITY\SYSTEM user account).

    Instead, look for substring Active:

    C:\WINDOWS\system32\query.exe user |
      Select-String ' Active ' |
      Out-File "D:\output.txt"
    

    Important:

    • query.exe's output is localized, so the above assumes that the Windows display language is English; adjust accordingly for other languages.

    • When running under the NT AUTHORITY\SYSTEM account, you can see what display language is in effect for it by executing intl.cpl, activating tab Administrative, and clicking on Copy settings..., list section Welcome screen, assuming you are an administrator; you may also modify that language setting there, namely by copying your settings.

    Note:

    • Presumably, on a Windows server there can be multiple sessions Active simultaneously, via RDP, so the above may match multiple users / lines.

    • If you want to exclude a specific user such as Testuser1, the simplest approach is to append another Select-String call with -NotMatch:

       C:\WINDOWS\system32\query.exe user |
         Select-String ' Active ' |
         Select-String -NotMatch '^[> ]Testuser1' |
         Out-File "D:\output.txt"
      
      • Note that the regex, ^[> ]Testuser1, is formulated to work both with interactive invocation and invocation via the SYSTEM account.

    Background information:

    The > at the start of one of the lines output by query.exe user (or, equivalently, quser.exe) indicates the caller's session.

    When query user is run:

    • in the by design invisible, non-interactive services session, such as from a scheduled task that runs with the option Run whether user is logged on or not as shown in the Task Scheduler GUI (taskschd.msc), or when run via psexec with the -s option (which runs as NT AUTHORITY\System)

    • there is no line that starts with >, because the services session isn't listed by query user, which lists interactive user sessions only (a line for services does show in the output of query session / qwinsta.exe, however).