To run a PowerShell script on multiple computers via Group Policy, you can work with an Immediate Scheduled Task. The main advantage over logon scripts is that you can execute your script with admin rights.

Josh Rickard

Josh's primary focus is in Windows security and PowerShell automation. He is a GIAC Certified Windows Security Administrator (GCWN) and GIAC Certified Forensic Analyst (GCFA). You can reach Josh at MSAdministrator.com or on Twitter at @MS_dministrator.

Other useful features are that the PowerShell script runs right after applying the Group Policy. In addition, the script only runs once because each time Group Policy refreshes, it will remove the task.

To work with Immediate Scheduled Tasks, you must join your endpoints to your Active Directory (AD) domain. You will also need Remote Server Administration Tools (RSAT) installed on your workstation (please do not do this on your Domain Controller).

After fulfilling these prerequisites, you will need to open up your Group Policy Management Console (GPMC). Navigate to the location in your AD forest that contains the systems to which you would like to apply this Immediate Scheduled Task. Then right-click and select "Create a GPO in this domain, and Link it here." When prompted, assign a descriptive name to this GPO:

Immediate Scheduled Task to run PowerShell script

Immediate Scheduled Task to run PowerShell script

Once you have created that GPO and linked it to your selected organizational unit (OU) or root domain, right-click it and select Edit.

Edit GPO to add settings

Edit GPO to add settings

This will bring up your Group Policy Object for which we will set this policy's conditions. With this policy open, we should navigate to the following location:

Computer Configuration -> Preferences -> Control Panel Settings -> Scheduled Tasks

On the right-hand side, you will have a blank area in the Scheduled Tasks pane. You should either right-click in the blank area or right-click on the Scheduled Tasks tree item on the left-hand side. Next, we will then select:

New -> Immediate Task (At least Windows 7)

Create Immediate Scheduled Task (At least Windows 7)

Create Immediate Scheduled Task (At least Windows 7)

Once you have selected the Immediate Task (At least Windows 7), a New Task pane prompts us to configure our task. These settings include a Name, Description, Account to run from, Run with highest privileges checkbox, and the Configure For: drop-down menu. First, we will need to give your new task a Name and Description (recommended).

Next, let's go to the bottom and select "Windows 7, Windows Server 2008R2" in the Configure For: drop-down list. This will make sure this task will work on Windows 7 and higher systems (Windows 7's Task Scheduler has significantly changed since Windows XP). Additionally, we will need to make sure that we select the Run with highest privileges checkbox.

Next, we will select the Change User or Group button. For this example, I am going to use the built-in NT Authority/System account on the local machine that will run this Immediate Task. You can, and the recommended approach is to use a separate account that has this right/authorization on your endpoint systems since the SYSTEM account has what I like to call "god" permissions. To select this account, simply type out SYSTEM in the "Enter the object name to select:" pane and click OK.

Configure an Immediate Task to run on workstations or systems

Configure an Immediate Task to run on workstations or systems

We will now move on to the Actions tab on the New Task (At least Windows 7) Properties pane. We will make sure that the following pane has these values:

  • Action = "Start a program"
  • Program/Script = C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
  • Add Arguments (optional) = -ExecutionPolicy Bypass -command "& C:\Path\To\Script.ps1"

We will keep the Start a program action and include the path to the Windows PowerShell executable in the Program/Script field. The Add Arguments (Optional) we will include a few things here that will make sure that our script runs. The first is the -ExecutionPolicy Bypass string. This will ensure your PowerShell execution policy doesn't prevent your script from running.

The second piece here is the -command "& C:\Path\To\Script.ps1" string. We are using the Command parameter to run our actual script. The "&" symbol inside the quotes ensures that our script runs and does not simply open or just load into memory. Your Add Arguments (Optional) field should look like the string above with all the hyphens and spaces.

Next, we will move to the Common tab and select the Apply once and do not reapply option since we want our Immediate Task to apply only once and not continually (unless you would like that).

Close out of all open windows in the GPMC. The next time your systems reboot, your Immediate Task will run. In my example, I am referencing a location on the individual endpoint systems, but you could also use a network share like \\networkshare01\scripts\scripts.ps1 in the -command “&” string.

If the desired script does not reside on the local system, we can add another setting to our Group Policy Object that can copy the intended script to our local machines. To do this, Edit our existing Immediate Task Group Policy Object and navigate to:

Computer Configuration -> Preferences -> Windows Settings -> Files

Right-click in the Files pane and select New -> File. We will first select Create in the Action drop-down menu. Then we will select our Source file (either on a network share or our local machine), and then for the Destination File, we will either type in or select the file path:

C:\Path\To\Script.ps1

Copy a file to the local machine for the Immediate Task to run

Copy a file to the local machine for the Immediate Task to run

If we look at one of our workstations, we can see that the system copies the file to the C:\Path\To\Script.ps1 location.

Script.ps1 on the endpoint system

Script.ps1 on the endpoint system

I have added the following code inside my C:\Path\To\Script.ps1 file so that I can see if it works as expected:

With this code, I should see the creation of a C:\Path\To\log.log file created with some simple text.

Log file created to identify that the Immediate Scheduled Task ran

Log file created to identify that the Immediate Scheduled Task ran

Additionally, if you are working with Windows 10, you can see that your Immediate Task ran by looking at the Event Viewer under Applications and Services Logs -> Windows PowerShell

On Windows 10 you can see if the script ran

On Windows 10 you can see if the script ran

With Immediate Scheduled Tasks you can run scripts on your endpoints quickly and resolve any configuration issues to help both yourself and your end users.

Win the monthly 4sysops member prize for IT pros

Share
4+

Users who have LIKED this post:

  • avatar

Related Posts

7 Comments
  1. DeployGuy 6 months ago

    Since the GPO runs under the local system account and that local account has no network rights to access off the local machine it seems you cannot send information back to yourself. But there is a way for that to happen and to omit the file copy of the script to the local machine.

    How? The key is to know that the local system account is by default a member of the Authorized User group which exist on every machine.

    So create a share with permissions with full control for Authorized User group, don't worry, we will control and restrict permissions using NTFS permissions.

    Create a folder structure, Example, these are all folder names.

    \\servername\Sharename\Get-FlashVersion

    Put your script in this folder and give modify rights only to your administrators so they can review and/or modify the script when needed. Regular uses must NOT have the ability to modify files in this folder.

    Now create another folder under Get-FlashVersion\Reports

    And now here is the magic, Give the  the Authenticated users group modify NTFS permissions to the reports folder.

    Now your script can use $PSSCRIPTROOT for relative addressing for your script to write a file back to the reports folder.

    \\servername\Sharename\Get-FlashVersion\$ENV:COMPUTERNAME.csv

    As group policy updates on each machine the task will run and gather what ever information your script gathers and write it to the share identified by the computer name.

    Then in the \\servername\Sharename\Get-FlashVersion folder you write a powershell script or simple batch file that concatenate the information of all the files in the report folder into a single file in the Get-FlashVersion folder. I add time information into the name of the report file created so that I can run the report again and not a have  file in use issue if I am still looking at the last report.

    Typically my report for each machine is information in a single line in comma delimited format.

    The concatenated file uses the .csv extension and the resultant file opens in excel automatically for sorting for analysis.

    The reason I gather only a single line of info is that you want the script to run quickly.

    I have run scripts like this for about 3 years. Usually I want to know what the version of a file is on all machines, or registry setting or pretty much anything you want to know.

    I only use query scripts, that is READ ONLY. I don't change or write values to the workstations as I consider that activity much better done by SCCM because of the success or failure reporting of that system.

    I use this as a near real-time check to compare the results of my SCCM queries to the powershell task scheduled query and get the greatest accuracy possible and to validate or NOT the results from the queries.

    Remember these are reports that arrive within about 2 hours from just about every system you target that is on line. (REAL LIVE MACHINES), that is as close to real-time reporting as you can get, if you absolutely, positively need to know a small bit information from all your machines right away, this is the best method that I have ever found and that Josh has so well documented.

    ALWAYS link your new GPO to an OU that is a test OU with test machines and make sure it works as you intended before linking to  larger amounts of machines.

    Consider this, within 5 minutes of enabling this GPO your machines will begin to report. On a network of 5000 or less workstations the load should not be felt and can be run continuously for days or weeks if needed. Although as short as possible is best. Remember always test, test,test and remember to TURN IT OFF when you have what you need.

    Remember this technique that Josh has shared is very powerful and with GREAT POWER comes GREAT RESPONSIBILITY.  Do it wrong and you may experience a CEV. (Career Ending Event)

    Use at your own and your networks risk.

    Excelsior,

    DeployGuy.

    5+

    Users who have LIKED this comment:

    • avatar
    • avatar
    • Author
      Josh Rickard 6 months ago

      DeployGuy, thank you for commenting!  Yes, you hit the nail on the head!  I have definitely seen this in the wild and it works great for gathering system inventory without SCCM or another inventory tool.  Thanks again for commenting, and sorry for the late reply (was on vacation for a bit. 🙂 )

      0

  2. Luc Fullenwarth 6 months ago

    I'm using this method since while also.

    On my side I prefer
    -File 'C:\Path\To\Script.ps1'
    to
    -Command "& C:\Path\To\Script.ps1"

    Usually, I also use -Noninteractive and -Noprofile parameters.

    Very good tutorial Josh!
    Thanks!

     

    1+

    Users who have LIKED this comment:

    • avatar
    • Author
      Josh Rickard 6 months ago

      Luc, thanks for commenting!  Yeah, I have used -File but -Command seems to work better in some (weird) situations.  Also, I actually choose NOT to use -Noninteractive and -Noprofile parameters.  This is because I actually use these to alert for malicious activity.  These parameters are typically (https://www.sans.org/summit-archives/file/summit-archive-1492186586.pdf) used by malicious actors, so when my workstation logs are forwarded to my SIEM then I can setup alerts for specific keywords. 🙂

      I wonder if this would be interested to anyone as blog post?

      Thanks!

      2+

      Users who have LIKED this comment:

      • avatar
  3. Boaz 5 months ago

    Hi Josh,

    Thanks for a very nice article.

    I encounter a problem with immediate tasks and Windows 10 (1703).

    Apparently the task is not deleting itself after expiration which causing the creation of the task in the next refresh fail.

    If I manually delete the task it will be created in the next GPO refresh.

    Did you encounter similar problem? If yes, do you have a solution?

    Thanks

    1+

Leave a reply

Your email address will not be published. Required fields are marked *

*

CONTACT US

Please ask IT administration questions in the forum. Any other messages are welcome.

Sending
© 4sysops 2006 - 2017

Log in with your credentials

or    

Forgot your details?

Create Account