python实现windows远程批量安装应用 python远程cmd_json


功能介绍

功能1:自动检测文件变动,并发送到另外一台计算机

两台windows计算机相互连接,计算机A监测本机指定文件夹下的文件变动,如果该文件夹中出现了新文件,则自动将其发送到计算机B的指定位置。

功能2:将python文件发送到另一台计算机并执行,并将执行结果传回本机

计算机B的性能要比计算机A的性能高很多,因此很多python代码要运行在计算机B,而A只起到收发python文件,并从计算机B那里获得运行结果的作用。

环境准备

开启win10 openssh服务

我们要把文件从计算机A发送到计算机B。

首先,在计算机B中进行操作。打开设置,搜索 管理可选功能 , 点击添加功能,下载安装openSSH服务器,还有OpenSSH客户端。安装完成后,在win10搜索框里搜索服务,设置这两个服务为自动启动:


python实现windows远程批量安装应用 python远程cmd_json_02


安装所需要的库

在计算机A上安装一些python库:

scpclient:pip install scpclient

paramiko:pip install paramiko

pywinrm:pip install pywinrm

winrm的设置

winrm用于远程执行命令。

我们在计算机B上进行操作:

打开powersheell(管理员),输入命令: winrm quickconfig ,查看winrm是否开启成功,如果提示未开始,输入enter执行提示操作开始winrm。

接下来是把网络设置为 专用网络 ,这个我发现surface pro4的 手机热点本身就被设置为了专用网络,就不再管了。

再接下来是执行两个命令(powershell 管理员模式):

winrm set winrm/config/service/auth @{Basic="true"}

然后就报出了这个错误:


python实现windows远程批量安装应用 python远程cmd_python_03


经搜索发现,上面那条命令是错误的,真正正确的是: winrm set winrm/config/service/auth '@{Basic="true"}'

再接下来是按照【10】的说法,配置非加密服务: winrm set winrm/config/service '@{AllowUnencrypted="true"}'

代码编辑

然后在计算机A运行代码:


import paramiko

hostname="计算机B的ip地址"
port = 22
username = "计算机B开机时候的用户名"
password = "计算机B开机时候的密码"
transport = paramiko.Transport((hostname, port))
transport.connect(username = username, password = password)
sftp = paramiko.SFTPClient.from_transport(transport)
# 下载文件
sftp.get("D:/test.txt","D:/U盘/test.txt") # 把计算机B放在D->U盘里的test.txt放到计算机A的D盘根目录
# #上传文件
# sftp.put("./video.mp4","/home/share/video.mp4")
sftp.close()


以上就实现了两台计算机文件的发送。接下来是远程执行python脚本的代码:


import paramiko
import time
import os
import shutil
import winrm
import json

# hostname="10.201.147.111"
# username="dell"
# password="2019202210088"

hostname = "计算机B的ip地址"
username = "计算机B的用户名"
password = "计算机B的密码"

port = 22

transport = paramiko.Transport((hostname, port))  # 建立远程连接
transport.connect(username=username, password=password)

sftp = paramiko.SFTPClient.from_transport(transport)



class ServerByPara(object):
    def __init__(self, cmd, host, user, password, system_choice):
        self.cmd = cmd
        self.client = paramiko.SSHClient()
        self.host = host
        self.user = user
        self.pwd = password
        self.system_choice = system_choice

    def exec_linux_cmd(self):
        data_init = ''
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.client.connect(hostname=self.host, username=self.user, password=self.pwd)
        stdin, stdout, stderr = self.client.exec_command(self.cmd, get_pty=True)
        if stderr.readlines():
            exec_tag = 1
            for data in stdout.readlines():
                data_init += data
        else:
            exec_tag = 0
            for data in stdout.readlines():
                data_init += data
        return json.dumps({
            "exec_tag": exec_tag,
            "data": data_init,
        }, ensure_ascii=False)

    def exec_win_cmd(self):
        data_init = ""
        s = winrm.Session(self.host, auth=(self.user, self.pwd))
        ret = s.run_cmd(self.cmd)
        if ret.std_err.decode():
            exec_tag = 1
            for data in ret.std_err.decode().split("rn"):
                data_init += data
        else:
            exec_tag = 0
            for data in ret.std_out.decode().split("rn"):
                data_init += data
        return json.dumps({
            "exec_tag": exec_tag,
            "data": data_init,
        }, ensure_ascii=False)

    def run(self):
        if self.system_choice == "Linux":
            result = self.exec_linux_cmd()
        else:
            result = self.exec_win_cmd()
        print(result)
        with open(r"script_info.txt", "w") as f:
            f.write(result)

def sendFile(hereFilePath,thereFilePath):
    # 上传文件
    print(hereFilePath)
    print(thereFilePath)
    sftp.put(hereFilePath, thereFilePath)

# 首先检查指定文件夹是否有文件
while True:
    fileList=os.listdir("D:codes")
    if len(fileList)>0: # 如果有文件就把所有文件都上传到计算服务器
        print("存在文件")
        for file in fileList:
            folder=file.split(".")[0]
            originFilePath=os.path.join("D:/codes",file)
            filePath=os.path.join("D:/codes/"+folder,file)
            sendFile(originFilePath,"D:/"+file)
            shutil.move(originFilePath,"D:/backup/"+file)
            # 运行解压程序
            print("运行解压程序")
            print("python D:/unzip.py "+"D:/"+file+" D:/codes/")
                server_obj = ServerByPara("python D:/unzip.py "+"D:/"+file+" D:/codes/", hostname, username, password, "windows")
                server_obj.run()
            time.sleep(3)
            # 上传完成后执行命令
            pyFile=filePath.replace(".zip",".py")
            print("开始运行:",pyFile)
            server_obj = ServerByPara("python "+pyFile, hostname, username, password, "windows")
            server_obj.run()
            print("运行结束")
    else:
        print("未扫描到文件")
        time.sleep(10)