0

I have the following code. It connects to a Service Now Instance. Fetches Incident for particular server. The Incident has details for Printer Creation. ip is in record['user_input'],printer name is in record['u_string_full_utf8_1']. What I would like to achieve is pass these as arguments to powershell so that it can run the Printer Create script. The arguments passed in the below code works. But I am not sure how to pass arguments in the middle of it.

import pysnow
import subprocess
import os

# Create client object
s = pysnow.Client(instance='instance', user='admin', password='password')

# Get all incidents
r = s.query('incident', query={'cmdb_ci':'a28cba7a4fb4030028f7fd218110c7f5'})

# order by 'created_on' descending, then iterate over the result and print out number
for record in r.get_multiple(order_by=['-created_on']):
    print(record['cmdb_ci'])

psxmlgen = subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
                            "Invoke-Command -ComputerName SERVER01 -FilePath 'C:\Users\testuser\Documents\Scripts\PrinterCreate.ps1' -ArgumentList '10.2.3.2','PS Driver for Universal Print','TESTPRINTER' -Credential $cred"], cwd=os.getcwd())
result = psxmlgen.wait()

I checked the existing resources but was unable to figure out how to pass it in the middle.

Any help would be appreciated.

Using Python2.7

Anti21
  • 850
  • 1
  • 7
  • 16
  • You may want to prefix an 'r' in the second argument to the popen. – Addy Aug 29 '17 at 17:18
  • Got it to work. I agree there should be r but its working without it and I think if ain't broke then don't fix it. – Anti21 Aug 29 '17 at 17:22

2 Answers2

0

There are two similar questions which you can reference. Popen gives you access to stdin of a interactive process. You may want to refer to

Running an interactive command from within python

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

both may help. I am not sure if powershell exposes it's stdin and stdout as normal native processes in windows.

Addy
  • 731
  • 5
  • 15
0

Got it to work with the following:

psxmlgen = subprocess.Popen([r'C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe',
                            "Invoke-Command -ComputerName Server01 -FilePath 'C:\Users\smehta30\Documents\Scripts\PrinterCreate.ps1' -ArgumentList "+record['user_input']+",'PS Driver for Universal Print',"+record['u_string_full_utf8_1']+" -Credential $cred"], cwd=os.getcwd())
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Anti21
  • 850
  • 1
  • 7
  • 16
  • That works, but it's dangerous unless you trust your inputs -- values in `record` containing literal double-quotes could exit their escaping to perform injection attacks, providing arbitrary powershell code. – Charles Duffy Aug 29 '17 at 17:23
  • (I could tell you how to avoid the same problem in bash, but unfortunately, with PowerShell I'm no help; that said, the same problem clearly exists in both places). – Charles Duffy Aug 29 '17 at 17:24
  • (As an aside -- the current working directory of the parent should be default for the child; does `cwd=` really change anything?) – Charles Duffy Aug 29 '17 at 17:24
  • First of all thanks for the edit. My bad. I am currently working for a prototype to display Servicenow automated printer creation queries. It is in very early stage. I need to learn how to avoid injection. Can you please provide the Bash code. Maybe I can implement something through here. Hmm would have to limit Input at Request creation end. Will look into it. – Anti21 Aug 29 '17 at 17:33
  • so, in bash, you'd write `subprocess.Popen(['sh', '-c', 'code using "$1" and "$2"', '_', record['user_input'], record['u_string_full_utf8_1'])` -- that way the values are passed to the shell interpreter out-of-band from code and substituted later. – Charles Duffy Aug 29 '17 at 17:36
  • (Frankly, if there isn't already a StackOverflow question on how to safely pass variables to PowerShell from Python, it's probably worth asking). – Charles Duffy Aug 29 '17 at 17:37