How to Run PowerShell Code Only During Certain Times

When you have a PowerShell command running inside a loop, you may not want it to execute continuously. For example, you might want a script to run only during business hours, between scheduled maintenance windows, or during a specific overnight period.

PowerShell makes this straightforward by comparing the current time with a start and end time.

Checking Whether the Current Time Is Within a Range

The current time can be retrieved with:

(Get-Date).TimeOfDay

This returns the current time as a TimeSpan, which can be compared with other TimeSpan values.

The following example runs code between 9:00 AM and 5:00 PM:

while ($true) {
    $currentTime = (Get-Date).TimeOfDay
    $startTime   = [TimeSpan]::Parse("09:00")
    $endTime     = [TimeSpan]::Parse("17:00")

    if ($currentTime -ge $startTime -and $currentTime -lt $endTime) {
        # Code to execute between 09:00 and 17:00
        Write-Host "Running scheduled code"
    }

    Start-Sleep -Seconds 30
}

In this example:

The code will execute during every loop iteration while the current time is within the specified range.

Including the End Time

The previous example excludes the end time. If the code should also run at exactly 5:00 PM, use -le instead:

if ($currentTime -ge $startTime -and $currentTime -le $endTime) {
    # Code to execute through 17:00
}

Handling Time Ranges That Cross Midnight

A simple comparison works when the start time comes before the end time on the same day. However, a range such as 10:00 PM to 2:00 AM crosses midnight and requires slightly different logic.

while ($true) {
    $currentTime = (Get-Date).TimeOfDay
    $startTime   = [TimeSpan]::Parse("22:00")
    $endTime     = [TimeSpan]::Parse("02:00")

    $withinRange =
        if ($startTime -le $endTime) {
            $currentTime -ge $startTime -and $currentTime -lt $endTime
        }
        else {
            $currentTime -ge $startTime -or $currentTime -lt $endTime
        }

    if ($withinRange) {
        # Code to execute between 22:00 and 02:00
        Write-Host "Running scheduled code"
    }

    Start-Sleep -Seconds 30
}

The important difference is the use of -or when the range crosses midnight. A time is within the range if it is:

This allows the script to correctly handle both sides of midnight.

Running the Code Only Once Per Time Window

If the loop runs every few seconds or minutes, the code inside the if statement will also run repeatedly. To execute it only once during the time window, use a Boolean flag:

$hasRun = $false

while ($true) {
    $currentTime = (Get-Date).TimeOfDay
    $startTime   = [TimeSpan]::Parse("09:00")
    $endTime     = [TimeSpan]::Parse("17:00")

    $withinRange =
        $currentTime -ge $startTime -and
        $currentTime -lt $endTime

    if ($withinRange -and -not $hasRun) {
        # Code to execute once
        Write-Host "Executing command"

        $hasRun = $true
    }
    elseif (-not $withinRange) {
        # Reset the flag for the next time window
        $hasRun = $false
    }

    Start-Sleep -Seconds 30
}

When the script first enters the time window, $hasRun is $false, so the code executes. The flag is then set to $true, preventing the code from running again during that same window.

Once the current time moves outside the window, the flag is reset. This allows the code to execute again during the next scheduled window.

Complete Example

Here is a reusable version that checks the time and runs a command every 30 seconds between 9:00 AM and 5:00 PM:

$startTime = [TimeSpan]::Parse("09:00")
$endTime   = [TimeSpan]::Parse("17:00")

while ($true) {
    $currentTime = (Get-Date).TimeOfDay

    if ($currentTime -ge $startTime -and $currentTime -lt $endTime) {
        # Replace this with the command you want to run
        Write-Host "The command is running at $(Get-Date)"
    }
    else {
        Write-Host "Outside the allowed time range"
    }

    Start-Sleep -Seconds 30
}

This pattern is useful for polling scripts, scheduled monitoring tasks, automated maintenance jobs, and any PowerShell process that should operate only during specific hours.