How to Deploy Scheduled Tasks via Intune with PowerShell

scheduled tasks scripts

Occasionally there comes a time when you might need to push scheduled tasks to multiple machines. As the domain shrinks, and machines move to Azure AD Joined only, traditional means like Group policy become unavailable for common items such as deploying Scheduled Tasks. Fortunately, Intune has several mechanisms built in to accomplish some of these tasks, but there are still things that can’t be done easily using the built-in tools.

I do think it is worth spending some time and determining if what you need to do can be down with built in tools. For example, if you want a script to run on a schedule, I prefer to use Proactive Remediations for these rather than scheduled tasks. What if you want to deploy a script that runs at start up, and contains a while loop to check every minute for a specific event? Or restart a service if it stops? This is not a good use case for a Proactive Remediation. Additionally, it is definitely possible to download items from blob storage, and even create scripts on the fly. If you want to ensure these things happen whether or not someone is connected to the Internet, this can be a good option.

DISCLAIMER

Please understand that the content herein is for informational purposes only. This existence and contents shall not create an obligation, liability or suggest a consultancy relationship. In further, such shall be considered as is without any express or implied warranties including, but not limited to express and implied warranties of merchantability, fitness for a particular purpose and non-infringement. There is no commitment about the content within the services that the specific functions of the services or its reliability, applicability or ability to meet your needs, whether unique or standard. Please be sure to test this process fully before deploying in ANY production capacity, and ensure you understand that you are doing so at your own risk.

Table of Contents

Considerations Before Deploying
Script to Add the Scheduled Task
Deploy Script in Intune
Conclusion


Considerations Before Deploying

Before we go too far, there are a few things to consider. Scheduled tasks can be helpful for ensuring repetitive tasks are handled but can open your workstations up to security risks. These are a few things to consider before deploying any scheduled tasks.

Script Signing

In general, it good to sign your scripts before deploying. With the right execution policy, it can ensure that any scripts that are tampered with will not run. Script signing isn’t a pure security method, but it can help ensure that only the scripts you want can run. This is especially important when we talk about the next point.

If you are interested in script signing, it may be worth having a public key certificate available to download from blob storage. This would allow you to sign your newly created script. Or just consider this when you decide whether to create a new script or download one. If scripts are required to be signed to run, you’ll need to account for this in your final script.

Scheduled Task Principal Account

The scheduled task needs an account to run under. I highly recommend picking an account that will run with the least number of permissions possible. This is especially important if you are creating a scheduled task to run a PowerShell script. Running as “LOCAL SERVICE” or the currently logged on user (if they are a non-Administrator account) would provide the best permissions possible.

If you are going to have a scheduled task run as “LOCAL SYSTEM” or “Administrator” be sure to save the script in a protected folder and/or sign it with a certificate to reduce the chances it will run after being modified.


Script to Add the Scheduled Task

Here is an example script to use to deploy a scheduled task. I have this script broken into three parts:

  1. Create the Script for the Task
  2. Create the Scheduled Task
  3. Run the Scheduled Task

Keep in mind, this is a simple example to get you started. There are several ways you can break this up, so I’ll go through the different options with each part.

Set script values and create the script

In Part one of this script, I have a simple script that I want to deploy. In this script, I want it to check and make sure that specific files are copied to a location in AppData. The reason for this is because the files cannot be modified while in the Program Files folder, by non-Administrator users, but the application requires that they be editable when the application is opened.

For your scheduled task this script can be replaced by whatever script you want to have configured for your scheduled task. I’m saving this one to C:\Temp but consider a more permanent location for your final script.

#############################################################
# Set Script Values and create the script
#############################################################
$scriptPath = "C:\temp"
$scriptName = "ScheduleTaskTest.ps1"
$script = '
$origin = "C:\Program Files\Autodesk\AutoCAD 2018\Support"
$destination = "$env:APPDATA\Autodesk\C3D 2018\enu\Support"
$Filenames = @("OhDOT.mnl","ohdot.mnr","OhDOT.cuix")

foreach($f in $Filenames){ 
    if (!(Test-Path "$destination\$f")) { 
        if (Test-Path "$origin\$f") { 
            Copy-Item -Path "$origin\$f" -Destination "$destination\$f" -Confirm:$false 
        }else {
            Write-Host "Computer missing $f"
        }
    }else {
        Write-Host "Files Exist already"
    }
}
'

Set-Content -Path $scriptPath\$scriptName -Value $script

This section of the script creates our file in the location indicated. The way you format the content here is how it will appear in the file, so I recommend creating the file separately, and copying it in when you have proven that the script works.

Alternatively, you can download an existing script instead of creating one. This may make it easier to perform source control, and ensure it is signed, but means you will have to have it exposed to the internet via some means (like anonymous blob storage).

Set Values of Scheduled Task & Create it

In part two, we want to create the scheduled task. I started off by giving it a name. It should be something you can easily identify when looking at it in Task Scheduler. The next line is optional, but I like to be able to run a script and have it be self-contained. If I am deploying this script to replace a previous version, I want it to wipe out existing tasks first. Feel free to remove this line if it doesn’t fit your needs.

Finally, we set the parameters needed to register the scheduled task. Pay attention to the principal variable here. In this case, I am setting it to run as the currently logged in user, because it doesn’t need to have any special permissions. You could also set this to LOCAL SERVICE for minimal permissions and handle any routing it needs in the script itself.

For details on all the parameters of creating a scheduled task with PowerShell, check this link here.

#############################################################
#Set Values of Scheduled Task 
#############################################################

$TaskName = "Start Copy Process"
Get-ScheduledTask | Where-Object {$_.TaskName -eq "$TaskName"} | Unregister-ScheduledTask -confirm:$false
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-WindowStyle hidden -File $scriptPath\$scriptName"
$trigger = New-ScheduledTaskTrigger -AtLogon
$principal = (Get-CimInstance -ClassName Win32_ComputerSystem).Username
$settings = New-ScheduledTaskSettingsSet
Register-ScheduledTask -TaskName $TaskName -Trigger $trigger -User $principal -Action $action -Settings $settings

An alternative option to this would be to create your scheduled task on a separate workstation, then export that task. From there, you can add the XML information directly into your script, have it export that information to an XML file on the location machine, then import it into scheduled tasks using PowerShell instead.

The process above is a little cleaner, but an XML file may give greater flexibility in configuring settings. Do what works best for you.

Run the Scheduled Task

To be fair, this is totally optional. However, I like to get some immediate clarification on whether the task creation was successful. Running it after creating it is the easiest way I know.

#############################################################
# Run Scheduled Task
#############################################################
try {
    Start-ScheduledTask -TaskName $TaskName
}
catch {
    Write-Host $Error
    Exit 2000
}

The full version (and latest version) of this script is located here.


Deploy Script in Intune

Unlike a Proactive Remediation, this is a script we really only need to run once on a machine. This means that the easiest deployment will be from the scripts section under Windows Devices. Navigate to Endpoint.Microsoft.com and get signed in.

  1. Click on the Devices Section, then Windows Devices. Choose PowerShell scripts and click Add. Give your script a name, and description then choose next.
basics for our scheduled task script
  1. Next, click the box at Script Location, and find your script. For the other options, it is best to always run in 64-bit PowerShell, unless you are deploying to 32-bit clients. You do NOT want to run the script with the logged-on users’ credentials, unless that user is a local admin. You cannot create a scheduled task via PowerShell as a standard user. Finally, enforce script signing based on your needs. Then click next.
deployment settings for scheduled task script
  1. Finally, choose the group where this script and scheduled task will be deployed. Hit Next, and then on the final screen hit Add.
group for deploying the scheduled tasks script

Conclusion

There you have it! The basics for deploying a scheduled task via PowerShell in Intune. There are several ways you can do this, so this isn’t necessarily the only way to do this. The idea here is to have a method that is easy to understand and easy to replicate. I hope I was able to accomplish that here today.

Let me know what you think? What would you change? What kinds of tasks are you thinking of deploying to workstations in your environment? Let me know, I can’t wait to hear your ideas! Hit me up on Twitter @SeeSmittyIT to let me know what you thought of this post. Or if you are avoiding the bird site, I’m also posted up on Mastodon @[email protected]. Thanks for reading!

Smitty

Curtis Smith works in IT with a primary focus on Mobile Device Management, M365 Apps, and Azure AD. He has certifications from CompTIA and Microsoft, and writes as a hobby.

View all posts by Smitty →