1

On a 2008 R2 server, I have a Windows task that executes a PowerShell script. It works fine when set in Task Scheduler to execute as an Admin account, but I'd like to set it to execute as the Windows Local Service account instead as I'd read that it's considered a security best practice since Local Service has very limited privileges.

When using the Local Service account, the task itself appears to run the PowerShell script successfully according to the history log in the task scheduler. But the PowerShell script does not output a text file as it's designed to do, leading me to believe that perhaps the PowerShell.exe itself ran, but the script was blocked for some reason.

In the task scheduler, I have the task set to "Run with highest privileges" so thought that was all I needed to get it to run successfully...

How can I get this PowerShell task to run successfully? Or should I just create a Windows domain service account to run this task instead?

72909903
  • 39
  • 5
  • Where is the script writing the output? Are you trying to write to the network or something? You probably won't have any network access as that account, but lots of access to the local system. – Zoredache Mar 13 '19 at 21:10
  • The script is writing the output to the local C: drive... And to clarify, I'm trying to use "Local Service", not "Local System". Local System definitely works but I'd like to avoid that since it has admin privileges. – 72909903 Mar 13 '19 at 21:42
  • Well does the account you are running it as have write rights at the path you are trying to write to? Does the account have enough privileges to actually run the commandlets that you are trying to run? – Zoredache Mar 13 '19 at 21:58
  • Ah, thanks Zoredache... Indeed, the Local Service account is not listed as having permissions to the C: drive. System account is listed though and has full permissions of course. Looks like I'd have to grant the Local Service account read/write permissions to the C: drive. But we want to avoid that so we're now looking into just creating our own custom service account to run this task, granting it only the bare minimum permissions it needs to do its job as per best practices. Thanks again. – 72909903 Mar 13 '19 at 23:40
  • Also, learned that setting Windows task to "Run with highest privileges" has some caveats to it: https://social.technet.microsoft.com/Forums/windows/en-US/7167bb31-f375-4f77-b430-0339092e16b9/how-does-quotrun-with-the-highest-privilegesquot-really-work-in-task-scheduler-?forum=w7itprogeneral – 72909903 Mar 13 '19 at 23:51

1 Answers1

0

I prefer to use Register-ScheduledJob as it allows me to use PowerShell script blocks instead of script files. But you are free to use only Register-ScheduledTask that will be even easier.

In the script below I use Register-ScheduledJob to create a PowerShell job.
Then I use Set-ScheduledTask to change the startup account to LocalSystem or any another built-in account.

You can run the script multiple times. But run it under an administrative account.

See $accountId = "NT AUTHORITY\LOCAL SERVICE"; below.
Also pay attention to -RunElevated. I've commented out it for you and that works.

$ErrorActionPreference = 'Stop'


Clear-Host

$taskName = "it3xl_dummy_PowerShell_job"
# Unregister-ScheduledJob it3xl_dummy_PowerShell_job -Confirm:$false

$task = Get-ScheduledJob -Name $taskName  -ErrorAction SilentlyContinue
if ($task -ne $null)
{
    Unregister-ScheduledJob $task  -Confirm:$false
    Write-Host "Old $taskName job has been unregistered"; Write-Host;
}


$trigger = New-JobTrigger -AtStartup;

$options = New-ScheduledJobOption -StartIfOnBattery  #-RunElevated;

Write-Host "Registering new $taskName job";
Register-ScheduledJob -Name $taskName  -Trigger $trigger  -ScheduledJobOption $options `
    -ScriptBlock {
    Write-Host In our PowerShell job we say - oppa!;
}


#$accountId = "NT AUTHORITY\SYSTEM";
$accountId = "NT AUTHORITY\LOCAL SERVICE";
$principal = New-ScheduledTaskPrincipal -UserID $accountId `
    -LogonType ServiceAccount  -RunLevel Highest;

$psSobsSchedulerPath = "\Microsoft\Windows\PowerShell\ScheduledJobs";
$someResult = Set-ScheduledTask -TaskPath $psSobsSchedulerPath `
    -TaskName $taskName  -Principal $principal


Write-Host;
Write-Host "Let's show proofs that our PowerShell job will be running under the LocalSytem account"
$task = Get-ScheduledTask -TaskName $taskName
$task.Principal

Write-Host "Let's start $taskName"
Start-Job -DefinitionName $taskName | Format-Table

Write-Host "Let's proof that our PowerShell job was ran"
Start-Sleep -Seconds 3
Receive-Job -Name $taskName
it3xl
  • 101
  • 3