How to use PowerShell to restart router?
My computer is connected to the router using a network cable, the router acts as a modem, it connects to the ISP through PPPoE, my computer is behind NAT.
The model of my router: Huawei HS8545M, LAN address: 192.168.1.1, webpage administrator login: CMCCAdmin, webpage administrator password: aDm8H%MdA.
I have to do the following to restart the router (7 clicks in total, the browser remembers the login and password):
Way too many steps.
I have tried to use this method:
$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Navigate "https://192.168.1.1"
But after a short while the connection is lost, .Document
is empty, trying to refresh results in this error:
OperationStopped: The RPC server is unavailable. (0x800706BA)
I am using Windows 10 20H2 and I have disabled Remote Desktop, Remote Assistance, Remote Registry, Windows Remote Management and many other things, I disabled remote stuff because they pose threats to security, I think they are relevant to this; By the way, RPC
service is running.
Can anyone help me?
Source code of first page: page1.html
Source code of second page: page2.html
This should be simple to do, login in 192.168.1.1, create a cookie, and use the cookie to get into 192.168.1.1/index.asp, submit Restart_button, job done, however I am not very familiar with commands that deal with networks...
I am currently looking for the Python way, I am using Python 3.9.1 amd64, I have put it in PATH long ago, I have installed Selenium and Twill via pip. and downloaded and extracted GeckoDriver.exe to Python installation folder;
I know selenium, twill, urllib, urllib2, cookielib and webbot, all are capable of doing this, I am currently trying to figure out how to do it in the best way.
I have managed to login to the router in Python via twill, however I don't know what to do next:
from twill.commands import *
go('http://192.168.1.1')
showforms()
fv("1","txt_Username","CMCCAdmin")
fv("1","txt_Password","aDm8H%MdA")
showforms()
submit('btnSubmit')
go("http://192.168.1.1/index.asp")
The button:
<input type="button" name="Restart_button" id="Restart_button" class="submit" style="width:98px" onclick="Reboot()" value="重启">
It is located at:
html.body.#container.#center.#content.table.tbody.tr.td.#frameContent.html.body.div.#Restart_button
Also, the inputfields
of the first page(http://192.168.1.1):
PS C:\Windows\System32> $html.inputfields
outerHTML : <input name="txt_Username" type="text" id="txt_Username" style="float:left;padding:0;width:218px;height:38px;line-height:38px;text-indent:0.5em;border:0 solid green;background-color:transparent;" maxlength="31"/>
tagName : INPUT
name : txt_Username
type : text
id : txt_Username
style : float:left;padding:0;width:218px;height:38px;line-height:38px;text-indent:0.5em;border:0 solid green;background-color:transparent;
maxlength : 31
outerHTML : <input name="txt_Password" type="password" id="txt_Password" maxlength="127" style="float:left;padding:0;width:218px;height:38px;line-height:38px;text-indent:0.5em;border:0 solid green;background-color:transparent;"
maxlength="31"/>
tagName : INPUT
name : txt_Password
type : password
id : txt_Password
maxlength : 31
style : float:left;padding:0;width:218px;height:38px;line-height:38px;text-indent:0.5em;border:0 solid green;background-color:transparent;
outerHTML : <input type="button" id="btnSubmit" name="btnSubmit" value="确定" onclick="SubmitForm();" class="button_css"/>
tagName : INPUT
type : button
id : btnSubmit
name : btnSubmit
value : 确定
onclick : SubmitForm();
class : button_css
outerHTML : <input type="reset" name="Submit2" value="取消" onclick="canceltext();" class="button_css"/>
tagName : INPUT
type : reset
name : Submit2
value : 取消
onclick : canceltext();
class : button_css
I have got the source code of the reset page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Pragma" content="no-cache" />
<link rel="stylesheet" href='../../../../Cuscss/frame.css?2020070716413845-1425773353' type='text/css'>
<script language="JavaScript" src="../../../resource/common/util.js?2020070716413845-1425773353"></script>
<script language="JavaScript" type="text/javascript">
function LoadFrame()
{
}
function Reboot()
{
if(ConfirmEx("确定要重启设备吗?"))
{
setDisable('Restart_button', 1);
setDisable('Restore_button', 1);
setDisable('btnRestoreDftCfg', 1);
var Form = new webSubmitForm();
Form.setAction('set.cgi?x=' + 'InternetGatewayDevice.X_HW_DEBUG.SMP.DM.ResetBoard'
+ '&RequestFile=html/ssmp/devmanage/cmccdevicereset.asp');
Form.addParameter('x.X_HW_Token', getValue('onttoken'));
Form.submit();
}
}
</script>
</head>
<body class="mainbody" onLoad="LoadFrame();">
<div class="func_spread"></div>
<div class="title_with_desc">
<label id="Title_reboot_lable">设备重启</label>
</div>
<div class="title_01" style="padding-left:10px;" width="100%">
<label id="Title_reboot_tips_lable">点击如下按钮重启路由器。</label>
</div>
<div class="button_spread"></div>
<div align="right">
<input type="hidden" name="onttoken" id="hwonttoken" value="de0f5f98c4d4a77239ccb981cd5c4bf3">
<input type='button' name="Restart_button" id="Restart_button" class="submit" style="width:98px" onClick='Reboot()' value="重启">
</div>
</body>
</html>
It is located at address:
http://192.168.1.1/html/ssmp/devmanage/cmccdevicereset.asp
Also I don't really know if Submit('btnSubmit')
logged me in or not, I am not totally sure...
And although this works, Firefox initializes very slowly.
I have finally figured out how to do it the telnet way:
telnet 192.168.1.1
root
adminHW
reset
How can I make it a script that automatically inputs commands?
If your router supports SSH access (you probably need to enable it in the router settings), you can try issuing a command via SSH to restart it.
It could be something like ssh USERNAME@ROUTER_ADDRESS reboot
or ssh USERNAME@ROUTER_ADDRESS "sudo reboot"
.
ssh USERNAME@ROUTER_ADDRESS
(if it does, you will be asked for password and, after entering correct password, get into the router's command prompt).reboot
. But you may also need to specify exact path like /sbin/reboot
, /usr/sbin/reboot
or etc. And/or you may also need to elevate the privileges like sudo COMMAND
or su -c 'COMMAND' root
.ssh USERNAME@ROUTER_ADDRESS
) and issuing a reboot command (e.g. sudo reboot
) into a single command (like ssh USERNAME@ROUTER_ADDRESS "sudo reboot"
). You will still be asked for password every time, but it can be avoided (please ping me in comments if you reached this step and want to avoid typing passwords).Open Network Monitor in your browser (e.g. in Firefox that's Shift+Ctrl+E) and try to determine which exactly web request is issued when you confirm restart (e.g. in Firefox you can see the whole data of the request).
According to user Ligeti here, for a similar model: https://jalalsela.com/accessing-hg8245q-shell/
root
/?
From here you can try and find a command like reboot
to restart, or shell
to give access to more bash commands, maybe shutdown -r
or help
/?
from there. If it says you don't have permission for something, he includes steps to super-admin yourself, but I don't think it would be necessary.
Finally I have done it, and I found it to be very easy.
I used Python 3.9.1, Internet Explorer , Selenium and IEDriverServer.exe (32-bit).
The code:
import selenium
from selenium import webdriver
ie = webdriver.Ie()
ie.get('http://192.168.1.1')
ie.find_element_by_id('txt_Username').send_keys("CMCCAdmin")
ie.find_element_by_id('txt_Password').send_keys("aDm8H%MdA")
ie.find_element_by_id('btnSubmit').click()
ie.get('http://192.168.1.1/html/ssmp/devmanage/cmccdevicereset.asp')
ie.find_element_by_id('Restart_button').click()
ie.switch_to.alert.accept()
I saved it as RebootModem.py
, it works well, just it doesn't close the Window automatically after the router rebooted, and the code execution just hangs at ie.switch_to.alert.accept()
and won't quit, requiring me to manually close the IE window...
I tried the code in console, and I have found that the console won't accept commands until the router has finished rebooting...
I am currently trying to find the webbot, urllib(2), cookielib and twill way to do this, I don't think relying on a browser is very efficient.
I have made it automatically close the IE window and script by:
start-process -filepath python -argumentlist $PSScriptRoot\RebootModem.py
start-sleep -seconds 15
get-process -name iexplore | stop-process
get-process -name IEDriverServer| stop-process
Save as RebootModem.ps1
, at the same directory as RebootModem.py
, run RebootModem.ps1
to start execution of RebootModem.py
and it will automatically close the IE window and Python.exe (its name is changed to IEDriverServer.exe) after 15 seconds...
To generalize the code, just replace the elementids with the elementids of your router's webpage, you can get them by Ctrl+Shift+I, and replace the addresses with the addresses you found (though you probably don't need to change 192.168.1.1), I got the address of the page used to reboot modem by "View Frame Source".
P.S. the full code I used to reset all network settings:
devcon disable *dev_8168*
devcon enable *dev_8168*
start-sleep -seconds 3
netsh winsock reset
netsh winhttp reset proxy
netsh http flush log buffer
net start dot3svc
netsh lan reconnect
net stop dot3svc
start-sleep -seconds 3
netsh int ip reset
netsh int ipv4 reset
netsh int ipv6 reset
netsh int httpstunnel reset
netsh int portproxy reset
netsh int tcp reset
start-sleep -seconds 3
ipconfig /release
ipconfig /all
ipconfig /flushdns
ipconfig /registerdns
ipconfig /renew
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
RunDll32.exe InetCpl.cpl,ResetIEtoDefaults
Start-Sleep -Seconds 1
[System.Windows.Forms.SendKeys]::SendWait("{Tab}")
[System.Windows.Forms.SendKeys]::SendWait(" ")
[System.Windows.Forms.SendKeys]::SendWait("R")
Start-Sleep -Seconds 2
[System.Windows.Forms.SendKeys]::SendWait("C")
start-process -filepath python -argumentlist $PSScriptRoot\RebootModem.py
start-sleep -seconds 15
get-process -name iexplore | stop-process
get-process -name IEDriverServer| stop-process
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name "ProxyEnable" -Type DWord -Value 1
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name "ProxyOverride" -Type String -Value "login.live.com;account.live.com;clientconfig.passport.net;wustat.windows.com;*.windowsupdate.com;*.wns.windows.com;*.hotmail.com;*.outlook.com;*.microsoft.com;*.msftncsi.com;<local>"
I have done it...again!
The PowerShell + VBScript + Telnet way to do this:
set router = CreateObject ("WScript.Shell")
router.run("Telnet")
WScript.Sleep 750
router.sendkeys("Open 192.168.1.1")
router.sendkeys("{Enter}")
WScript.Sleep 750
router.sendkeys("root")
router.sendkeys("{Enter}")
WScript.Sleep 750
router.sendkeys("adminHW")
router.sendkeys("{Enter}")
WScript.Sleep 750
router.sendkeys("reset")
router.sendkeys("{Enter}")
Save as RebootModem.vbs
Start-Process -Filepath cscript.exe -Argumentlist $PSScriptRoot\RebootModem.vbs
Start-Sleep -Seconds 6
Get-Process -Name Telnet | Stop-Process
Save as RebootModem.ps1
Run RebootModem.ps1
to restart the modem via Telnet and automatically close Telnet.exe after 6 seconds.
Pure PowerShell method:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
Start-Process -Filepath Telnet.exe -Argumentlist 192.168.1.1
Start-Sleep -Seconds 1
[System.Windows.Forms.SendKeys]::SendWait("root")
[System.Windows.Forms.SendKeys]::SendWait("{Enter}")
[System.Windows.Forms.SendKeys]::SendWait("adminHW")
[System.Windows.Forms.SendKeys]::SendWait("{Enter}")
[System.Windows.Forms.SendKeys]::SendWait("reset")
[System.Windows.Forms.SendKeys]::SendWait("{Enter}")
Get-Process -Name Telnet | Stop-Process
It gets the job done in less than 3 seconds. I have determined that this is indeed the most efficient way to do this.
User contributions licensed under CC BY-SA 3.0