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
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
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
How to Use Boto to Stream a File Out of Amazon S3 to Rackspace Cloudfiles
Timedelta to String Type in Pandas Dataframe
Get Files Names Inside a Zip File on Ftp Server Without Downloading Whole Archive
Cx_Freeze Crashing Python 3.7.0
How to Normalize JSON Correctly by Python Pandas
How to Read One Single Line of CSV Data in Python
Get First Row Value of a Given Column
Django Template System, Calling a Function Inside a Model
Differencebetween Join and Merge in Pandas
Pivot String Column on Pyspark Dataframe
How to Pip or Easy_Install Tkinter on Windows
How to Make the Width of the Title Box Span the Entire Plot
How to Check If an Object Is a List or Tuple (But Not String)
Pandas: Resample Timeseries with Groupby
Using Monotonically_Increasing_Id() for Assigning Row Number to Pyspark Dataframe