如何连接到远程 Windows 机器以使用 python 执行命令?
Posted
技术标签:
【中文标题】如何连接到远程 Windows 机器以使用 python 执行命令?【英文标题】:How to connect to a remote Windows machine to execute commands using python? 【发布时间】:2013-09-28 11:09:54 【问题描述】:我是 Python 新手,我正在尝试制作一个连接到远程 Windows 机器并在那里执行命令并测试端口连接性的脚本。
这是我正在编写的代码,但它不起作用。基本上,我想要它返回本地机器数据,而不是远程机器数据。
import wmi
import os
import subprocess
import re
import socket, sys
def main():
host="remotemachine"
username="adminaam"
password="passpass!"
server =connects(host, username, password)
s = socket.socket()
s.settimeout(5)
print server.run_remote('hostname')
class connects:
def __init__(self, host, username, password, s = socket.socket()):
self.host=host
self.username=username
self.password=password
self.s=s
try:
self.connection= wmi.WMI(self.host, user=self.username, password=self.password)
self.s.connect(('10.10.10.3', 25))
print "Connection established"
except:
print "Could not connect to machine"
def run_remote(self, cmd, async=False, minimized=True):
call=subprocess.check_output(cmd, shell=True,stderr=subprocess.STDOUT )
print call
main()
【问题讨论】:
各位有什么建议吗? ?请帮忙 在用户名前添加域前缀很重要。例如username = r"EUR\adminaam"
【参考方案1】:
您可以改用pywinrm
library,它是跨平台兼容的。
这是一个简单的代码示例:
#!/usr/bin/env python
import winrm
# Create winrm connection.
sess = winrm.Session('https://10.0.0.1', auth=('username', 'password'), transport='kerberos')
result = sess.run_cmd('ipconfig', ['/all'])
通过以下方式安装库:pip install pywinrm requests_kerberos
。
这是this page 在远程主机上运行 Powershell 脚本的另一个示例:
import winrm
ps_script = """$strComputer = $Host
Clear
$RAM = WmiObject Win32_ComputerSystem
$MB = 1048576
"Installed Memory: " + [int]($RAM.TotalPhysicalMemory /$MB) + " MB" """
s = winrm.Session('windows-host.example.com', auth=('john.smith', 'secret'))
r = s.run_ps(ps_script)
>>> r.status_code
0
>>> r.std_out
Installed Memory: 3840 MB
>>> r.std_err
【讨论】:
我正在尝试这个,当我运行像“ipconfig”这样的命令时遇到了一个问题。它说“HTTPSConnectionPool(host='192.168.1.13', port=5986): Max retries exceeded with url: /wsman (由 ConnectTimeoutError(您可以使用以下两种方法将一台计算机连接到网络中的另一台计算机:
使用 WMI 库。 Netuse 方法。WMI
以下是使用 wmi 模块进行连接的示例:
ip = '192.168.1.13'
username = 'username'
password = 'password'
from socket import *
try:
print("Establishing connection to %s" %ip)
connection = wmi.WMI(ip, user=username, password=password)
print("Connection established")
except wmi.x_wmi:
print("Your Username and Password of "+getfqdn(ip)+" are wrong.")
网络使用
第二种方法是使用netuse模块。
通过 Netuse,您可以连接到远程计算机。您可以访问远程计算机的所有数据。可以通过以下两种方式:
通过虚拟连接进行连接。
import win32api
import win32net
ip = '192.168.1.18'
username = 'ram'
password = 'ram@123'
use_dict=
use_dict['remote']=unicode('\\\\192.168.1.18\C$')
use_dict['password']=unicode(password)
use_dict['username']=unicode(username)
win32net.NetUseAdd(None, 2, use_dict)
断开连接:
import win32api
import win32net
win32net.NetUseDel('\\\\192.168.1.18',username,win32net.USE_FORCE)
在本地系统中安装远程计算机驱动器。
import win32api
import win32net
import win32netcon,win32wnet
username='user'
password='psw'
try:
win32wnet.WNetAddConnection2(win32netcon.RESOURCETYPE_DISK, 'Z:','\\\\192.168.1.18\\D$', None, username, password, 0)
print('connection established successfully')
except:
print('connection not established')
在本地系统中卸载远程计算机驱动器:
import win32api
import win32net
import win32netcon,win32wnet
win32wnet.WNetCancelConnection2('\\\\192.168.1.4\\D$',1,1)
在使用 netuse 之前,您还应该使用 python 在系统中安装 pywin32。
来源:Connect remote system。
【讨论】:
WMI 相对于 Netuse 的优缺点是什么,反之亦然?【参考方案3】:也许您可以使用 SSH 连接到远程服务器。
在您的 Windows 服务器上安装 freeSSHd。
SSH客户端连接代码:
import paramiko
hostname = "your-hostname"
username = "your-username"
password = "your-password"
cmd = 'your-command'
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname,username=username,password=password)
print("Connected to %s" % hostname)
except paramiko.AuthenticationException:
print("Failed to connect to %s due to wrong username/password" %hostname)
exit(1)
except Exception as e:
print(e.message)
exit(2)
执行命令并获得反馈:
try:
stdin, stdout, stderr = ssh.exec_command(cmd)
except Exception as e:
print(e.message)
err = ''.join(stderr.readlines())
out = ''.join(stdout.readlines())
final_output = str(out)+str(err)
print(final_output)
【讨论】:
这个解决方案帮了我很大的忙。从 Windows 机器上,我试图在远程机器上运行 shell 脚本,该远程机器最终具有要运行的 python 脚本路径。如果我需要运行多个命令,我可以重复执行命令框吗?请提出建议。 多次运行 exec_command 时,每个命令都在其自己的“shell”中执行。所以前面的命令对后面命令的环境没有影响。 如果您需要前面的命令来影响后面的命令,只需使用服务器外壳的适当语法即可。大多数 *nix shell 使用分号或双与号(具有不同的语义)来指定命令列表。在您的情况下,&符号更合适,因为它仅在先前的命令成功时执行以下命令:像这样: stdin,stdout,stderr=ssh.exec_command("ORACLE_SID=PROD && cd /01/application/dataload && pwd" )【参考方案4】:用于连接
c=wmi.WMI('machine name',user='username',password='password')
#this connects to remote system. c is wmi object
用于命令
process_id, return_value = c.Win32_Process.Create(CommandLine="cmd.exe /c <your command>")
#this will execute commands
【讨论】:
哇,很酷,效果很好,可以用pip安装[#]pip install wmi【参考方案5】:客户端机器是否加载了python?如果是这样,我正在使用psexec
在我的本地机器上,我使用 .py 文件中的子进程来调用命令行。
import subprocess
subprocess.call("psexec server -c ")
-c 将文件复制到服务器,以便我可以运行任何可执行文件(在您的情况下,它可能是一个充满连接测试的 .bat 或上面的 .py 文件)。
【讨论】:
【参考方案6】:我个人发现pywinrm
library 非常有效。但是,它确实需要在机器上运行一些命令和一些其他设置才能工作。
【讨论】:
你能推荐一些可用于跨平台远程登录的包 有趣的是你应该问。我个人正在为此开源一个库。【参考方案7】:我不知道 WMI,但如果你想要一个简单的服务器/客户端, 你可以使用来自tutorialspoint的这个简单代码
服务器:
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
while True:
c, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
c.send('Thank you for connecting')
c.close() # Close the connection
客户
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 12345 # Reserve a port for your service.
s.connect((host, port))
print s.recv(1024)
s.close # Close the socket when done
它还包含简单客户端/服务器应用程序所需的所有信息。
只需转换服务器并使用一些简单的协议从 python 调用函数。
P.S:我相信有很多更好的选择,如果你愿意,这只是一个简单的选择......
【讨论】:
感谢 Kobi 回复我,但要找到每个客户并在那里运行脚本会非常困难......我想做的是访问一台机器的多台机器并在那里执行命令【参考方案8】:连接远程服务器并执行命令的最佳方式是使用“wmiexec.py”
只需运行 pip install impacket
这将在python的脚本文件夹下创建“wmiexec.py”文件
在 python 内部 > 脚本 > wmiexec.py
我们需要通过以下方式运行wmiexec.py
python <wmiexec.py location> TargetUser:TargetPassword@TargetHostname "<OS command>"
请根据您的更改 wmiexec.py 位置
就像我使用 python 3.8.5 和我的 wmiexec.py 位置将是 C:\python3.8.5\Scripts\wmiexec.py
python C:\python3.8.5\Scripts\wmiexec.py TargetUser:TargetPassword@TargetHostname "<OS command>"
根据你的远程机器修改 TargetUser、TargetPassword、TargetHostname 和 OS 命令
注意: 以上方法用于在远程服务器上运行命令。
但是如果您需要从远程服务器捕获输出,我们需要创建一个 python 代码。
import subprocess
command = 'C:\\Python36\\python.exe C:\\Python36\\Scripts\\wmiexec.py TargetUser:TargetPassword@TargetHostname "ipconfig"'
command = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
stdout= command.communicate()[0]
print (stdout)
相应地修改代码并运行它。
【讨论】:
【参考方案9】:太晚了吗?
我个人同意 Beatrice Len 的观点,我使用 paramiko 可能是 windows 的额外步骤,但我有一个示例项目 git hub,请随意克隆或询问我。
https://github.com/davcastroruiz/django-ssh-monitor
【讨论】:
【参考方案10】:pypsrp - Python PowerShell 远程协议客户端库
At a basic level, you can use this library to;
Execute a cmd command
Run another executable
Execute PowerShell scripts
Copy a file from the localhost to the remote Windows host
Fetch a file from the remote Windows host to the localhost
Create a Runspace Pool that contains one or multiple PowerShell pipelines and execute them asynchronously
Support for a reference host base implementation of PSRP for interactive scripts
参考号:https://github.com/jborean93/pypsrp
【讨论】:
【参考方案11】:已经有很多答案了,但还有一个选择
PyPSExec https://pypi.org/project/pypsexec/
它是著名的 psexec 的 python 克隆。 无需在远程 Windows 机器上进行任何安装即可工作。
【讨论】:
以上是关于如何连接到远程 Windows 机器以使用 python 执行命令?的主要内容,如果未能解决你的问题,请参考以下文章
使用带有公钥和密码的 SSH 隧道通过 SQLAlchemy 连接到远程 PostgreSQL 数据库,所有这些都来自 Windows 机器