Python Module_subprocess_调用 Powershell

目录

前言

使用Python内建的subprocess模块,能够实现外部程序的调用。如果你的工作环境是Windows系统,那么Python+Powershell的组合会为你的工作带来极大的便利。本篇介绍一个使用Python做数据处理,Powershell做系统调用的例子。

Powershell call Python

首先在Windows Server 2012 R2中使用Powershell脚本做数据收集,并存放到一个文件中。

#fileName = hd.ps1
#function for countdown
Function Countdown($number,$title,$text1,$text2='Pls Call Jmilk')
{
    Write-Host "Exit the Script after $number seconds" -ForegroundColor Red
    $Countdown = $number
    for($PercentComplete = $Countdown; $PercentComplete -ge 0; $PercentComplete--)
    {
        Write-Progress -Activity $title -Status $text1 -CurrentOperation $text2 -SecondsRemaining $PercentComplete ; 
        Sleep -Seconds 1;
    }
}#End Function Countdown

Write-Host "Welcome to use the script to create table for HI & OFR nodes status" -ForegroundColor Cyan
Write-Host "Building the file hd.txt...Pls be patient.The script will be auto-Exit after created the hd.txt file" -ForegroundColor Yellow

#Change the rdtools path
$rdtoolsPath = 'E:\Users\userName\rdtools'
cd $rdtoolsPath

$cmd = 'commands'  #commands of Data-Collection 因为保密条约不能将内部指令对外 

cmd /c $cmd | Out-File -FilePath E:\Users\userName\Desktop\hd.txt  
#在powershell里调用了别的Shell所以需要使用cmd指令来实现环境变量的传递
#Out-File 将数据导出到文件

Write-Host 'Build Done' -ForegroundColor Green

#Powershell call python
Start-Process python E:\Users\userName\Desktop\hd.py 
#在收集完数据后调用Python做数据处理

#结束并推出Powershell
Countdown 60 'Hd.ps1' 'Exiting...' 'Pls go to the next step!' 

Python call Powershell

主要使用了subprocess模块,subproocess的详细介绍,点击这里

#coding:utf8
#FileName=hd.py

import os
import codecs
from openpyxl.workbook import Workbook
from openpyxl.writer.excel import ExcelWriter
from openpyxl.cell import get_column_letter
from openpyxl.cell import Cell
from openpyxl import Workbook
from openpyxl import load_workbook
import subprocess

#读取数据收集文件
def readFile(fileUrl):
    """Read the file and return the file content"""
    try:
        #unicode file
        fileObject = codecs.open(fileUrl,'r',encoding='utf-16')
    except unicodeDecodeError:
        print "Pls check the encoding for hd.txt whether [unicode]"
    else:
        print("Unspecified Error,Pls call Jmilk")

    try:
        fileContent = fileObject.readlines()
    finally:
        fileObject.close()
    return fileContent

#数据分类函数
def getNodeCountList(readLines):
    """Get the different node status type and change the global variable"""
    i = 0
    for line in readLines:
        lineItem = line.split(':')
        if lineItem[0] == '---- \r\n':
            i += 1
            continue
        if lineItem[0] == '  Node State':
            if lineItem[1] == ' Ready count':
                global ReadyCount
                ReadyCount[i-1] = int(lineItem[2])
            if lineItem[1] == ' OutForRepair count':
                global OutForRepairCount
                OutForRepairCount[i-1] = int(lineItem[2])
            if lineItem[1] == ' HumanInvestigate count':
                global HumanInvestigateCount
                HumanInvestigateCount[i-1] = int(lineItem[2])

#生成Excel表格
def createTable():
    """Create the HI‘s & OFR nodes status table"""
    wb = Workbook()
    ws = wb.worksheets[0]
    ws.title = u"NodeCount"
    for i in list(range(1,26)):
            ws.cell("A"+str(i)).value = '%s' % (cluster[i-1])
            ws.cell("B"+str(i)).value = '%s' % (HumanInvestigateCount[i-1])
            ws.cell("C"+str(i)).value = '%s' % (OutForRepairCount[i-1])
            ws.cell("D"+str(i)).value = '%s' % (ReadyCount[i-1])
            ws.cell("E"+str(i)).value = '%.2f%s' %((float(HumanInvestigateCount[i-1])/(HumanInvestigateCount[i-1]+OutForRepairCount[i-1]+ReadyCount[i-1]))*100,'%')
    wb.save("Hd.xlsx")

#Python call powershell 使用powershell实现发送数据处理邮件  
def python_call_powershell(bodyStr):
        args = [r"C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe","-ExecutionPolicy","Unrestricted",r"E:\Users\userName\Desktop\SendMail.ps1",str(bodyStr)]
        ps = subprocess.Popen(args,stdout=subprocess.PIPE)
        psReturn = ps.stdout.read()
        return psReturn

if __name__ == '__main__':
    #Change to your user name
    user = 'userName'
    cluster = []
    ReadyCount = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    OutForRepairCount = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    HumanInvestigateCount = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
    percentage = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]


    fileUrl = 'E:\\Users\\' + user + '\\Desktop\\hd.txt'
    if os.path.exists(fileUrl):
        readContent = readFile(fileUrl)
        getNodeCountList(readContent)
        #createTable()
    else:
        print('Not exist the file!')
    for i in list(range(0,24)):
                percentage[i] = '%.2f%s' % ((float(HumanInvestigateCount[i])/(HumanInvestigateCount[i]+OutForRepairCount[i]+ReadyCount[i]))*100,'%')
    bodyStr = [x for li in [cluster,HumanInvestigateCount,OutForRepairCount,ReadyCount,percentage] for x in li]
    for index in list(range(0,24)):
                print cluster[index]+'\t',str(HumanInvestigateCount[index])+'\t',str(OutForRepairCount[index])+'\t',str(ReadyCount[index])+'\t'+percentage[index]
    print bodyStr

    callResult = python_call_powershell(bodyStr)
    print callResult

Powershell发送邮件

#fileName = sendMail.ps1

#Set secure password
Function Set-SecurePwd($storage)
{
    $mysecret = 'mailPassword'
    $mysecret | 
    ConvertTo-SecureString -AsPlainText -Force |
    ConvertFrom-SecureString |
    Out-File -FilePath $storage

    $pw = Get-Content $storage | ConvertTo-SecureString

    return $pw
}#End Function Set-SecurePwd

#Sned Email
Function Send-Email($attach,$body)
{
    #$pwd = Set-SecurePwd $storage

    #$cred = New-Object System.Management.Automation.PSCredential "mailUsername",$pwd
    $to = "XXX@XXX.com"
    $from = "XXX@XXX.com"
    $cc = "XXX@XXX.com"
    $sub = "Number of statistics for Node status"
    $smtp = "SMTP.163.COM"

    Send-MailMessage -To $to -From $from -cc $cc -Subject $sub -Body  $body -BodyAsHtml  -SmtpServer $smtp -port 25 -Attachments $attach -Credential $cred -UseSsl 

    if($?)
    {
        Write-Host "Sent Successfully!" -ForegroundColor Green
    }
    else
    {
        Write-Host "Error" -ForegroundColor Red
    }
}#End Function Send-Email


#Mail
$storage = "E:\Users\userName\Desktop\password.txt"
$attach = "E:\Users\userName\Desktop\Hd.xlsx"
$data = $args[0]   #获取Python传递过来的参数
$date = Get-Date
$currentTime = "{0:G}" -f $date.AddHours(16)
$body = "<html>Report of data deal with</html>" #使用HTML的方式来自定义邮件格式

Send-Email $attach $body
Sleep 10

最后

在上面这个例子中,使用Powershell做数据收集,Python做数据处理,最后使用Powershell的内建方法Send-MailMessage来发送数据处理报告。实现的过程非常简便。

上一篇:NRedis-Proxy 高性能Redis 中间件服务原理解析


下一篇:Exchange Server 2016预览版自动化部署及简单体验