Running PowerShell Script from Python

11,942

Solution 1

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

Solution 2

You can use subprocess.run and need PIPE and shell. The following code worked for me:

import subprocess
result = subprocess.run([r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe', r'C:\Users\(correct subfolders)\TEST.ps1'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
print(result)

Printing the result can give you the return value like if the command was successfully executed. If you want to extract the result value, you can do,

print(result.stdout.decode('utf-8'))
Share:
11,942
spYder
Author by

spYder

Updated on June 04, 2022

Comments

  • spYder
    spYder almost 2 years

    I'm trying to run a Powershell Script ( check below ) First remark, my Powershell script, when running with Powershell works fine, giving the expected result ( closing all open folders ) , but I have to call this from a Python script, therefore I tried using subprocess.Popen, but I'm having the error : "io.UnsupportedOperation: fileno"

    Tried several different things already, but the solutions suggested aren't working.

    I'm trying to call the following Powershell Script :

    $shell = New-Object -ComObject Shell.Application 
    $shell.Windows() | Format-Table LocationName, LocationURL 
    $window = $shell.Windows() 
    $window | ForEach-Object { $_.Quit() }
    

    The idea is to close all the open folders, and directly running with Powershell works as expected.

    Then I tried to call this script from Python :

    p = subprocess.Popen(['powershell.exe', 'C:\\Users\\(correct subfolders)\\TEST.ps1'])
    

    or

    p = subprocess.Popen(['C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe', 'C:\\Users\\(correct subfolders)\\TEST.ps1'])
    

    and they don't return errors, a cmd window opens, but nothing happens. Then I tried the following :

    p = subprocess.Popen(['powershell.exe', 'C:\\Users\\(correct subfolders)\\TEST.ps1'], stdout=sys.stdout)
    

    But I have the following error ( check below )

    File "<pyshell#15>", line 1, in <module>
        p = subprocess.Popen(['powershell.exe', 'C:\\Users\\FernanP\\Desktop\\TEST.ps1'], stdout=sys.stdout)
      File "C:\Users\FernanP\AppData\Local\Programs\Python\Python36-32\lib\subprocess.py", line 667, in __init__
        errread, errwrite) = self._get_handles(stdin, stdout, stderr)
      File "C:\Users\FernanP\AppData\Local\Programs\Python\Python36-32\lib\subprocess.py", line 922, in _get_handles
        c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
    io.UnsupportedOperation: fileno
    

    I looked into similar Questions here, and people said about the Pillow version, but I'm currently using 6.1.0, so it should not be a problem.

    Therefore, either an equivalent to the powershell script directly in Python would be enough, or a way to deal with this issue. Hope I informed sufficiently. KR

  • spYder
    spYder almost 5 years
    Thanks for the help, indeed I'm not having the error anymore, so that part is fixed. BUT.... it does nothing... It just works when I click the powershell script with the right button "run with powershell". No idea why
  • spYder
    spYder almost 5 years
    hanks for the help, indeed I'm not having the error anymore, so that part is fixed. BUT.... it does nothing... It just works ( delete the open folders ) when I click the powershell script with the right button "run with powershell".
  • Gravity Mass
    Gravity Mass almost 5 years
    @aranhaplf I used the same function as the solution that you selected man!
  • spYder
    spYder almost 5 years
    Managed to run using just the "commandline_options " in the end, Thanks for the help!
  • Ryan Harris
    Ryan Harris almost 4 years
    This worked for me after I realized how to use it. Since this is a class, you need to either import/call it from another script or you could add the following script to the end of this script to see the responses directly: ``` if name == "main": response = Utility.run_ftp_upload_powershell_script(ps_script_path) print(response) ```