Запустить сценарии powershell INSIDE python - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь запустить скрипт powershell в python скрипте. Моя идея заключалась в том, чтобы сделать что-то вроде:

#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

Если есть какой-то способ сделать что-то подобное без необходимости создания отдельного файла powershell, который был бы наилучшим сценарием. Если нет, и он должен быть в своем собственном файле, который тоже в порядке, и если он должен быть таким, как бы я вызывал функцию изнутри python?

Любая помощь очень ценится!

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

Я считаю, что самый простой способ достичь того, что вы пытаетесь сделать, - это использовать subprocess.Popen. Эта функция может вызывать команды командной строки / терминала из скрипта python. Его можно использовать следующим образом:

import subprocess
subprocess.Popen()

Где ваша команда помещена между двумя скобками.

Команду Powershell можно выполнить из командной строки с помощью командной строки (см. this ):

powershell -command ""

Где ваша команда находится между двумя кавычками. Поскольку subprocess.Popen может вызывать команду командной строки, вы можете вызывать команду powershell через нее. Вот пример использования вашей первой команды ps:

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

Кроме того, вы можете использовать subprocess.run для выполнения команды. Единственное отличие состоит в том, что subprocess.run выполняет команду, а затем ваш сценарий продолжается, а subprocess.Popen запускает команду, а ваш сценарий продолжается.

Если вы хотите, чтобы команда выполняла свои действия без вывода сообщений (например, без открытия powershell), передайте stdout=subprocess.PIPE, shell=True на subprocess.Popen с вашей командой. Вы можете распечатать вывод непосредственно с помощью чего-то вроде:

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

Где process - это ваш объект subprocess.Popen (). Теперь приступим к выполнению всех ваших команд:

Если вы хотите напечатать вывод ваших команд, вы можете использовать:

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... ")'))

Просто используйте call_command для каждой команды, и все готово. Вы увидите некоторые дополнительные символы в выводе (например, \n или \r), они включены по умолчанию для powershell для фактического создания новой строки и т. Д. c. По сути, если вы не хотите их использовать, вы можете удалить их самостоятельно (например, string.replace('\n', ''))

Если вы действительно хотите открыть powershell, вызов subprocess.Popen для каждой строки откроет один терминал powershell на строку. что я не думаю, что вы хотели бы. Я бы взял еще немного хитрости, чтобы вызвать все команды в одном терминале PowerShell:

Одна вещь, которую вы могли бы сделать, это поместить ваши команды PowerShell в файл с расширением .ps1. Затем вы можете вызывать его с помощью подпроцесса. Откройте и запустите его в терминале PowerShell. Например:

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

Но вам понадобится другой файл, а не только ваш python скрипт.

Или:

вы можете объединить все ваши команды в один:

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"""

Затем запустите его с подпроцессом:

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

Чтобы распечатать его в терминале вместо открытия powershell, используйте:

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

That должно быть!

0 голосов
/ 03 апреля 2020

Следующий код должен работать, хотя я его не тестировал:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...