You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Python开发的adBot接收PowerShell命令?

问题描述

我在虚拟机中运行名为adBot的.exe程序,目前它可通过adClient脚本接收命令,在Active Directory中创建用户,这部分代码运行良好。但我希望让它能够接收PowerShell命令,当前使用rpyc和subprocess库实现连接。

现有代码

adBot 代码

#adBot
import argparse
import rpyc
from rpyc.utils.server import ThreadedServer
import datetime
import subprocess
date_time = datetime.datetime.now()

class MonitorService(rpyc.Service):
    def on_connect(self, conn):
        print("Conectado {}".format(date_time))
    def on_disconnect(self, conn):
        print("Desconectado {}\n".format(date_time))
    def exposed_run_command(self,command):
        try:
            output = subprocess.check_output(command,shell=True) 
            print(output)
        except subprocess.CalledProcessError as Error:
            print(Error.returncode)
            print(Error.output)
def main():
    parser = argparse.ArgumentParser(description="Active Directory Bot")
    parser.add_argument("-port",type=int,help="Enter Custom Port Number")
    args = parser.parse_args()
    port = args.port
    print("Puerto Recuperado: " + str(port))
    if not port:
        port = 18821 
    print("Puerto Usado: "+ str(port))
 
    t = ThreadedServer(MonitorService,port=port)
    t.start()

AdClient 代码

#AdClient
import rpyc
DISABLE_user = 'disable'
ENABLE_user = 'enable'
DELETE_user = 'delete'
ADD_group = 'add'
REMOVE_group = 'remove'
AD_IP = "172.19.128.3"  # IP Directorio Activo
LOCAL = "localhost"
MV_SERVER = "192.168.74.128"  # IP  maquina Virtual
AD_BOT_PORT = 18821
domain_controller = "dc=TEST,dc=LOCAL"
users_ou = f"ou=ALL,ou=Employee,{domain_controller}"
groups_ou = f"ou=Employee_Groups,{domain_controller}"

def enviarComando(comando):
 
    try:
        con = rpyc.connect(MV_SERVER, AD_BOT_PORT)
        con.root.run_command(comando)
        print("ok")
    except Exception as ERR:
        print(f"Error en enviar comando {ERR}")
    except TimeoutError as TIMEOUT:
        print(f"Error en tiempo de espera: {TIMEOUT}")

def crearUsuario(nombres, apellidos,desc, oficina, numTelf, numCasa, mobileNum, titulo, departamento, compania, dirCasa, active=False):

    if active:
        deshabilitar = "no"
    else:
        deshabilitar = "yes"
    descripcion = desc+f" USUARIO CREADO EN EL DIRECTORIO ACTIVO {datetime.datetime.now()}"
    displayName = nombres + " " + apellidos
    defaultPassword = "P@tito.123"
    username = cda.defineUsername(nombres, apellidos)
    upn = cda.defineUPN(username)
    email = cda.defineCorreo(nombres,apellidos)
    dn = f'"cn={username},{users_ou}"'
    country = "EC"
    grupo = f'"cn=All,{groups_ou}"'# All grupo ya creado
    comando = 'dsadd user ' \
              f'{dn} ' \
              f'-samid "{username}" ' \
              f'-upn "{upn}" ' \
              f'-fn "{nombres}" ' \
              f'-ln "{apellidos}" ' \
              f'-display "{displayName}" ' \
              f'-empid "{NULL}" ' \
              f'-pwd {defaultPassword} ' \
              f'-desc "{descripcion}" ' \
              f'-office "{oficina}" ' \
              f'-tel "{numTelf}" ' \
              f'-email "{email}" ' \
              f'-hometel "{numCasa}" ' \
              f'-pager "{NULL}" ' \
              f'-mobile "{mobileNum}" ' \
              f'-fax "{NULL}" ' \
              f'-iptel "{NULL}" ' \
              f'-webpg "{NULL}" ' \
              f'-title "{titulo}" ' \
              f'-dept "{departamento}" ' \
              f'-company "{compania}" ' \
              f'-disabled {deshabilitar} ' \
              '-pwdneverexpires yes ' \
              '-mustchpwd yes ' \
              f'-memberof {grupo} ' \
              '-acctexpires never ' \
              ''
    #comando = "New-ADUser -name 'sales user' -GivenName Sales -Surname USER -SamAccountName SalesUser -UserPrincipalName saleuser@corp.lan"
    print(comando)
    enviarComando(comando)
解决方案

要让adBot支持PowerShell命令,核心是确保subprocess调用PowerShell解释器而非默认的cmd,以下是具体修改方式:

1. 优化服务端命令执行逻辑

修改exposed_run_command方法,明确调用PowerShell并处理编码问题,避免输出乱码:

def exposed_run_command(self, command):
    try:
        # 指定调用PowerShell,输出采用UTF-8编码
        output = subprocess.check_output(
            ["powershell", "-Command", command],
            encoding='utf-8',
            stderr=subprocess.STDOUT
        )
        print(output)
        return output  # 返回执行结果给客户端,方便后续处理
    except subprocess.CalledProcessError as error:
        print(f"命令执行失败,返回码: {error.returncode}")
        print(f"错误输出: {error.output}")
        return error.output

2. 客户端发送PowerShell命令

直接构造PowerShell命令发送即可,比如修改crearUsuario中的示例命令:

# 替换原注释的命令为以下内容
comando = 'New-ADUser -name "sales user" -GivenName Sales -Surname USER -SamAccountName SalesUser -UserPrincipalName saleuser@corp.lan'
enviarComando(comando)

如果未修改服务端默认调用逻辑,客户端需要显式指定调用PowerShell:

comando = 'powershell -Command "New-ADUser -name \'sales user\' -GivenName Sales -Surname USER -SamAccountName SalesUser -UserPrincipalName saleuser@corp.lan"'
enviarComando(comando)

3. 注意事项

  • 确保虚拟机环境已安装Active Directory PowerShell模块,保证AD命令可正常执行
  • 命令中的引号需正确转义,避免语法错误
  • 建议服务端返回执行结果,客户端可根据返回值判断命令执行状态

内容的提问来源于stack exchange,提问作者Cuervo 616

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:42:57