当前位置: 首页 > 后端技术 > Python

关于执行winrmremotepslogin有中文乱码和?乱码问题及解决方法

时间:2023-03-26 15:09:15 Python

python的winrm库提供了命令行远程连接的功能,可以实现远程登录的功能,执行命令:1.远程登录importwinrmauth=(username,password)shell=温姆。Session(host_ip,auth=auth,transport='ntlm')当然如果要实现远程连接,客户端和服务端必须启动并设置winrm服务。详情请参考:https://www.jianshu。com/p/ac0...2。执行命令winrm作为windows远程连接的库,提供了cmd命令和ps命令两种执行命令的执行方式。这两个命令之间仍然存在差异。比如ps命令直接用cmd运行会报错。两者的区别是笔者从网上借来的:powershell可以看作是cmd的超集,所有常用命令如dir、cd、ipconfig等都可以在powershell中直接使用。但其背后的实现是完全不同的。powershell基于完全面向对象,它通过“别名化”函数和对象来支持这些旧命令。.执行命令很简单,只需要使用生成的shell对象调用相应的方法res=shell.run_ps('ipconfig')res=shell.run_cmd('ipconfig')即可得到命令返回的内容,直接即可res.std_out.decode()res还有其他参数,比如状态码等,需要的话可以直接使用chartdet.detect(res.std_out))检查编码类型,直接解码打印出来的编码类型。比如打印出来的是gb2312,那就用res.std_out.decode('gb2112')方法二:如果不输出的时候有问题,那么就需要考虑是不是发送命令的时候有问题了。首先确认有问题的命令是否可以运行。您可以远程连接到相应的服务器并手动运行它。powershell远程登录请参考:https://blog。csdn.net/weixin_...如果确认命令正常,则可能是源码有问题。跑到wirm的源代码里看情况,我这里的版本是pywinrm0.4.2defrun_cmd(self,command,args=()):#TODOoptimizeperf.不要每次都调用打开/关闭shellshell_id=self.protocol.open_shell().cleanup_command(shell_id,command_id)self.protocol.close_shell(shell_id)returnrsdefrun_ps(self,script):"""base64encodesaPowershellscriptandexecutesthepowershellencodedscriptcommand"""#mustuseutf16littleendianon上windowsencoded_ps=b64encode(script.encode('utf_16_le')).decode('ascii')rs=self.run_cmd('powershell-encodedcommand{0}'.format(encoded_ps))iflen(rs.std_err):#如果有错误消息,请将其清理并使其成为人类#可读rs.std_err=self._clean_error_msg(rs.std_err)returnrs重点观察这两个函数,我们可以看到当你执行run_ps的时候,转码后会直接调用run_cmd,那么是不是可以认为ps命令转码后可以转码运行呢到cmd执行?这只是猜测,需要研究的汉字乱码问题也可能出现在这次转码中!通过调试可以看到,我们输入的命令的condepage是936,库默认的编码是437,会导致输入的命令出现乱码。我们现在要做的是统一编码。第一步:继承winrm.Session类并重写run_cmddefrun_cmd(self,command,args=()):#TODOoptimizeperf.不要每次调用打开/关闭shellshell_id=self.protocol.open_shell(codepage=936)))self.protocol.cleanup_command(shell_id,command_id)self.protocol。close_shell(shell_id)returnrs第二步:在执行命令前设置shell的代码shell.protocol.open_shell(codepage='936')重写run_ps和run_cnd时注意调用你重写的类的方法,否则rewrite是没有意义的,这样可以保证输入命令时编码统一。