Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register-ScheduledJob as the system account (without having to pass in credentials)

I believe for Register-ScheduledTask you can specify -User "System"or do something like:

$principal = New-ScheduledTaskPrincipal -UserId SYSTEM -LogonType ServiceAccount -RunLevel Highest

How do I do this with Register-ScheduledJob?

This command will be running the context of the local admin so it will have access to do this. I just don't see this option in the cmdlet.

Here is an example of how to do this with the scheduled tasks cmdlet

edit: Does windows make this impossible by design? If I open an interactive PS session as the system (using psexec) and try to create a schedualed job I get an error:

PS C:\Windows\system32> Register-ScheduledJob -Name systemsssss -ScriptBlock {'s
dfsdfsdfsd'}
Register-ScheduledJob : An error occurred while registering scheduled job
definition systemsssss to the Windows Task Scheduler.  The Task Scheduler
error is: (32,4):UserId:.
At line:1 char:1
+ Register-ScheduledJob -Name systemsssss -ScriptBlock {'sdfsdfsdfsd'}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (Microsoft.Power...edJobDefini
   tion:ScheduledJobDefinition) [Register-ScheduledJob], ScheduledJobExceptio
  n
    + FullyQualifiedErrorId : CantRegisterScheduledJobDefinition,Microsoft.Pow
   erShell.ScheduledJob.RegisterScheduledJobCommand

This same command works fine when run as the local administrator account

like image 748
red888 Avatar asked Nov 12 '16 23:11

red888


2 Answers

First use Register-ScheduledJob to create your PowerShell job.

Then use Set-ScheduledTask to change a startup account to the Local System or any other built-in accounts, i.e. SYSTEM, LOCAL SERVICE, NETWORK SERVICE, etc.

Use the following PS-script. Or download it from my GitHub Gist
The code is self-explanatory (I believe).
You can run it multiple times under an administrative account if you want to check how it works.

BTW, I prefer to use jobs (Register-ScheduledJob) over tasks because jobs allow me to embed PowerShell script blocks (strings) instead using of external script files. Look at -ScriptBlock below.

Also pay attention to -RunElevated. It is a must be.

$ErrorActionPreference = 'Stop'
Clear-Host

#### Start of Main Logic ###########################

$taskName = "my_PowerShell_job"

$accountId = "NT AUTHORITY\SYSTEM";
#$accountId = "NT AUTHORITY\LOCAL SERVICE";

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

# Uncomment the following exit command to only delete your job.
# exit;

# Shchedule your job. Using of -AtStartup as an example.
$trigger = New-JobTrigger -AtStartup;

$options = New-ScheduledJobOption -StartIfOnBattery  -RunElevated;

Write-Host " @ Registering of ""$taskName"" job";
Register-ScheduledJob -Name $taskName  -Trigger $trigger  -ScheduledJobOption $options `
    -ScriptBlock {
        # Put your code here.
        Write-Host Your job has been launched!;
    }


$principal = New-ScheduledTaskPrincipal -UserID $accountId `
    -LogonType ServiceAccount  -RunLevel Highest;

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

#### End of Main Logic ###########################

Write-Host;
Write-Host " @ Let's look at running account of ""$taskName"" PowerShell job"
$task = Get-ScheduledTask -TaskName $taskName
$task.Principal

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

Write-Host " @ Let's proof that ""$taskName"" PowerShell job has been launched"; Write-Host;
Start-Sleep -Seconds 3
Receive-Job -Name $taskName
Write-Host;
like image 126
it3xl Avatar answered Nov 18 '22 12:11

it3xl


Sadly you can't run schedule a job or task as the system account.

But you can create local administrator accounts as the system account.

And you can schedule jobs or tasks as a local administrator account.

So what I did to get around this problem is this:

$password = ConvertTo-SecureString (New-Guid).Guid -AsPlainText -Force
$user = New-LocalUser "service.scheduler" -Password $Password -Description "For scheduling in tasks from system account"
$credentials = New-Object System.Management.Automation.PSCredential($user.name, $password)
Register-ScheduledJob -Trigger $trigger -ScriptBlock $scriptblock -Name $taskName -ScheduledJobOption $options -credential $credentials

This does mean you are passing in credentials, but you don't have to store them as plain text or specify them.

like image 2
Dicky Moore Avatar answered Nov 18 '22 10:11

Dicky Moore