Skip to content

Instantly share code, notes, and snippets.

@la11111
Created October 30, 2012 23:04
Show Gist options
  • Save la11111/3983667 to your computer and use it in GitHub Desktop.
Save la11111/3983667 to your computer and use it in GitHub Desktop.
Powershellv3 wrapper for IronPython, plus Json - JPosh.py
import clr
import System.Collections
clr.AddReference("System.Management.Automation")
from System.Management.Automation import *
from System.Management.Automation.Runspaces import *
import System.IO
rs_default = RunspaceFactory.CreateRunspace()
rs_default.Open()
System.Management.Automation.Runspaces.Runspace.DefaultRunspace = rs_default
class JPosh(object):
"""
Easily access Powershell (v3) via IronPython.
Uses Json to communicate.
Why do this? To interface with a wsgi-style server and use
Powershell to serve data over the web.
"""
def __init__(self, json=True):
"""
create a new powershell instance.
p = new JPosh() #normal
p = new JPosh(json=False) #return CLR objects instead of json
"""
self.rs = RunspaceFactory.CreateRunspace()
self.rs.Open()
self.ps = PowerShell.Create()
self.ps.Runspace = self.rs
self.script = []
self.json = json
def invoke(self, **kwargs):
"""
p = JPosh()
p.invoke() # run what's in the pipeline
p.invoke("dir ~") # run a command
p.invoke("dir",var="outvar") # save output to a variable in powershell
p.invoke("dir",depth="2") # depth of json nesting (default 1)
p.invoke("dir",props=['name','length']) # filter output to the given
# properties (Select-Object)
"""
params = {'script':None,'var':None,'depth':'1','props':None}
for k in kwargs.keys():
if k in params.keys():
params[k] = kwargs[k]
script = params['script']
print "script: ", script
var = params['var']
print "var:", var
depth = params['depth']
print "depth:", depth
props= params['props']
print "props:", props
if script:
self.script.append(script)
else:
if len(self.script) == 0:
return r'\{\n"error": ["Empty pipeline; need a script to run."]\n\}'
if props:
if type(props) is list and len(props) > 0:
props = ",".join(props)
else:
props = str(props)
props = r' | Select-Object -Property ' + props
else:
props = ""
script = " | ".join(self.script)
if var:
script = '$'+var+' = '+script
if self.json and not var:
s = "".join([
r'$myerr = @(); try{',
script,
props,
' | ConvertTo-Json -Depth ',
str(depth),
' | Out-String} catch {$myerr += $_} if($myerr.Count -gt 0){@{"error" = $myerr} | ConvertTo-Json -Depth 1 | Out-String}'])
else:
s = "".join([
r'$myerr = @(); try{',
script,
props,
'} catch {$myerr += $_} if($myerr.Count -gt 0){@{"error" = $myerr}}'])
self.ps.AddScript(s)
try:
result = self.ps.Invoke()
self.script = []
except Exception as inst:
return '\{\n"error": ["{}"]\n\}'.format(str(inst))
self.script = []
if not self.json:
if not var:
return result
try:
if result.Count == 0:
return r"[]"
else:
ret = []
for r in result:
ret.append(str(r))
return "\n".join(ret)
except Exception as inst:
return str(inst)
def add_script(self, script):
"""
p = JPosh()
p.add_script(r"dir ~")
p.add_script(r'? { $_.name -match "foofile" }')
p.invoke()
#is equivalent to:
p.invoke(r'dir ~ | ? {$_.name -match "foofile"}')
"""
if script and type(script) is str:
self.script.append(script)
r = '\{\n\t"Script added": "{}",\n'.format(script)
r += '\t"current pipeline": "{}\}"\n'.format(" | ".join(self.script))
return r
def get_pipeline(self):
"""
p.get_pipeline() # see what's waiting to be run
"""
r = '{'
r += '\t"current pipeline": "{}"\n'.format(" | ".join(self.script))
r += '}'
return r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment