Python管理远程windows
2020年9月22日 - 由Bo 0 评论 1508 阅读
目前的测试机一部分是docker linux,另有一部分是windows,用于不同产品对平台的需求。
linux用docker构建相应的环境依赖包,但windows却没有这么方便了。一个个的远程登录去操作实在繁琐,于是现在有个需求是能自动的管理windows测试机上的环境依赖,比如在某个服务失败时能批量执行命令重启,比如能批量升级某个软件。
这里就必须得提到winrm。WinRM(Windows Remote Management)是windows内置的远程管理协议,它的端口是5985和5986,通过它我们可以与远程主机建立连接、执行命令、监视管理和配置远程服务器。
首先我们需要打开远程windows机器的winrm服务,在其上面分别执行如下命令:
winrm quickconfig
winrm set winrm/config/service/auth @{Basic="true"}
Enable-WSManCredSSP -Role Server -Force
Set-Item -Path "WSMan:\localhost\Service\Auth\CredSSP" -Value $true
python有个包是用到了winrm,叫做pywinrm,执行pip install pywinrm安装。
于是我们可以用python脚本设定各种条件来决定是否需要对远程windows机器做操作。
建立连接:
import winrm
winrm.Session('http://%s:5985/wsman' % ip, auth=(name, passwd), transport='ntlm')
运行cmd命令或者powershell脚本
session.run_cmd('ipconfig', ['/all']) # run cmd
ps_script = """$strComputer = $Host
Clear
$RAM = WmiObject Win32_ComputerSystem
$MB = 1048576
"Installed Memory: " + [int]($RAM.TotalPhysicalMemory /$MB) + " MB" """
session.run_ps(ps_script) # run powershell script
在使用中遇到一个情况需要留意,需要批量启动一个自定义的server,但该server是持续存在且会等待其他模块的输入,于是就会造成这样的情况:python脚本连接了远程机器,并启动了这个server,由于这个命令始终在等待结束信号,于是便一直挂起。
因此可以重写一下pywinrm里的对应方法,我加了一个新的方法叫做new_run_cmd,并增加了一个not_wait的标签,当not_wait为真时,便会在执行了命令后退出,而不会一直等待。
class Connection:
def new_run_cmd(self, command, not_wait=False, args=()):
shell_id = self.protocol.open_shell()
command_id = self.protocol.run_command(shell_id, command, args)
if not_wait:
return None
else:
rs = winrm.Response(self.protocol.get_command_output(shell_id, command_id))
self.protocol.cleanup_command(shell_id, command_id)
self.protocol.close_shell(shell_id)
return rs
然后可以替换调用,便可指定是否需要等待命令结束了。
winrm.Session.run_cmd = Connection.new_run_cmd
关于完整的connection类和使用方式,可以参考我的一个github项目地址:https://github.com/bobjiangps/remote_windows_terminal