Today was one of these days. Faced with a new problem I've never come across before. I was trying to configure a task to run once and only once on the server was provisioned for the first time. Something like a bootstrap script. In my quest to solve that problem, I came across a thing called Run and RunOnce registry keys!
What are Run(Once) registry keys?
Who knew that these things even existed, but here we are. So what do these keys really do? Let's grab the definition from the official documentation on [MSDN](https://msdn.microsoft.com/en-us/library/aa376977(v=vs.85).aspx" target="_blank)
Run and RunOnce registry keys cause programs to run each time that a user logs on. The data value for a key is a command line. Register programs to run by adding entries of the form
description-string=commandline
. You can write multiple entries under a key. If more than one program is registered under any particular key, the order in which those programs run is indeterminate.
The Windows registry contains these 4 keys:
- HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
- HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
- HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
- HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
Although they look very similar, there are subtle changes which we'll need to highlight.
HKCU keys will run the task when a specific user, while HKLM keys will run the task at first machine boot, regardless of the user logging in.
The Run registry keys will run the task every time there's a login. The RunOnce registry keys will run the taks once and then delete that key.
If you want to ensure that a RunOnce key is deleted only if its task is run successfully, you can prepend the key name value with an exclamation mark '!'.
In addition, if you want the RunOnce command to run even in Safe Mode, you can prepend the key name value with an asterisk '*'.
This is great at so many levels because you can execute some really powerful and complex tasks during the machine's startup. In my case, I had to apply some DNS settings using PowerShell.
Configuration
You can configure the keys manually by firing up regedit.exe
and navigating to the appropriate key.
Then you need to add a new string, give it a name and configure the appropriate task as it's value.
However, if you aren't not a GUI enthusiast and you prefer scripting it (I like PoSH for most things these days), you can run the following command to configure a new RunOnce task. Open a new PowerShell window and type the following:
Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name '!RegisterDNS' -Value "c:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe -noexit -command 'Register-DnsClient'"
And that's all there is to it. With a couple of lines of PowerShell or a few clicks in the GUI, we can quickly setup a task to run once or at every login for a specific user or every user. A handy little utility and, as we all know, it's the small things/wins that count, right?