import json import ssl import sys import urllib.parse import urllib.request HOST = "https://192.168.1.51:8006" CTX = ssl.create_default_context() CTX.check_hostname = False CTX.verify_mode = ssl.CERT_NONE def api(path, data=None, ticket=None, csrf=None, json_body=None): body = None headers = {} if json_body is not None: body = json.dumps(json_body).encode() headers["Content-Type"] = "application/json" elif data is not None: body = urllib.parse.urlencode(data).encode() req = urllib.request.Request(HOST + path, body, headers) if ticket: req.add_header("Cookie", "PVEAuthCookie=" + ticket) if csrf: req.add_header("CSRFPreventionToken", csrf) with urllib.request.urlopen(req, context=CTX, timeout=40) as r: raw = r.read() return json.loads(raw)["data"] if raw else None def agent(ticket, csrf, command, timeout=90): r = api("/api2/json/nodes/starhe/qemu/100/agent/exec", json_body={"command": command}, ticket=ticket, csrf=csrf) pid = r["pid"] for _ in range(timeout // 2): import time time.sleep(2) st = api("/api2/json/nodes/starhe/qemu/100/agent/exec-status?pid=%d" % pid, ticket=ticket) if st.get("exited"): return st.get("out-data") or "", st.get("err-data") or "" return "TIMEOUT", "" if __name__ == "__main__": d = api("/api2/json/access/ticket", {"username": "root@pam", "password": "yx66668888"}) ticket, csrf = d["ticket"], d["CSRFPreventionToken"] ps = sys.argv[1] out, err = agent(ticket, csrf, [ "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe", "-NoProfile", "-Command", ps]) print(out) if err: print("ERR:", err[:300])