2026-01-27 15:44:52 +01:00
from time import time
import subprocess
from _socket import socket
import argparse
import time
import socket
import subprocess
TARGET_LINK = " f0:2f:74:30:0c:d0 "
TARGET_HOSTNAME = " tower.home.the.malice.zone "
TARGET_IP = socket . gethostbyname ( TARGET_HOSTNAME )
def remote_cmd ( command ) :
2026-01-29 14:08:41 +01:00
print ( f " Executing: ssh alisceon@tower.home.the.malice.zone ' { command } ' " )
2026-01-30 18:56:08 +01:00
response = subprocess . run ( f " ssh tower -o ' StrictHostKeyChecking no ' ' { command } ' " , shell = True , capture_output = True , text = True )
2026-01-27 15:44:52 +01:00
return ( response . returncode , response . stdout , response . stderr )
def weboot ( ) :
2026-01-27 16:00:34 +01:00
print ( " Rebooting to windows " )
2026-01-27 15:44:52 +01:00
code , stdout , stderr = remote_cmd ( " sudo efibootmgr -n 0000 " )
if code == 0 :
code , stdout , stderr = remote_cmd ( " sudo reboot " )
2026-01-29 14:08:41 +01:00
time . sleep ( 120 )
2026-01-27 15:44:52 +01:00
if code != 0 :
raise RuntimeError ( f " weboot failed { stderr } " )
return code , stdout , stderr
def send_wol ( ) :
2026-01-27 16:00:34 +01:00
print ( f " Broadcasting WOL packet to { TARGET_LINK } " )
2026-01-27 15:44:52 +01:00
response = subprocess . run ( f " wakeonlan { TARGET_LINK } " , shell = True , capture_output = True , text = True )
return ( response . returncode , response . stdout , response . stderr )
def get_os ( ) :
2026-01-27 16:00:34 +01:00
print ( " Determining target OS " )
2026-01-27 15:44:52 +01:00
code , stdout , stderr = remote_cmd ( " whoami " )
if code == 255 and " No route to host " in stderr :
2026-01-27 16:00:34 +01:00
print ( " Target is offline " )
2026-01-27 15:44:52 +01:00
return " offline "
elif code != 0 :
raise RuntimeError ( f " win_or_linux failed { stderr } " )
2026-01-29 14:08:41 +01:00
if " tower \\ alisceon " in stdout . lower ( ) :
2026-01-27 16:00:34 +01:00
print ( " Target is running Windows " )
2026-01-27 15:44:52 +01:00
return " windows "
else :
2026-01-27 16:00:34 +01:00
print ( " Target is running Linux " )
2026-01-27 15:44:52 +01:00
return " linux "
def swap_os ( ) :
match get_os ( ) :
case " windows " :
code , stdout , stderr = remote_cmd ( " shutdown /r " )
case " linux " :
code , stdout , stderr = weboot ( )
case " offline " :
return False
return True
def boot_linux ( ) :
2026-01-27 16:00:34 +01:00
print ( " Booting Linux " )
2026-01-27 15:44:52 +01:00
match get_os ( ) :
case " windows " :
2026-01-27 16:00:34 +01:00
print ( " Tower is busy " )
2026-01-27 15:44:52 +01:00
return False
case " linux " :
2026-01-27 16:00:34 +01:00
print ( " Linux is already running " )
2026-01-27 15:44:52 +01:00
return True
case " offline " :
2026-01-27 16:00:34 +01:00
print ( " Booting via WOL " )
2026-01-27 15:44:52 +01:00
send_wol ( )
time . sleep ( 60 )
return True
def boot_windows ( ) :
2026-01-27 16:00:34 +01:00
print ( " Booting Windows " )
2026-01-27 15:44:52 +01:00
match get_os ( ) :
case " windows " :
2026-01-27 16:00:34 +01:00
print ( " Windows is already running " )
2026-01-27 15:44:52 +01:00
return True
case " linux " :
2026-01-27 16:00:34 +01:00
print ( " Tower is busy " )
2026-01-27 15:44:52 +01:00
return False
case " offline " :
2026-01-27 16:00:34 +01:00
print ( " Booting via WOL " )
2026-01-27 15:44:52 +01:00
boot_linux ( )
weboot ( )
if get_os ( ) == " windows " :
return True
else :
return False
def reboot ( ) :
2026-01-27 16:00:34 +01:00
print ( " Rebooting target " )
2026-01-27 15:44:52 +01:00
orig_os = get_os ( )
match orig_os :
case " windows " :
code , stdout , stderr = remote_cmd ( " shutdown /r " )
time . sleep ( 60 )
weboot ( )
return True
case " linux " :
code , stdout , stderr = remote_cmd ( " sudo reboot " )
return True
case " offline " :
2026-01-27 16:00:34 +01:00
print ( " Target is offline, cannot reboot " )
2026-01-27 15:44:52 +01:00
return False
def shutdown ( ) :
2026-01-27 16:00:34 +01:00
print ( " Shutting down target " )
2026-01-27 15:44:52 +01:00
match get_os ( ) :
case " windows " :
2026-01-29 14:08:41 +01:00
code , stdout , stderr = remote_cmd ( " shutdown /s /t 0 " )
2026-01-27 16:00:34 +01:00
time . sleep ( 30 )
2026-01-27 15:44:52 +01:00
case " linux " :
code , stdout , stderr = remote_cmd ( " sudo shutdown -h now " )
2026-01-27 16:00:34 +01:00
time . sleep ( 30 )
2026-01-27 15:44:52 +01:00
case " offline " :
2026-01-27 16:00:34 +01:00
print ( " Target is already offline " )
2026-01-27 15:44:52 +01:00
return False
2026-01-29 14:08:41 +01:00
if get_os ( ) == " offline " :
print ( " Target is now offline " )
return True
else :
print ( " Failed to shut down target " )
return False
2026-01-27 15:44:52 +01:00
2026-01-30 18:56:08 +01:00
def winupdate ( ) :
print ( " Starting Windows Update process " )
if get_os ( ) != " windows " :
print ( " Target is not running Windows, cannot update " )
return False
code , stdout , stderr = remote_cmd ( ' powershell -Command " Start-Service wuauserv " ' )
if code != 0 :
raise RuntimeError ( f " Failed to start Windows Update service: { stderr } " )
time . sleep ( 30 )
code , stdout , stderr = remote_cmd ( ' powershell -Command " UsoClient StartScan " ' )
if code != 0 :
raise RuntimeError ( f " Failed to start Windows Update scan: { stderr } " )
time . sleep ( 300 )
code , stdout , stderr = remote_cmd ( ' powershell -Command " UsoClient StartDownload " ' )
if code != 0 :
raise RuntimeError ( f " Failed to start Windows Update download: { stderr } " )
time . sleep ( 600 )
code , stdout , stderr = remote_cmd ( ' powershell -Command " UsoClient StartInstall " ' )
if code != 0 :
raise RuntimeError ( f " Failed to start Windows Update installation: { stderr } " )
time . sleep ( 1800 )
return True
2026-01-27 15:44:52 +01:00
def action_do ( action ) :
match action :
2026-01-27 16:00:34 +01:00
case " get_os " :
os = get_os ( )
print ( f " Current OS: { os } " )
2026-01-27 15:44:52 +01:00
case " boot_linux " :
if boot_linux ( ) :
print ( " Linux is now running " )
else :
print ( " Failed to boot Linux " )
case " boot_windows " :
if boot_windows ( ) :
print ( " Windows is now running " )
else :
print ( " Failed to boot Windows " )
case " swap_os " :
if swap_os ( ) :
print ( " OS swapped successfully " )
else :
print ( " Failed to swap OS " )
case " reboot " :
if reboot ( ) :
print ( " Reboot command sent successfully " )
else :
print ( " Failed to reboot " )
case " shutdown " :
if shutdown ( ) :
print ( " Shutdown command sent successfully " )
else :
print ( " Failed to shutdown " )
case " winupdate " :
2026-01-30 18:56:08 +01:00
if winupdate ( ) :
print ( " Windows update commands sent successfully " )
case " autowin " :
2026-01-27 15:44:52 +01:00
if get_os ( ) != " offline " :
print ( " Target is in use, belaying update 1h " )
time . sleep ( 3600 )
action_do ( " winupdate " )
2026-01-27 16:00:34 +01:00
if boot_windows ( ) :
print ( " Initiating Windows update " )
else :
print ( " Failed to boot Windows for update " )
return
2026-01-30 18:56:08 +01:00
winupdate ( )
2026-01-27 15:44:52 +01:00
if code == 0 :
print ( " Windows update initiated successfully " )
else :
print ( f " Failed to initiate Windows update: { stderr } " )
#first reboot to windows
time . sleep ( 300 )
weboot ( )
#second reboot after update
time . sleep ( 600 )
reboot ( )
#shutdown
time . sleep ( 300 )
shutdown ( )
2026-01-27 16:00:34 +01:00
def main ( ) :
2026-01-27 15:44:52 +01:00
parser = argparse . ArgumentParser ( description = " WOL and reboot utility " )
2026-01-30 18:56:08 +01:00
parser . add_argument ( " action " , choices = [ " get_os " , " boot_linux " , " boot_windows " , " swap_os " , " reboot " , " shutdown " , " winupdate " , " autowin " ] , help = " Action to perform " )
2026-01-27 15:44:52 +01:00
action_do ( parser . parse_args ( ) . action )
2026-01-27 16:00:34 +01:00
if __name__ == " __main__ " :
main ( )