A simple, cron-like Windows service with an http interface. I use this tool to manage our deployment servers, gitlab runners (all VM's are running Windows), test automation VM's, etc. A client tool n1.exe
is also available to interface with this service.
Prior to this service, I have been using the task scheduler for running periodic tasks. Over time, it proved to be cumbersome to manage especially with lots of VM's involved.
This service runs command lines periodically as its main function. A run.conf
configuration file is provided. The lowest timer tick value support is 1 minute.
┌───────────── min (0 - 59)
│ ┌─────────── hour (0 - 23)
│ │ ┌───────── day of month (1 - 31)
│ │ │ ┌─────── month (1 - 12)
│ │ │ │ ┌───── day of week (0 - 6) (0 to 6 are Sunday to Saturday
│ │ │ │ │
* * * * * command to execute
Examples:
Run every minute:
* * * * * cmd.exe /arg1 /arg2 "arg with space" /sampledir "path\to\something"
Run every 5 minutes:
*/5 * * * * cmd.exe /arg1 /arg2 "arg with space" /sampledir "path\to\something"
Run every 2 hours:
* */2 * * * cmd.exe /arg1 /arg2 "arg with space" /sampledir "path\to\something"
Run every Aug 28 at 8:00am:
0 8 28 8 * file.exe -arg1 -arg2
Run every Saturday at 10 mins interval:
*/10 * * * 6 file.exe --arg1 --arg2
Check out run.conf
configuration for more information.
This is the main reason why I wrote this service; to rid of logging in to every VM and do stuff.
You can use n1.exe
to upload a new version of this service to itself.
n1.exe update --file [new-service-exe] --hosts [ip1, ip2, ip3, ...] self
With this command, n1.exe
will upload the file, service saves it, then call MoveFileEx
API with the MOVEFILE_DELAY_UNTIL_REBOOT
flag to ask Windows to overwrite the running binary with the newly uploaded one after system reboot. By default, the service will reboot the system after calling MoveFileEx
.
Another useful feature; updating all gitlab runner services. Currently, all our runners are installed in c:\runner
folder so this path is hardcoded.
n1.exe update --file [new-gitlab-runner-exe] --hosts [ip1, ip2, ip3, ...] runner
Same with updating the service itself, without the reboot.
n1.exe update --file [new-run-conf-file] --hosts [ip1, ip2, ip3, ...] conf
I use this to upload additional tools/executables to add to run.conf
but you can upload any file to any location using this command.
n1.exe upload --file [any-file] --path [location/path-to-copy-the-file] --host [ip]
n1.exe stat --files [comma-separated files/dirs] --host [ip]
I use this mainly to confirm whether the run.conf
update process is successful or not.
n1.exe read --file [file-to-read] --host [ip]
Quite a dangerous feature, though. Remember that this service runs under SYSTEM account in session 0.
n1.exe exec --cmd [cmd-to-execute] --host [ip]
The service will also capture the console output (if cmd is console-based) and sent it back to client.
Since cmd
will be executed from service session, it is not interactive by default. To run an interactive command, use n1.exe
's --interactive=true
option.
n1.exe exec --cmd [cmd-to-execute] --host [ip] --interactive=true --wait=true --waitms=5000
The service will run cmd
within the same session as winlogon.exe
(not session 0) via the CreateProcessAsUser
API. This is done through an external function StartSystemUserProcess
hosted in libcore.dll
.
I use this mainly to confirm whether the service update process is successful or not.
n1.exe version --host [ip]
Run the following commands as administrator:
holly.exe install
holly.exe start
Run the following commands as administrator:
holly.exe stop
holly.exe remove
disptrace.dll
is built using VS2015 so you need to install VC++ 2015 redistributable.
- Add
holly.exe
file to 'Allowed apps' in your Windows Firewall. You can also enable port 8080 as well.
Logging uses ETW. For more information, check out this project or this blog series.
- Install manifest file
admin_prompt> wevtutil.exe im jytrace.man /mf:"full_path_to_disptrace.dll" /rf:"full_path_to_disptrace.dll"
- Use
mftrace.exe
to view real-time logs from service from command line/Powershell. You can findmftrace.exe
from the Windows SDK/WDK installation folder (i.e.C:\Program Files (x86)\Windows Kits\10\bin\x86\
). Note thatmftrace.exe
needsmfdetours.dll
(from the same location) to run, in case you want to copy the two files to a separate location. For more information aboutmftrace.exe
, check out this link.
admin_prompt> mftrace.exe -c config.xml
If you're forking/contributing/modifying the service and you want more logs from the service, use the provided trace()
wrapper function.