1

I keep trying to run this piece of code but everytime I print, it seems to net me nothing in regards to what I see with my output.

p = subprocess.run(["powershell.exe", "C://Users//xxxxx//Documents//betterNetstatOut.ps1"], shell=True, capture_output=True, text=True)

output = p.stdout
print(output)

My PowerShell command is a very basic println at this point:

Write-Output 'Hello world'

but running print on my out seems to return an empty string. I also tried running subprocess.Popen() and subprocess.call() and they all seem to return an empty string instead of 'Hello World'. Eventually, I would like to parse many lines and move them to a dataframe but I am stuck on this one line first.

Zarif Rahman
  • 79
  • 1
  • 8

2 Answers2

2

Your PowerShell command likely produced only stderr output, which is why you saw no output given that you only printed p.stdout - also printing p.stderr would surface any stderr output (which typically contains error messages).

Assuming your script file path is correct, the likeliest explanation for receiving only stderr output is that your effective PowerShell execution policy prevents execution of scripts (.ps1 files), which you can bypass with -ExecutionPolicy Bypass in a call to the Windows PowerShell CLI, powershell.exe.

Additionally:

  • There's no need for double slashes (//) in your script path; while it still works, / is sufficient.

  • It's better to use the -File parameter rather than -Command (which is implied) for invoking scripts via the PowerShell CLI - see this answer for more information.

  • For a predictably execution environment and to avoid unnecessary overhead from loading profiles, using -NoProfile is advisable.

  • You don't need shell=True, which, due to calling via cmd.exe, only slows your command down.

To put it all together:

import subprocess

p = subprocess.run(
     ["powershell.exe", 
      "-NoProfile", 
      "-ExecutionPolicy", "Bypass", 
      "-File", "C:/Users/xxxxx/Documents/betterNetstatOut.ps1"], 
     capture_output=True, text=True
    )

print('--- stdout --')
print(p.stdout)
print('--- stderr --')
print(p.stderr)
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Follow-up question: Is there a way to handle the PowerShell command without looking for a .ps1 file? Just run 'netstat -a' directly from the subprocess.run() function? – Zarif Rahman Sep 07 '22 at 18:54
  • 1
    @ZarifRahman, use `-Command` instead of `-File`, and pass `'netstat -a'` to it. If you need a comprehensive overview of the PowerShell CLI, see [this answer](https://stackoverflow.com/a/68136129/45375). That said, if _all_ you need is a call to `netstat`, you don't need PowerShell at all - just use `'netstat.exe'` instead of `"powershell.exe"` and `'-a'` as its argument. – mklement0 Sep 07 '22 at 19:51
  • Thank you for the example! But 'netstat -a' is just an example I wanted to run through. – Zarif Rahman Sep 07 '22 at 21:59
  • 1
    @ZarifRahman, understood. Then use the `-Command` approach. – mklement0 Sep 07 '22 at 22:00
  • I am running this piece of code great within my terminal but running it as an executable causes the PowerShell window to keep opening and closing. I am using PyInstaller to create my exe and was wondering if there was a way to suppress the powershell window from showing up? – Zarif Rahman Sep 15 '22 at 18:31
  • I see that you've created a follow-up question about launching PowerShell _invisibly_ at https://stackoverflow.com/q/73735991/45375 – mklement0 Sep 15 '22 at 20:54
  • 1
    Yup! Haha, from my research, this issue seemed a little bit more complicated than in this original question. Didn't think this would be a bigger deal when posting this comment but slowly realized what is going on behind the scenes. – Zarif Rahman Sep 15 '22 at 20:58
-1
import subprocess

p = subprocess.run(["powershell.exe", "powershell -ExecutionPolicy Bypass -File", "C://Users//xxxxx//Documents//betterNetstatOut.ps1"], shell=True, capture_output=True, text=True)
print(p.stdout)
  • `-ExecutionPolicy Bypass` is a good pointer, but Is the _nesting_ of `powershell.exe` calls in your code a typo? – mklement0 Sep 07 '22 at 22:10