Python实现管理员权限运行CMD指令

一、subprocess.Popen

 Python执行 cmd指令属于外部调用,subprocess.Popen 方法即可,实现如下:

# !/usr/bin/python3
# coding: utf-8
import subprocess


def command(cmd, timeout=1800000):
    try:
        sp = subprocess.Popen(
            cmd,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        print("[PID] %s: %s" % (sp.pid, cmd))
        sp.wait(timeout=timeout)

        stderr = str(sp.stderr.read().decode("gbk")).strip()
        stdout = str(sp.stdout.read().decode("gbk")).strip()
        if "" != stderr:
            raise Exception(stderr)
        if stdout.find("失败") > -1:
            raise Exception(stdout)
    except Exception as e:
        raise e

参考资料

《Python脚本以管理员权限运行》

 

二、bat 获取管理员权限

但当系统权限不足时,肿么办?

先看传统 bat的处理方式:

@echo off 
echo get admin rights
cacls.exe "%SystemDrive%\System Volume Information" >nul 2>nul
if %errorlevel%==0 goto isAdmin

if exist "%temp%\getAdmin.vbs" del /f /q "%temp%\getAdmin.vbs"
echo Set shell = CreateObject^("Shell.Application"^)>"%temp%\getAdmin.vbs"
echo shell.ShellExecute "%~s0","","","runas",1 >>"%temp%\getAdmin.vbs"
echo WScript.Quit >>"%temp%\getAdmin.vbs"
"%temp%\getAdmin.vbs" /f
if exist "%temp%\getAdmin.vbs" del /f /q "%temp%\getAdmin.vbs"
exit

:isAdmin
sc stop WebClient
pause

这段代码的主要流程:

1、调用 cacls.exe 程序查询“系统卷标信息”,验证是否具备管理员权限

2、不具备管理员权限时创建getAdmin.vbs脚本,脚本内容如下

Set shell = CreateObject("Shell.Application")
shell.ShellExecute "%~s0","","","runas",1
WScript.Quit

3、强制执行这个 getAdmin.vbs脚本

4、删除 getAdmin.vbs脚本文件 并退出

 

那么getAdmin.vbs脚本又做了什么呢?

脚本内容只有三行

① Set shell = CreateObject("Shell.Application") 创建 Shell对象

② 以管理员权限运行当前脚本(bat脚本),其中参数 "%~s0" 是当前脚本的绝对路径,"runas" 是 shell指令 runas,"1"是管理员权限

③ 脚本退出

 

总体流程就是 bat在权限不足情况下创建了一个 vb脚本,让 vb脚本反向调用bat

 

三、Python 的曲线救国

想要做一个工具类,可以实现任意 cmd指令的管理员权限下的执行

挖坑式的自造轮子:

① 创建一个空的 bat文件,动态写入cmd指令

② 创建一个固定内容的 vb脚本

③ Python调用 vb脚本, vb 调用 bat

 

1、文件结构

 

2、../tool/script/shell.vbs

cwd = CreateObject("Scripting.FileSystemObject").GetFile(Wscript.ScriptFullName).ParentFolder.Path
path = cwd & "\cmd.bat"

Set shell = CreateObject("Shell.Application")
shell.ShellExecute path,"","","runas",1

WScript.Quit

参考资料

《VBS获取当前路径的两个方法》 

《VBS中字符串拼接 & 与 + 的区别》

 

3、方法实现

 工具方法 runAdmin 实现代码如下:

注意:因 cmd指令是动态写入文件,固 runAdmin 方法不支持并发,调用时要加线程锁

# !/usr/bin/python3
# coding: utf-8
import os
import subprocess
import traceback


def runAdmin(cmd, timeout=1800000):
    f = None
    try:
        bat = os.getcwd() + r"\tool\script\cmd.bat"
        f = open(bat, 'w')
        f.write(cmd)
    except Exception as e:
        traceback.print_exc()
        raise e
    finally:
        if f:
            f.close()

    try:
        shell = os.getcwd() + r"\tool\script\shell.vbs"
        sp = subprocess.Popen(
            shell,
            shell=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        print("[PID] %s: %s" % (sp.pid, cmd))
        sp.wait(timeout=timeout)

        stderr = str(sp.stderr.read().decode("gbk")).strip()
        stdout = str(sp.stdout.read().decode("gbk")).strip()
        if "" != stderr:
            raise Exception(stderr)
        if stdout.find("失败") > -1:
            raise Exception(stdout)
    except Exception as e:
        raise e

 

 

如有纰漏,敬请@

 

 

 

  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值