Skip to content

New-PSUSchedule -OneTime treats future local times as past #5602

@DataTraveler1

Description

@DataTraveler1

Description of Issue

Summary

On PSU 2026.1.2, New-PSUSchedule -OneTime accepts a future UTC DateTime but rejects an equivalent future Local DateTime as already in the past.

One time schedule is scheduled for the past. Scheduled for 3/20/2026 2:52:47 PM +00:00 but it is 3/20/2026 2:50:46 PM

This makes it look like one-time schedule validation is converting future local times incorrectly before comparing them to the current time.

Expected Behavior

If -OneTime is given a future local DateTime, PSU should accept it.

At minimum, a future Local DateTime should not be treated as a UTC wall-clock time and then rejected as already in the past.

Actual Behavior

  • Future UTC DateTime values are accepted and execute successfully.
  • Future Local DateTime values are rejected as already in the past.

The server-side exception path is logged through:

  • PowerShellUniversal.PublicClient.NewSchedule
  • PowerShellUniversal.Configuration.ScheduleService.CreateAsync
  • PowerShellUniversal.Automation.JobService.ScheduleJob

Minimal Repro

1. UTC succeeds

$script = Get-PSUScript -Name 'YourScript'
$time = (Get-Date).AddMinutes(2).ToUniversalTime()
New-PSUSchedule -Script $script -Name 'utc-probe' -OneTime $time -TimeZone 'UTC'

2. Local fails

$script = Get-PSUScript -Name 'YourScript'
$time = (Get-Date).AddMinutes(2)
New-PSUSchedule -Script $script -Name 'local-probe' -OneTime $time -TimeZone 'Eastern Standard Time'

Repro Results

  • UTC case created successfully and executed successfully.
  • Local case failed with Scheduled for ... +00:00.

UTC success path

  • Scheduling one time script 12 at 3/20/2026 6:52:47 PM with time zone UTC.
  • Job 102 then starts and completes successfully.

Local failure path

  • Scheduling one time script 12 at 3/20/2026 2:52:47 PM with time zone Eastern Standard Time.
  • Immediately followed by:
System.Exception: One time schedule is scheduled for the past. Scheduled for 3/20/2026 2:52:47 PM +00:00 but it is 3/20/2026 2:50:46 PM

Debug logging additionally confirms:

  • gRPC-Web request handling
  • JWT bearer authentication success
  • request-body read
  • route match to PublicClient/NewSchedule

The logs still do not show the exact incoming DateTime payload or the internal conversion step that produces the +00:00 comparison.

Relevant Documentation Context

PSU documentation for New-PSUSchedule states:

  • -OneTime <DateTime>: "The initial time zone is determined by the Kind property of the DateTime object. If the kind is Unknown, it will be assumed to be UTC."
  • -TimeZone <String>: "The TimeZone to execute the script in."

Based on that documentation, the observed Local-value failure does not look correct.

Impact

Users may need to convert one-time schedule inputs to UTC to avoid false past-time validation failures, even when the local time is clearly in the future.

That creates confusing behavior and makes documented timezone handling harder to trust.

Workaround

Use explicit UTC values for one-time schedules.

$time = (Get-Date).AddMinutes(5).ToUniversalTime()
New-PSUSchedule -Name 'TEST' -OneTime $time -TimeZone 'America/Chicago' -Script 'SCRIPT'

Suggested Investigation Area

Possible places to look:

  • one-time schedule normalization before validation
  • DateTime.Kind handling for Local values
  • interaction between -OneTime and -TimeZone
  • conversion logic inside PowerShellUniversal.Automation.JobService.ScheduleJob

Version

2026.1.2

Severity

Low

Hosting Method

MSI (Windows Service)

Operating System

Windows

Database

SQLite

Licensed

Yes

Features

Onetime Schedules

Additional Environment data

Standard PSU build using local authentication with MSI build on Windows Server 2019 Standard.

Screenshots/Animations

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    v5Version 5 issue.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions