How do I create known tasks with the same triggers, properties, etc. Such as they all start when user logs on. The tasks have definite names such as Task_1, Task_2, Task_3 etc. I dont know how to use the foreach command in powershell.
Tasks can be surprisingly difficult to work with. When I first read your question it sounded like you wanted to copy a trigger from one task to several others. This is crude but you can do something like this:
$Trigger = (Get-ScheduledTask -TaskName "NameOfTheTemplatTask").Triggers[0]
Set-ScheduledTask -TaskName "NameOfDestinationTask" -Trigger $Trigger
Note: you'd have to update the task names.
Given you'r comments on Alex_P's Answer I understand better. You just need to create a trigger, store it in a variable then specify that variable as the argument to the -Triggers parameter on the New-ScheduledTask cmdlet.
$NewAction = New-ScheduledTaskAction -Execute 'C:\windows\system32\notepad.exe'
$NewTrigger = New-ScheduledTaskTrigger -AtLogOn
$NewSchedTAsk = New-ScheduledTask -Trigger $NewTrigger -Action $NewAction
Register-ScheduledTask -TaskName TestTask -TaskPath "\" -Action $NewAction -Trigger $NewTrigger
Obviously this is just an example, and you would need to update with information for your own environment and purposes.
Note: Don't forget Register-ScheduledTask
You could wrap this in a ForEach loop to get as many tasks as you wanted...
$NewAction = New-ScheduledTaskAction -Execute 'C:\windows\system32\notepad.exe'
$NewTrigger = New-ScheduledTaskTrigger -AtLogOn
$Tasks = #('Task_1', 'Task_2', 'Task_3')
ForEach($Task in $Tasks)
{
$NewSchedTAsk = New-ScheduledTask -Trigger $NewTrigger -Action $NewAction
Register-ScheduledTask -TaskName $Task -TaskPath "\" -Action $NewAction -Trigger $NewTrigger
}
Again these are just examples to give you a road map to solving these issues for your own environment.
You should also check out the MS Docs on the scheduledTask module that hosts the discussed cmdlets. You'll find similar examples, better vetted than what I cobbled together on the fly.
I would start with something like this:
$tasks = #('Task_1', 'Task_2', 'Task_3')
$tasks | ForEach-Object {
Start-ScheduledTask -TaskName $_
}
Here is the link for Start-ScheduledTask.
Tasks are just XML files, located in the locations below.
# File system:
Get-ChildItem -Path "$env:windir\Tasks"
# Registry:
Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tasks'
Get-ChildItem -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache\Tree'
You can copy them elsewhere, edit them and rename them to be used as your template,
or just export from the UI once, or vis cmd.exe or PowerShell, modify as needed and import back in.
The following example commands will export/import a scheduled task. However, make
sure to update the command...
"\TASK-PATH-TASKSCHEDULER\TASK-NAME," "%UserProfile%\EXPORT-FOLDER-PATH\TASK-EXPORT-NAME.xml
...with your device details.
schtasks /query /xml /tn "\TASK-PATH-TASKSCHEDULER\TASK-NAME" > "%UserProfile%\EXPORT-FOLDER-PATH\TASK-EXPORT-NAME.xml"
Or with PowerShell
Export-ScheduledTask -TaskName "TASK-NAME" -TaskPath "\TASK-PATH-TASKSCHEDULER\" |
out-file C:\PATH\TO\EXPORT-FOLDER\TASK-EXPORT-NAME.xml
Command to import a scheduled task and press Enter:
schtasks /create /xml "%UserProfile%\IMPORTED-FOLDER-PATH\TASK-INPORT-NAME.xml" /tn "\TASKSCHEDULER-FOLDER-PATH\TASK-INPORT-NAME" /ru "COMPUTER-NAME\USER-NAME"
Or with PowerShell
Register-ScheduledTask -xml (Get-Content 'C:\PATH\TO\IMPORTED-FOLDER-PATH\TASK-INPORT-NAME.xml' |
Out-String) -TaskName "TASK-IMPORT-NAME" -TaskPath "\TASK-PATH-TASKSCHEDULER\" -User COMPUTER-NAME\USER-NAME –Force
Related
I'm currently having issues using the New-ScheduledTaskAction -Execute String command.
The issue occurs when the passed String exceeds 260 characters. I tested this using the following code:
Code that works:
# create app object
$real_time_task_action = New-ScheduledTaskAction -Execute "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
$current_date = Get-Date
# create base trigger object
$real_time_base_trigger = New-ScheduledTaskTrigger `
-Once `
-At $current_date `
-RepetitionInterval (New-TimeSpan -Minutes 1)
# create tasks
$real_time_base_task = New-ScheduledTask -Action $real_time_task_action -Trigger $real_time_base_trigger
# register tasks
Register-ScheduledTask PerfAlgRealTimeBase -InputObject $real_time_base_task
Code that errors out:
# create app object
$real_time_task_action = New-ScheduledTaskAction -Execute "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
$current_date = Get-Date
# create base trigger object
$real_time_base_trigger = New-ScheduledTaskTrigger `
-Once `
-At $current_date `
-RepetitionInterval (New-TimeSpan -Minutes 1)
# create tasks
$real_time_base_task = New-ScheduledTask -Action $real_time_task_action -Trigger $real_time_base_trigger
# register tasks
Register-ScheduledTask PerfAlgRealTimeBase -InputObject $real_time_base_task
This is the actual error (which I feel is somewhat generic):
Register-ScheduledTask : The task XML contains a value which is incorrectly formatted or out of range.
My question then is: is there a way to go around this character limitation? Ultimately I would like to execute Task actions with Strings with more than 260 characters.
Currently, paths are limited to 260 characters in Windows per default. To work around this, you can either:
Prefix every path with \\?\, e. g. \\?\D:\very long path, to make it an extended-length path (source). Or
Enable long paths in Windows 10 (since v1607) by changing the registry (source):
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value 1
A reboot is required to make this change effective for all processes.
Good Afternoon:
I have written a PS Script that can create a task on my local machine; however, it is my intention to have this configure a task on multiple machines from a list. I cannot seem to find a way on how to do this. I did see something on using New-CimSession, but I dont think that is what I am looking for...
Here is my script:
foreach ($confighost in (Get-Content -Path "C:\Users\*User*\Documents\Test.txt"))
{
#Check for existent script in Task Scheduler
$taskpath = "\\$confighost\c$\Windows\System32\Tasks\LocalUserCleanUp"
$testtask = Test-Path -path $taskpath
If ($testtask -eq $true)
{
#If Task is already present, Do Not Run
Write-Host "CleanUp Task Listed in Task Scheduler On" $confighost ". Will not Implement Task..."
}
else
{
#If Task Does Not Exist Create Task
New-CimSession -ComputerName $confighost
Write-Host "No CleanUp Task Listed in Task Scheduler, Creating Task..."
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument "C:\Users\*Users*\Documents\ProfileCleanup.ps1"
$trigger = New-ScheduledTaskTrigger -Daily -At 2am
$settings = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -Action $action -Trigger $trigger -Principal $settings -TaskName "LocalUserCleanUp" -Description "Checks user accounts nightly to see if they are older than 30 days"
}
}
I look forward to your insight. Thanks again for all your assistance!
You can use Invoke-Command to execute your task creation code on a target server:
$cred = Get-Credential # There are a number of methods to automate reading the credential from a file
Invoke-Command -Credential $cred -ComputerName server01, server02, server0X {
# Your task creation code here
}
If you have any variables defined in your local session that you need available in the remote code, you can reference them in your Invoke-Command ScriptBlock reference the variable from the using scope by prefixing the local variable with $using:.
I am trying to figure out how to write a PowerShell script to find and run a scheduled task, or if it is not there then to create it. Here is what I have built so far. The else statement works but the first task does not.
$taskName = "crebackup"
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName}
if($taskExists) {
Start-ScheduledTask -TaskName "crebackup"}
else {
$action = New-ScheduledTaskAction -Execute “C:\POSNation\SQLBackup\sqlbackup.exe”
$Trigger = New-ScheduledTaskTrigger -Daily -At 3am
$Settings = New-ScheduledTaskSettingsSet
$Task = New-ScheduledTask -Action $Action -Trigger $Trigger -Settings $Settings
Register-ScheduledTask -TaskName 'crebackup' -InputObject $Task -User 'usernamehere' -Password 'passwordhere'}
In this case the sqlbackup.exe task needed the working directory to start in. This is displayed as "Start in (optional)" when you look at the task using Task Scheduler. To add that, use this for the $action variable:
$action = New-ScheduledTaskAction -WorkingDirectory "C:\POSNation\SQLBackup" -Execute "C:\POSNation\SQLBackup\sqlbackup.exe"
Also, make sure scripts don't have any smart quotes in them(“, ”). Smart quotes are often automatically generated by word processors and some websites. I replaced the smart quotes in the example above.
I need to write a script, which will create task scheduler job, which at pc startup will run executable. In short, script will be something like this:
$trigger = New-JobTrigger -AtStartup -RandomDelay 00:00:10
Register-ScheduledJob -Trigger $trigger -Name FileJob -ScriptBlock {$args[0]}
But it doesn't work. What's wrong?
I use the following Powershell snippet to create Windows Scheduled Tasks.
$action = New-ScheduledTaskAction -Execute 'application.exe' -Argument '-NoProfile -WindowStyle Hidden'
$trigger = New-ScheduledTaskTrigger -AtStartup -RandomDelay 00:00:10
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "FileJob" -Description "FileJob"
This is what I use to create my task:
#The first command uses the New-ScheduledTaskAction cmdlet to assign the action variable $A to the executable file tskmgr.exe
$A = New-ScheduledTaskAction -Execute "C:\WINDOWS\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" -file "C:\directory\powershell.ps1"
#The second command uses the New-ScheduledTaskTrigger cmdlet to assign the trigger variable $T to the value AtLogon
$T = New-ScheduledTaskTrigger -weekly -DaysOfWeek Saturday -At 7am
#The third command uses the New-ScheduledTaskSettingsSet cmdlet to assign the settings variable $S to a task settings object
$S = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -DontStopOnIdleEnd -ExecutionTimeLimit 1:00:00 -MultipleInstances 2
#The fourth command assigns the principal variable to the New-ScheduledTaskPrincipal of the scheduled task, Domain\Username
$P = New-ScheduledTaskPrincipal -UserId domain\gMSAaccount$ -LogonType Password -RunLevel Highest
#The fifth command sets the description varible to $D for the task definition
$D = "Insert your description here"
#Registers the new scheduled task and defines it by using the $D variable
Register-ScheduledTask Name_of_Task -Action $A -Trigger $T -Settings $S -Principal $P -Description $D<p>
I found that using gMSA accounts are the best in an active directory environment. Implement gMSA The requirement is that in order to use gMSA, you must create your task with a powershell script or schtask.exe.
I have a script that can legitimately run much longer than 3 days (it's a command queuing script, so it has a lot of pauses in it waiting for a job to complete). I'm using the PowerShell Register-ScheduledJob cmdlet to create the job.
Everything works great except, by default, the Windows Task Scheduler will stop the script if it hasn't completed after 3 days. I can work around this by going in the GUI and unchecking the 'Stop the task if it runs longer than: 3 days' check box. I need to be able to 'uncheck' that box via Powershell code. Here's how I'm scheduling it currently:
$immediate = (get-date).AddMinutes(2).ToString("MM/dd/yyyy HH:mm")
$scheduled_date = get-date -Format "yyyyMMMd-HHMMss"
$trigger = New-JobTrigger -Once -At $immediate
$sjo = New-ScheduledJobOption -RunElevated
Register-ScheduledJob -Name "SVC Migrations - $scheduled_date" -ScriptBlock {powershell.exe -File C:\scripts\addvdiskcopy_queue.ps1 } -Trigger $trigger -ScheduledJobOption $sjo >> C:\scripts\temp\job_scheduled.txt
Again, everything works great with this until 72 hours hits. Any help is appreciated!
Thanks!
New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0
This returns an object that can be passed to Register-ScheduledJob's -Settings argument. For example:
Register-ScheduledJob `
-Settings $(New-ScheduledTaskSettingsSet -ExecutionTimeLimit 0) `
# ...further arguments...
Just figured this out on Server 2012R2 without having to use the external DLL.
Works with Register-ScheduledTask but haven't tested with Register-ScheduledJob.
I created the with Register-ScheduledTask in a way similar to the above but without the ExecutionTimeLimit setting defined. This gave me the default of 3 days.
Then I returned the task and changed the settings as below:
$Task = Get-ScheduledTask -TaskName "MyTask"
$Task.Settings.ExecutionTimeLimit = "PT0H"
Set-ScheduledTask $Task
Check out this thread on CodePlex.
It looks like you can use the Task Scheduler Managed Library to achieve this. You'll need to download the library and load the DLL. Here is a fully working sample (just update the path to the DLL).
$TaskName = 'asdf';
# Unregister the Scheduled Job if it exists
Get-ScheduledJob asdf -ErrorAction SilentlyContinue | Unregister-ScheduledJob;
# Create the Scheduled Job
$Trigger = New-JobTrigger -At '5:00 PM' -Once;
$Option = New-ScheduledJobOption;
$Action = { Write-Host 'hi'; };
$Job = Register-ScheduledJob -Name asdf -ScriptBlock $Action -Trigger $Trigger -ScheduledJobOption $Option;
# Modify the Scheduled Job using external library
Add-Type -Path "C:\Users\Trevor\Downloads\TaskScheduler\Microsoft.Win32.TaskScheduler.dll";
$TaskService = New-Object -TypeName Microsoft.Win32.TaskScheduler.TaskService;
$Task = $TaskService.FindTask($TaskName, $true);
$Task.Definition.Settings.ExecutionTimeLimit = [System.TimeSpan]::Zero;
$Task.RegisterChanges();
I tested the library in my environment, and it works as expected. The net result is that the "Stop the task if it runs longer than" checkbox is disabled.
Use the following settings in task definition:
New-ScheduledTaskSettingsSet -ExecutionTimeLimit "PT0S"
Older post, but none of these options worked for me other than what #jdc0589 said in a comment. I run this script on an Azure VM running Windows Server 2016 Datacenter.
$action = New-ScheduledTaskAction -Execute "java.exe" `
-Argument "-jar `"D:\Selenium\selenium-grid-extras.jar`"" `
-WorkingDirectory "D:\Selenium"
$trigger = New-ScheduledTaskTrigger -AtStartup
$everyMinute = New-TimeSpan -Minutes 1
$nolimit = New-TimeSpan -Minutes 0
$settings = New-ScheduledTaskSettingsSet `
-MultipleInstances IgnoreNew `
-RestartInterval $everyMinute `
-RestartCount 999 `
-Priority 0 `
-ExecutionTimeLimit $nolimit `
-StartWhenAvailable `
-DisallowHardTerminate
Register-ScheduledTask `
-Action $action `
-Trigger $trigger `
-Settings $settings `
-TaskName "Start SGE Hub" `
-TaskPath "\Selenium Grid Extras" `
-Description "At machine startup, run SGE so that the hub can process tests without a logon" `
-RunLevel Highest `
-User "SYSTEM" `
-Force