Как использовать PowerShell для перезапуска маршрутизатора?
Мой компьютер подключен к роутеру сетевым кабелем, роутер выполняет функцию модема, он подключается к интернет-провайдеру через PPPoE, мой компьютер находится за NAT.
Модель моего роутера: Huawei 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 и используйте его для входа на 192.168.1.1/index.asp, нажмите кнопку Restart_button, и дело сделано, однако я не очень хорошо знаком с командами, которые работают с сетями...
В настоящее время я ищу способ с Python, я использую Python 3.9.1 amd64, я давно поместил его в PATH, я установил Selenium и Twill через pip, а также скачал и распаковал GeckoDriver.exe в папку установки Python;
Я знаю, что selenium, twill, urllib, urllib2, cookielib и webbot — все они способны на это. Сейчас я пытаюсь понять, как это сделать наилучшим образом.
Мне удалось войти в маршрутизатор в Python через twill, однако я не знаю, что делать дальше:
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 reboot
или ssh USERNAME@ROUTER_ADDRESS "sudo reboot"
.
- Для начала вам нужно включить доступ по SSH. Убедитесь, что он работает, введя что-то вроде
ssh USERNAME@ROUTER_ADDRESS
(если работает, вас попросят ввести пароль и после ввода правильного пароля вы попадете в командную строку маршрутизатора). - Затем определите, какую команду вам нужно ввести в командной строке маршрутизатора, чтобы перезапустить его. Это может быть просто
reboot
. Но вам также может потребоваться указать точный путь, например/sbin/reboot
,/usr/sbin/reboot
или и т. д. И/или вам также может потребоваться повысить привилегии, напримерsudo COMMAND
илиsu -c 'COMMAND' root
. - Если предыдущие два шага пройдены, вы можете объединить вход в SSH (
ssh USERNAME@ROUTER_ADDRESS
) и запуск команды перезагрузки (напримерsudo reboot
) в одну команду (напримерssh USERNAME@ROUTER_ADDRESS "sudo reboot"
). Вас все равно будут спрашивать пароль каждый раз, но этого можно избежать (пожалуйста, напишите мне в комментариях, если вы дошли до этого шага и хотите избежать ввода паролей).
HTTP-способ
Откройте сетевой монитор в вашем браузере (например, в Firefox это Shift+ Ctrl+ E) и попробуйте определить, какой именно веб-запрос отправляется при подтверждении перезагрузки (например, в Firefox вы можете увидеть все данные запроса).
решение2
По словам пользователя Ligeti, для похожей модели:https://jalalsela.com/accessing-hg8245q-shell/
- SSH/Telnet к устройству
- Войти как
root
- Вы можете просмотреть список доступных команд с помощью
/?
Отсюда вы можете попробовать найти команду, например, reboot
перезапустить, или shell
предоставить доступ к большему количеству команд bash, может быть, shutdown -r
или help
/ ?
оттуда. Если он говорит, что у вас нет разрешения на что-то, он включает шаги, чтобы стать супер-администратором, но я не думаю, что это будет необходимо.
решение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
, и это автоматически закроет окно IE и Python.exe (его имя изменится на IEDriverServer.exe) через 15 секунд...
Чтобы обобщить код, просто замените elementids на elementids веб-страницы вашего маршрутизатора, вы можете получить их с помощью ++ Ctrl, и замените адреса на адреса, которые вы нашли (хотя вам, вероятно, не нужно менять 192.168.1.1), я получил адрес страницы, используемой для перезагрузки модема, с помощью «Просмотра источника кадра».ShiftI
P.S. Полный код, который я использовал для сброса всех сетевых настроек:
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 и автоматического закрытия Telnet.exe через 6 секунд.
Чистый метод 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 секунды. Я определил, что это действительно самый эффективный способ сделать это.