如何使用 PowerShell 和/或 Python 重启路由器?

如何使用 PowerShell 和/或 Python 重启路由器?

如何使用 PowerShell 重启路由器?

我的电脑使用网线连接到路由器,路由器充当调制解调器,它通过 PPPoE 连接到 ISP,我的电脑位于 NAT 后面。

我的路由器型号:华为HS8545M、LAN地址:192.168.1.1、网页管理员登录:CMCCAdmin、网页管理员密码:aDm8H%MdA。

我必须执行以下操作来重新启动路由器(总共点击 7 次,浏览器会记住登录名和密码):

在此处输入图片描述

在此处输入图片描述

步骤太多了。

我曾尝试使用这种方法:

$ie = New-Object -ComObject 'internetExplorer.Application'
$ie.Navigate "https://192.168.1.1"

但过了一会儿,连接就丢失了,.Document一片空白,尝试刷新时出现以下错误:

OperationStopped: The RPC server is unavailable. (0x800706BA)

我正在使用 Windows 10 20H2,并且已禁用远程桌面、远程协助、远程注册表、Windows 远程管理和许多其他功能,我禁用了远程功能,因为它们对安全构成威胁,我认为它们与此有关;顺便说一句,RPC服务正在运行。

谁能帮我?


第一页源代码:页面1.html

第二页源代码:页面2.html

这应该很简单,登录 192.168.1.1,创建一个 cookie,然后使用该 cookie 进入 192.168.1.1/index.asp,提交 Restart_button,任务完成,但是我不太熟悉处理网络的命令......


我目前正在寻找 Python 的方式,我使用的是 Python 3.9.1 amd64,我早就把它放在了 PATH 中,我已经通过 pip 安装了 Selenium 和 Twill。并且下载并解压了 GeckoDriver.exe 到 Python 安装文件夹;

我知道 selenium、twill、urllib、urllib2、cookielib 和 webbot 都可以做到这一点,我目前正在尝试找出如何以最佳方式做到这一点。


我已经设法通过 twill 使用 Python 登录到路由器,但我不知道下一步该做什么:

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")

在此处输入图片描述

按钮:

<input type="button" name="Restart_button" id="Restart_button" class="submit" style="width:98px" onclick="Reboot()" value="重启">

它位于:

html.body.#container.#center.#content.table.tbody.tr.td.#frameContent.html.body.div.#Restart_button

此外,inputfields第一页的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

我已经获得了重置页面的源代码:

<!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>

其地址为:

http://192.168.1.1/html/ssmp/devmanage/cmccdevicereset.asp

另外我真的不知道Submit('btnSubmit')我是否登录了,我不完全确定......

尽管这种方法可行,但是 Firefox 的初始化速度非常慢。


我终于明白了如何通过 telnet 方式进行操作:

telnet 192.168.1.1
root
adminHW
reset

我怎样才能使它成为自动输入命令的脚本?

答案1

SSH 方式

如果您的路由器支持 SSH 访问(您可能需要在路由器设置中启用它),您可以尝试通过 SSH 发出命令来重新启动它。

它可能类似于ssh USERNAME@ROUTER_ADDRESS rebootssh USERNAME@ROUTER_ADDRESS "sudo reboot"

  1. 首先,您需要启用 SSH 访问。输入类似以下内容以确保它有效ssh USERNAME@ROUTER_ADDRESS(如果有效,系统会要求您输入密码,输入正确密码后,进入路由器的命令提示符)。
  2. 然后确定您需要在路由器的命令提示符中输入哪个命令来重新启动它。它可能只是reboot。但您可能还需要指定确切的路径,如/sbin/reboot/usr/sbin/reboot等等。并且/或者您可能还需要提升权限,如sudo COMMANDsu -c 'COMMAND' root
  3. 如果完成了前面两个步骤,您可以将登录 SSH(ssh USERNAME@ROUTER_ADDRESS)和发出重启命令(例如sudo reboot)合并为一个命令(如ssh USERNAME@ROUTER_ADDRESS "sudo reboot")。每次仍会要求您输入密码,但可以避免(如果您已到达此步骤并想避免输入密码,请在评论中联系我)。

HTTP 方式

在浏览器中打开网络监视器(例如在 Firefox 中为Shift+ Ctrl+ E),并尝试确定在确认重新启动时究竟发出了哪个 Web 请求(例如在 Firefox 中,您可以看到请求的全部数据)。

答案2

根据用户 Ligeti 的说法,对于类似的模型:https://jalalsela.com/accessing-hg8245q-shell/

  • 通过 SSH/Telnet 连接到设备
  • 登录身份root
  • 您可以使用以下命令列出可用的命令/?

从这里,您可以尝试找到命令,例如reboot重新启动,或者shell授予对更多 bash 命令的访问权限,也许shutdown -rhelp?那里。如果它说您没有权限执行某些操作,他会包含您自己超级管理员的步骤,但我认为这没有必要。

答案3

最后我终于完成了,我发现这非常简单。

我使用了 Python 3.9.1、Internet Explorer、Selenium 和 IEDriverServer.exe(32 位)。

代码:

    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()

我将其保存为RebootModem.py,它运行良好,只是在路由器重新启动后它不会自动关闭窗口,并且代码执行只是挂起ie.switch_to.alert.accept()并且不会退出,需要我手动关闭 IE 窗口...

我尝试了控制台中的代码,发现控制台在路由器重启完成之前不会接受命令......

我目前正在尝试寻找 webbot、urllib(2)、cookielib 和 twill 方法来做到这一点,我认为依赖浏览器并不是很有效。


我已使其自动关闭 IE 窗口和脚本,方法是:

    start-process -filepath python -argumentlist $PSScriptRoot\RebootModem.py
    start-sleep -seconds 15
    get-process -name iexplore | stop-process
    get-process -name IEDriverServer| stop-process

另存为RebootModem.ps1,与 放在同一目录RebootModem.py,运行RebootModem.ps1开始执行RebootModem.py,15秒后会自动关闭IE窗口和Python.exe(其名称更改为IEDriverServer.exe)...


为了概括代码,只需将 elementids 替换为路由器网页的 elementids,您可以通过 ++ 获取它们Ctrl,并将地址替换为您找到的地址(尽管您可能不需要更改 192.168.1.1),我通过“查看框架源ShiftI获得了用于重新启动调制解调器的页面的地址。


PS 我用来重置所有网络设置的完整代码:

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>"

答案4

我又做到了...又一次!

PowerShell + VBScript + Telnet 方式执行此操作:

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}")

另存为RebootModem.vbs

Start-Process -Filepath cscript.exe -Argumentlist $PSScriptRoot\RebootModem.vbs
Start-Sleep -Seconds 6
Get-Process -Name Telnet | Stop-Process

另存为RebootModem.ps1

运行RebootModem.ps1以通过 Telnet 重新启动调制解调器,并在 6 秒后自动关闭 Telnet.exe。


纯 PowerShell 方法:

    [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

不到 3 秒就能完成任务。我确定这确实是最有效的方法。

相关内容