python实践winrm,实现远程连接调度Windows服务器

前言

最近有个需求:用自己主机控制多个windows节点,实时获取他们的cpu和运存占用情况,通过查询,决定采用python中的winrm。
Tip:winrm服务是windows 一种方便远程管理的服务;开启winrm service,便于在日常工作中,远程管理服务器,或通过脚本,同时管理多台服务器,来提高工作效率。

常规做法

配置远程主机,使其支持被远程控制

  • 查看winrm service listener(分为http和https):
    1
    winrm e winrm/config/listener

如果没有返回,则没有开启winrm服务。

  • 开启winrm服务:

    1
    winrm quickconfig
  • 为winrm service 配置auth:

    1
    winrm set winrm/config/service/auth @{Basic="true"}
  • 为winrm service 配置加密方式为允许非加密:

    1
    winrm set winrm/config/service @{AllowUnencrypted="true"}
  • 查看winrm服务的配置:

    1
    winrm get winrm/config

客户端主机

  • 装winrm

    1
    pip install pywinrm
  • 测试

    1
    2
    3
    4
    import winrm
    wintest = winrm.Session('http://47.98.149.160:5985/wsman',auth=('Administrator','Jwy12345a'))
    ret = wintest.run_cmd('ipconfig')
    print(ret)

遇到的问题及解决措施

  • 在测试环节,导入winrm包后,控制台显示:winrm has no attribute session
    解决办法:pip导错了包,应该是pywinrm这个包,将pip原来的包删除,重新导入一遍。

  • pycharm问题:module ‘pip’ has no attribute ‘main’
    解决办法:pip升级导致无法导包

  • 测试的时候,报出以下错误:

    1
    requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='47.98.149.160', port=5985): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x104921650>, 'Connection to 47.98.149.160 timed out. (connect timeout=30)'))

    解决办法:由于云服务器有公网ip地址,所以本机可以ping通服务器,但是由于本机不存在公网地址,是局域网地址,所以服务器不能ping通主机,导致二者不能正常通信,只能换一种方法,也就是在云服务器端运行程序,程序提供了当前cpu运行情况和运存情况,本机可以随时访问并得到信息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    import time

    import psutil # cd C:\Python36-32\Scripts pip install psutil

    # 获取本机磁盘使用率和剩余空间G信息
    import pymysql

    conn = pymysql.connect(user="root", passwd="No.93329332", host="134.175.5.88", port=3306, db="node_status")
    cur = conn.cursor()
    flag = 0
    while(True):
    # 循环磁盘分区
    content = ""
    for disk in psutil.disk_partitions():
    # 读写方式 光盘 or 有效磁盘类型
    if 'cdrom' in disk.opts or disk.fstype == '':
    continue
    disk_name_arr = disk.device.split(':')
    disk_name = disk_name_arr[0]
    disk_info = psutil.disk_usage(disk.device)
    # 磁盘剩余空间,单位G
    free_disk_size = disk_info.free // 1024 // 1024 // 1024
    # 当前磁盘使用率和剩余空间G信息
    if (disk_name == 'C'):
    disk_c_name = disk_name
    disk_c_info = disk_info
    free_c_disk_size = free_disk_size
    info = "%s盘使用率:%s%%, 剩余空间:%iG" % (disk_c_name, str(disk_c_info.percent), free_c_disk_size)
    # print(info)
    # print(disk_name)
    if (disk_name == 'C'):
    # 拼接多个磁盘的信息
    content = content + info
    print(content)
    # return content
    # cpu信息
    cpu_percent = psutil.cpu_percent(interval=1)
    cpu_info = "CPU使用率:%i%%" % cpu_percent
    print(cpu_info)
    # return cpu_info
    # 内存信息
    virtual_memory = psutil.virtual_memory()
    used_memory = virtual_memory.used / 1024 / 1024 / 1024
    free_memory = virtual_memory.free / 1024 / 1024 / 1024
    memory_percent = virtual_memory.percent
    memory_info = "内存使用:%0.2fG,使用率%0.1f%%,剩余内存:%0.2fG" % (used_memory, memory_percent, free_memory)
    print(memory_info)
    # return memory_info
    now = time.asctime()
    if(flag == 0):
    sql = "INSERT INTO status(ip, \
    disk_percent, disk_freesize, CPU_percent, memory_used,memory_free,memory_percent,mytime) \
    VALUES ('%s', '%s', '%s', '%s', '%s','%s','%s','%s')" % \
    ('106.13.70.159', str(disk_c_info.percent) + "%", str(free_c_disk_size) + "G", str(cpu_percent) + "%",str(used_memory)[:3] + "G",str(free_memory)[:3] + "G",str(memory_percent) + "%",now)
    flag = 1
    else:
    used_memory_float = str(used_memory)[:3] + 'G'
    free_memory_folat = str(free_memory)[:3] + 'G'
    disk_c_info_percent_str = str(disk_c_info.percent) + '%'
    free_c_disk_size_str = str(free_c_disk_size) + 'G'
    cpu_percent_str = str(cpu_percent) + '%'
    memory_percent_str = str(memory_percent) + '%'

    sql = "update status set disk_percent = '%s', disk_freesize = '%s', \
    CPU_percent = '%s', memory_used = '%s' , memory_free = '%s' ,\
    memory_percent = '%s' , mytime = '%s' where ip = '106.13.70.159'" % \
    (disk_c_info_percent_str,free_c_disk_size_str,cpu_percent_str,used_memory_float,free_memory_folat,memory_percent_str,now)
    flag = 2
    try:
    # 执行sql语句
    cur.execute(sql)
    # 执行sql语句
    conn.commit()
    if(flag==1):
    print("insert ok")
    else:
    print("update ok")
    except Exception as e:
    # 发生错误时回滚
    conn.rollback()
    print("failed")
    print(e)
    time.sleep(60)
    # 关闭数据库连接
    conn.close()
  • sql中update也可以

    1
    sql = "update table set ss = '%s'where id = '1'"% disk
Thank you for your accept. mua!
-------------本文结束感谢您的阅读-------------