Boom
Boom

Reputation: 25

How pass variable from Python to Powershell

How to change this command in Powershell to work with Python:

$route = Get-NetRoute | Where-Object { $_.NextHop -eq $defaultGateway }
$ip, $mask = $route.DestinationPrefix -split '/'

I have tried something like this, but it doesn't work:

route = subprocess.run(f"powershell.exe Get-NetRoute | Where-Object {{ $_.NextHop -eq '{default_gateway}' }}", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).decode("utf-8")
ip, mask = route.split("/")[0], route.split("/")[1]

Upvotes: 1

Views: 649

Answers (1)

zett42
zett42

Reputation: 27806

Here is a working solution:

import subprocess, base64

default_gateway = "1.2.3.4"  # Replace with your value

# The PowerShell script, as formatted triple-single-quoted string which 
# can span multiple lines.
command = f'''
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Get-NetRoute | Where-Object NextHop -eq '{default_gateway}' | ForEach-Object DestinationPrefix
'''

# Encode the command in UTF-16 LE, then Base-64 for PowerShell
commandBase64 = base64.b64encode( command.encode("utf-16-le") ).decode()

# Run the encoded PowerShell command and capture its output
proc = subprocess.run( f"powershell.exe -EncodedCommand {commandBase64}", capture_output=True, encoding="utf-8", shell=True)

if proc.returncode == 0:
    ip, mask = proc.stdout.strip().split("/")
    print(f"IP: {ip}, mask: {mask}")
else:
    print(f"ERROR: {proc.stderr}")
  • The safest way to call PowerShell from another language like Python is to use the powershell.exe -EncodedCommand parameter, which accepts a Base-64 encoded Unicode string. The Unicode encoding must be UTF-16 LE. This avoids all the hassles with parameter quoting.
  • [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 ensures that PowerShell actually outputs UTF-8.
  • ForEach-Object DestinationPrefix outputs the value of the DestinationPrefix property only. Otherwise you would get the formatted, for-display-only output of Get-NetRoute, which is not suitable for programmatic processing.
  • subprocess.run() returns a CompletedProcess object
    • The stdout property contains the actual output of PowerShell.
    • Likewise, the stderr property contains the error output of PowerShell.
    • Make sure to check the returncode property to determine success or failure of PowerShell.

Upvotes: 2

Related Questions