Created
October 30, 2012 23:04
-
-
Save la11111/3983667 to your computer and use it in GitHub Desktop.
Powershellv3 wrapper for IronPython, plus Json - JPosh.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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