Run Powershell Function from Python Script

How to run a Powershell function through a Python script

Your parameter construction is off. You want to run the following commandline in PowerShell:

. "./1337Export.ps1"; & export

which basically means "dot-source (IOW import) the script 1337Export.ps1 from the current working directory, then call (&) the function export".

The cleanest way to do this is to put the statement in a scriptblock:

&{. "./1337Export.ps1"; & export}

and pass that scriptblock as a single argument, so your Python statement should look like this:

subprocess.call(["C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\powershell.exe", '-Command', '&{. "./1337Export.ps1"; & export}'])

Of course you need to make sure that 1337Export.ps1 actually exists in the current working directory when you execute the Python script.

Run powershell Scripts INSIDE python script

I believe the easiest way to achieve what you are trying to do is by using subprocess.Popen. This function can call command-line/terminal commands from within a python script. 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 -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. Here's an example using your first ps command:

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

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.
You can print the output directly with something like:

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

Where process is your subprocess.Popen() object.
Now onto completing all your commands:

If you want to print the output of your commands, you can use:

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

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. I would take some more trickery to call all the commands in one powershell terminal:

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

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:

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!

How to pass a string variable to a PowerShell function from python

Using str.format the code could be as follows. Note, when calling the PowerShell CLI with the -Command parameter, there is no need to use & {...}, PowerShell will interpret the string as the command you want to execute. There is also no need for & (call operator) when calling your function (check) and lastly, function parameters in PowerShell are either named (-Color) or positional, don't use (...) to wrap your parameters.

import subprocess
color = "blue"
subprocess.call([ 'powershell.exe', '-c', '. ./colortest.ps1; check -color {0}'.format(color) ])

Running powershell script within python script, how to make python print the powershell output while it is running

  1. Make sure you can run powershell scripts (it is disabled by default). Likely you have already done this. http://technet.microsoft.com/en-us/library/ee176949.aspx

    Set-ExecutionPolicy RemoteSigned
  2. Run this python script on your powershell script helloworld.py:

    # -*- coding: iso-8859-1 -*-
    import subprocess, sys

    p = subprocess.Popen(["powershell.exe",
    "C:\\Users\\USER\\Desktop\\helloworld.ps1"],
    stdout=sys.stdout)
    p.communicate()

This code is based on python3.4 (or any 3.x series interpreter), though it should work on python2.x series as well.

C:\Users\MacEwin\Desktop>python helloworld.py
Hello World

Running a python script via Powershell script

Assuming that python is already in your path variables you can just call a python script like this:

python C:\User\PythonScripts\TestFile.py

Running PowerShell Script from Python

Here I have created my own function to run any powershell script with its parameters

import subprocess  # IMPORT FOR SUB PROCESS . RUN METHOD

POWERSHELL_PATH = "powershell.exe" # POWERSHELL EXE PATH
ps_script_path = "C:\\PowershellScripts\\FTP_UPLOAD.PS1" # YOUR POWERSHELL FILE PATH

class Utility: # SHARED CLASS TO USE IN OUR PROJECT

@staticmethod # STATIC METHOD DEFINITION
def run_ftp_upload_powershell_script(script_path, *params): # SCRIPT PATH = POWERSHELL SCRIPT PATH, PARAM = POWERSHELL SCRIPT PARAMETERS ( IF ANY )

commandline_options = [POWERSHELL_PATH, '-ExecutionPolicy', 'Unrestricted', script_path] # ADD POWERSHELL EXE AND EXECUTION POLICY TO COMMAND VARIABLE
for param in params: # LOOP FOR EACH PARAMETER FROM ARRAY
commandline_options.append("'" + param + "'") # APPEND YOUR FOR POWERSHELL SCRIPT

process_result = subprocess.run(commandline_options, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True) # CALL PROCESS

print(process_result.returncode) # PRINT RETURN CODE OF PROCESS 0 = SUCCESS, NON-ZERO = FAIL
print(process_result.stdout) # PRINT STANDARD OUTPUT FROM POWERSHELL
print(process_result.stderr) # PRINT STANDARD ERROR FROM POWERSHELL ( IF ANY OTHERWISE ITS NULL|NONE )

if process_result.returncode == 0: # COMPARING RESULT
Message = "Success !"
else:
Message = "Error Occurred !"

return Message # RETURN MESSAGE


Related Topics



Leave a reply



Submit