4

As part of a system build automation script (that I'm using to create AWS AMIs), I want the system to reboot and then run additional post-boot setup tasks - but only once (so that when the system is imaged and then the image used to start a new instance, it will not run the post-boot setup tasks again).

The way I started to implement this is that the initial setup script (written in Powershell) uses Register-ScheduleJob -Trigger (New-JobTrigger -AtStartup) ... -Name PostBootSetup to setup another Powershell script run immediately after boot. In the post-boot script, I have:

Get-JobTrigger -Name PostBootSetup | ?{$_.Enabled} | Disable-JobTrigger

But when it is run I get this error (I'm logging all output of the post-boot script to a file):

Powershell : A scheduled job definition with Name PostBootSetup could not be found.

Which is weird because that is the output from the job that is currently running. I've also added just plain calls to Get-ScheduledJob and Get-JobTrigger -Name PostBootSetup that should output the relevant records, but there is absolutely no output from these - even though if I run these commands on a Powershell console after the machine started, I get the expected output.

Is it possible that a job can't access its own scheduled job record while running? If so, is there a workaround? or am I missing something? If this is not a good method to go about doing a one-time post-boot job, what would you suggest?

As a further note, I'm not very comfortable in batch, so I'd appreciate solutions that use Powershell or .Net or something that is more expressive than batch.

Guss
  • 2,670
  • 5
  • 34
  • 59
  • Did you ever find a solution for this problem? I am running into a similar issue where I need to run a powershell script on boot, just once but I can't seem to find a way to make it work – Petrik Feb 18 '16 at 08:59
  • 1
    Eventually I just used the standard `ScheduleJob` interface and once the `PostBootSetup` finishes successfully it creates a file in a known path. When it runs again, it checks that know path and if a file exists - it exits without doing anything. Not ideal, but that's how we've done it on UNIX a long time ago (before they invented advanced crons, and systemd timers) – Guss Jun 12 '17 at 12:45

1 Answers1

3

Use one of the RunOnce registry keys, they were designed for exactly this kind of task.
They run once, and then disappear.

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce

Make a new string value key where the name is whatever, and the data is the CLI EXE and switches to what you want run.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa376977%28v=vs.85%29.aspx

PS C:\> new-itemproperty -path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce -name "myInstall" -value '"c:\temp\borland\setup.exe" /this /that /other'
Clayton
  • 4,523
  • 17
  • 24
  • What credentials do these are run under? Am I correct to assume that the HKLM one is run after boot as LOCAL SYSTEM and that the HKCU on is run on first login using the discussing l specific user's credentials? – Guss Sep 22 '15 at 01:21
  • There are no credentials for the RunOnce key like there are for scheduled jobs. HKLM runs as system. HKCU would be the first user making an interactive login. – Clayton Sep 22 '15 at 13:21
  • 1
    I've read about it a bit more, and `RunOnce` doesn't run on boot at all - it runs on first log in. The point of the exercise is to run on boot and not wait for a user to log in, specifically because I want to automate the setup to complete without an active user session. I've looked at `RunServicesOnce`, but it doesn't look like it is working on 2012R2. – Guss Sep 22 '15 at 13:26
  • My bad, long time since I've used these... Thought HKLM RunOnce ran without logon, unlike HKCU RunOnce. And I cannot get RunServices to work on 2012 R2 either. Consistency... something MS continues to have less of. – Clayton Sep 22 '15 at 16:44