How can a (PowerShell) script determine it is running at startup?

2

I'm building a PoSh startup script that initializes a couple scheduled tasks. One task is triggered at user logon and another is triggered on idle. Both tasks run the script again. Only the first part of the script is needed at startup, but the entire script should run all other times.

How might a script determine when it is running at startup vs running at later times?

Teknowledgist

Posted 2017-06-28T20:23:25.833

Reputation: 157

Can't you pass a different parameter, or a different script, where the full script calls the start-up part before continuing with the remaining commands? – AFH – 2017-06-28T20:51:06.920

How often are you running the script throughout the day? – Cory Knutson – 2017-06-29T14:57:01.847

Hard to say. Idle checks every 15 minutes, but the task has a delay to run the script. The script runs shortly after logon too, so it depends on how many users. – Teknowledgist – 2017-06-29T20:42:27.167

On a Linux system I would touch a file (update the last edited date) at every run of the script. Then you can compare the uptime with the difference of the last edit time and the current time. This tells you if the last edit time was before last boot (script is run at boot) or after last boot (script is run at idle). I hope this helps you/someone to translate this idea to the Windows environment. – agtoever – 2017-07-01T06:08:46.170

Answers

3

I would recommend the parameter option as well. Make two scheduled tasks, one to run at startup, which calls the -AtStartup switch. Then you can make a second task to call the script without the switch. The switch type for parameters is built for this purpose.

Function Start-Task {
    [CmdletBinding()]
    Param(
       [Parameter(Mandatory=$True,Position=1)]
       [string]$paramOne,

       [Parameter(Mandatory=$True)]
       [string]$paramTwo,

       [switch]$AtStartup
    )

    if ($AtStartup) {
        #Do startup activities....
        Test-Connection -ComputerName Localhost
    }

    #Rest of script work
}

Cory Knutson

Posted 2017-06-28T20:23:25.833

Reputation: 287

A switch is a good idea. I would invert your suggestion of a second scheduled task however use the switch in the GPO. Every other time, it won't have the switch and will not it's not at startup. Thanks. – Teknowledgist – 2017-06-29T12:48:30.420

Technically though, the script doesn't know it is running at startup, it just knows it is being told it is running at startup. I'm still curious if there is a more definitive way to tease startup status out of Windows. Maybe check if the logon service has not been started since the last boot? – Teknowledgist – 2017-06-29T14:10:37.870

2

You could use

[System.Environment]::TickCount

to get the number of milliseconds elapsed since the system started.

Patrick Seymour

Posted 2017-06-28T20:23:25.833

Reputation: 7 662

I thought of something similar to that, but what value would be right every time? Too short and sometimes it might think it is not running at startup due to updates or other delays prior to the script. Too long (beyond 15 minutes) and sometimes it will run on idle and think it is at startup. – Teknowledgist – 2017-06-29T12:45:21.033

There probably is no correct answer for that. It would vary with things like the number of services and drivers loading at startup, whether your machine is set to run scripts asynchronously or synchronously, etc. I think you would need to do some test runs to get values for your environment. – Patrick Seymour – 2017-06-29T17:06:38.607