简体   繁体   English

在 python 脚本内运行 powershell 脚本

[英]Run powershell Scripts INSIDE python script

I am trying to run a powershell script with in a python script.我正在尝试在 python 脚本中运行 powershell 脚本。 My idea was to do something like:我的想法是做类似的事情:

#pythonscript.py


def windowsupdate():

    #Somehow call all of this powershell code within the file

    Write-Host("Installing module PSWindowsUpdate if not already installed... ")
    Install-Module PSWindowsUpdate
    Write-Host("PSWindowsUpdate is now installed.")
    Write-Host("")
    Write-Host("Getting Windows Updates...")
    Import-Module PSWindowsUpdate
    $updates = Invoke-Command -ScriptBlock {Get-Wulist -verbose}
    $updatenumber = ($updates.kb).count
    if ($null -ne $updates){
        Get-WindowsUpdate -AcceptAll -Install | Out-File C:\PSWindowsUpdate.log
        do {$updatestatus = Get-Content c:\PSWindowsUpdate.log
            "Currently processing the following update:"
            Get-Content c:\PSWindowsUpdate.log | select-object -last 1
            Start-Sleep -Seconds 10
            $ErrorActionPreference = 'SilentlyContinue'
            $installednumber = ([regex]::Matches($updatestatus, "Installed" )).count
            $ErrorActionPreference = ‘Continue’
        }until ( $installednumber -eq $updatenumber)
    }
    Remove-Item -path C:\PSWindowsUpdate.log


#call function
windowsupdate() #opens up a powershell window and goes through the code then when completed close

If there is any way to do something similar to this without the need of creating a seperate powershell file that would be the best case scenario.如果有任何方法可以做类似的事情而不需要创建一个单独的 powershell 文件,那将是最好的情况。 If not and it needs to be in its' own file that is okay too, and if it needs to be this way, how would I call the function from within python?如果不是,它也需要在自己的文件中也可以,如果需要这样,我将如何从 python 中调用 function?

Any help is greatly appreciated!任何帮助是极大的赞赏!

I believe the easiest way to achieve what you are trying to do is by using subprocess.Popen .我相信实现您想要做的最简单的方法是使用subprocess.Popen This function can call command-line/terminal commands from within a python script.这个 function 可以从 python 脚本中调用命令行/终端命令。 It can be used like this:它可以这样使用:

import subprocess
subprocess.Popen()

Where your command is placed between the two brackets.您的命令放在两个括号之间的位置。

A Powershell command can be executed from the command line using the command line (see this ):可以使用命令行从命令行执行 Powershell 命令(请参阅):

powershell -command ""

Where your command is between the two quotation marks.您的命令在两个引号之间的位置。 Since subprocess.Popen can call a command line command, you can call a powershell command through it.由于 subprocess.Popen 可以调用命令行命令,所以可以通过它调用 powershell 命令。 Here's an example using your first ps command:这是使用您的第一个 ps 命令的示例:

import subprocess
command='Write-Host("Installing module PSWindowsUpdate if not already installed...")'
subprocess.Popen('powershell -command '+"'"+command+"'")

Alternatively, you can use subprocess.run to execute the command.或者,您可以使用 subprocess.run 来执行命令。 The only difference it that subprocess.run executes the command and then your script continues, while subprocess.Popen runs the command while your script continues.唯一的区别是 subprocess.run 执行命令然后你的脚本继续,而 subprocess.Popen 在你的脚本继续时运行命令。

If you want the command to do it's thing silently (eg. without opening powershell), pass stdout=subprocess.PIPE, shell=True to subprocess.Popen with your command.如果您希望命令以静默方式执行此操作(例如,不打开 powershell),请使用您的命令将stdout=subprocess.PIPE, shell=True传递给subprocess.Popen You can print the output directly with something like:您可以使用以下内容直接打印 output:

stdout_value = process.communicate()[0]
print (stdout_value)

Where process is your subprocess.Popen() object.其中 process 是您的 subprocess.Popen() object。 Now onto completing all your commands:现在完成所有命令:

If you want to print the output of your commands, you can use:如果要打印命令的 output,可以使用:

import subprocess
def call_command(command):
    process=subprocess.Popen('powershell -command '+"'"+command+"'", stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
    stdout_value = process.communicate()[0]
    return stdout_value

print(call_command('Write-Host("Installing module PSWindowsUpdate if not already installed... ")'))

Simply use call_command for each command and you're done.只需对每个命令使用 call_command 即可。 You will see some extra characters in the output (eg. \n or \r ), these are included by default for powershell to actually create a newline, etc. Basically, if you don't want them, you can remove them yourself (eg. string.replace('\n', '') )您将在 output 中看到一些额外的字符(例如\n\r ),默认情况下包含这些字符,以便 powershell 实际创建换行符等。基本上,如果您不想要它们,您可以自己删除它们(例如string.replace('\n', '') )

If you want to actually open powershell, calling subprocess.Popen for each line will open one powershell terminal per line, which I don't think you'd want.如果您想实际打开 powershell,则为每一行调用subprocess.Popen将为每行打开一个 powershell 终端,我认为您不会想要。 I would take some more trickery to call all the commands in one powershell terminal:我会采取一些技巧来调用一个 powershell 终端中的所有命令:

One thing you could do is put your powershell commands in a file with the.ps1 file extension.you can then call it with subprocess.Popen and run it altogether in a powershell terminal.您可以做的一件事是将 powershell 命令放在文件扩展名为 .ps1 的文件中。然后您可以使用 subprocess.Popen 调用它并在 powershell 终端中完全运行它。 For example:例如:

import subprocess
subprocess.Popen("C://path/to/your/file/myfile.ps1")

But you'd have to have another file, not just your python script.但是你必须有另一个文件,而不仅仅是你的 python 脚本。

Or:或者:

your could combine all your commands into one:您可以将所有命令合并为一个:

commands = """ Write-Host("Installing module PSWindowsUpdate if not already installed... ")
Install-Module PSWindowsUpdate
Write-Host("PSWindowsUpdate is now installed.")
Write-Host("")
Write-Host("Getting Windows Updates...")
Import-Module PSWindowsUpdate
$updates = Invoke-Command -ScriptBlock {Get-Wulist -verbose}
$updatenumber = ($updates.kb).count
if ($null -ne $updates){
    Get-WindowsUpdate -AcceptAll -Install | Out-File C:\PSWindowsUpdate.log
    do {$updatestatus = Get-Content c:\PSWindowsUpdate.log
        "Currently processing the following update:"
        Get-Content c:\PSWindowsUpdate.log | select-object -last 1
        Start-Sleep -Seconds 10
        $ErrorActionPreference = 'SilentlyContinue'
        $installednumber = ([regex]::Matches($updatestatus, "Installed" )).count
        $ErrorActionPreference = ‘Continue’
    }until ( $installednumber -eq $updatenumber)
}
Remove-Item -path C:\PSWindowsUpdate.log"""

Then run it with subprocess:然后用子进程运行它:

import subprocess;
subprocess.Popen(["powershell","& {" + command+ "}"])
# or subprocess.Popen('powershell -command' + command)

To print it in the terminal instead of opening powershell, use:要在终端中打印而不是打开 powershell,请使用:

import subprocess;
subprocess.Popen(["powershell","& {" + command+ "}"], stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
stdout_value = process.communicate()[0]
return stdout_value

That should be it!应该是这样!

The following code should work, though I didn't test it:以下代码应该可以工作,尽管我没有测试它:

def windowsupdate():
    pscommand = ' Write-Host("Installing module PSWindowsUpdate if not already installed... ")
    Install-Module PSWindowsUpdate
    Write-Host("PSWindowsUpdate is now installed.")
    Write-Host("")
    Write-Host("Getting Windows Updates...")
    Import-Module PSWindowsUpdate
    $updates = Invoke-Command -ScriptBlock {Get-Wulist -verbose}
    $updatenumber = ($updates.kb).count
    if ($null -ne $updates){
        Get-WindowsUpdate -AcceptAll -Install | Out-File C:\PSWindowsUpdate.log
        do {$updatestatus = Get-Content c:\PSWindowsUpdate.log
            "Currently processing the following update:"
            Get-Content c:\PSWindowsUpdate.log | select-object -last 1
            Start-Sleep -Seconds 10
            $ErrorActionPreference = 'SilentlyContinue'
            $installednumber = ([regex]::Matches($updatestatus, "Installed" )).count
            $ErrorActionPreference = ‘Continue’
        }until ( $installednumber -eq $updatenumber)
    }
    Remove-Item -path C:\PSWindowsUpdate.log'

    import subprocess;
    process=subprocess.Popen(["powershell","& {" + pscommand + "}"],stdout=subprocess.PIPE);
    result=process.communicate()[0]
    print (result)

windowsupdate()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM