Fork me on GitHub

IronPython整合Windows PowerShell

      Windows PowerShell 是微软为 Windows 环境所开发的 shell 及脚本语言技术,这项全新的技术提供了丰富的控制与自动化的系统管理能力;关于PowerShell参看易学易用的Windows PowerShell 。IronPython也是脚本语言,两种脚本语言的联姻可以解决Windows 系统管理的任务,是系统管理员的必备工具。这里有一篇文章在提醒DBA们要开始学PowerShell   RTFM :http://weblog.infoworld.com/dbunderground/archives/2007/01/rtfm.html

     PowerShell托管的API为IronPython整合PowerShell提供了条件。可以在IronPython直接访问PowerShell,直接利用PowerShell的强大Shell功能。下面的例子演示了IronPython中如何使用PowerShell。

D:\IronPython\Samples\IPPowerShell>ipy -i powershell.py
Run 'dir(shell)' to get a list of available PowerShell commands!
In general, IronPython PowerShell commands are accessed using the form:
shell.get_process("cmd").select(First=2)

>>> shell.dir()
目录: Microsoft.PowerShell.Core\FileSystem::D:\IronPython\Samples\IPPowerShel
l

Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar-- 2006-9-14 14:46 3583 minsysreq.py
-ar-- 2006-9-14 14:44 3136 minsysreq_ps.py
-ar-- 2006-9-11 12:21 6261 powershell.py
-ar-- 2006-9-14 14:51 12911 readme.htm
>>> shell.dir().sort("LastWriteTime",Descending=True).select_object("Name")
Name
----
readme.htm
minsysreq.py
minsysreq_ps.py
powershell.py
>>>

例子代码可以从这里获取:IronPython Sample ,有一个IPPowerShell例子,下载解压后有一个IronPython script文件powershell.py文件。可以在通过在你的IronPython脚本文件中通过使用这个powershell模块来使用PowerShell,当然你要安装PowerShell。

下面我们来一起学习一下powershell.py文件:

# **********************************************************************************
#
# Copyright (c) Microsoft Corporation. All rights reserved.
#
# This source code is subject to terms and conditions of the Shared Source License
# for IronPython. A copy of the license can be found in the License.html file
# at the root of this distribution. If you can not locate the Shared Source License
# for IronPython, please send an email to ironpy@microsoft.com.
# By using this source code in any fashion, you are agreeing to be bound by
# the terms of the Shared Source License for IronPython.
#
# You must not remove this notice, or any other, from this software.
#
# **********************************************************************************

import clr

clr.AddReference('System.Management.Automation')
clr.AddReference('IronPython')

from System.Management.Automation import *
from System.Management.Automation.Host import *
from System.Management.Automation.Runspaces import *

import System

#Create a new runspace to execute powershell commands within
_runspace = RunspaceFactory.CreateRunspace()
_runspace.Open()
_intrinsics = _runspace.SessionStateProxy.GetVariable("ExecutionContext")

def translate(name):
'''
Utility function converts a string, name, to lowercase.
Also replaces hyphens with underscores.
'''
name = name.lower()
return name.replace('-', '_')

def fix_arg(arg):
'''
Utility function converts arg (of type string, PSObjectWrapper, or
ShellOutput) to type string.
'''
if isinstance(arg, str):
arg = _intrinsics.InvokeCommand.ExpandString(arg)
elif isinstance(arg, PSObjectWrapper):
arg = arg.data
elif isinstance(arg, ShellOutput):
arg = arg.data
return arg

def InvokeCommand(_cmdName, _input=None, *args, **kws):
'''
Used to actually invoke a powershell command.
'''
#print 'invoke', _cmdName, _input
cmd = Command(_cmdName)

#Adds parameters to the command
for arg in args:
cmd.Parameters.Add(CommandParameter(None, fix_arg(arg)))

for name, value in kws.items():
cmd.Parameters.Add(CommandParameter(name, fix_arg(value)))

#Create a pipeline to run the command within and invoke
#the command.
pipeline = _runspace.CreatePipeline()
pipeline.Commands.Add(cmd)
if _input:
ret = pipeline.Invoke(fix_arg(_input))
else:
ret = pipeline.Invoke()
#return the output of the command formatted special
#using the ShellOutput class
return ShellOutput(ret)

class Shell:
'''
Instances of this class are like pseudo PowerShell
shells. That is, this class essentially has a method for
each PowerShell command available.
'''
def __init__(self, data):
'''
Standard constructor. Just copies a dictionary mapping
PowerShell commands to names as members of this class.
'''
for key, value in data.items():
setattr(self, key, value)

class ShellCommand(object):
'''
Wrapper class for shell commands.
'''
def __init__(self, name, input=None):
'''
'''
self.name = name
self.input = input

def __call__(self, *args, **kws):
'''
'''
return InvokeCommand(self.name, self.input, *args, **kws)

def __get__(self, instance, context=None):
'''
'''
return ShellCommand(self.name, instance)
def __repr__(self):
'''
'''
return "<ShellCommand %s>" % self.name

class ShellOutput(object):
'''
'''
def __init__(self, data):
'''
'''
self.data = data

def __len__(self):
'''
'''
return self.data.Count

def __repr__(self):
'''
'''
if self.data.Count == 0: return ''
return str(self.out_string(Width=System.Console.BufferWidth-1)[0]).strip()

def __getitem__(self, index):
'''
'''
if index >= self.data.Count: raise IndexError
ret = self.data[index]
if isinstance(ret, PSObject):
return PSObjectWrapper(ret)

class PSObjectWrapper(object):
'''
'''
def __init__(self, data):
'''
'''
self.data = data

def __getattr__(self, name):
'''
'''
member = self.data.Members[name]
if member is not None:
ret = member.Value
if isinstance(ret, PSMethod):
ret = InvokeToCallableAdapter(ret)
return ret

raise AttributeError(name)

def __repr__(self):
'''
'''
return self.data.Members['ToString'].Invoke()

def dump(o):
'''
'''
print str(o.out_string(Width=System.Console.BufferWidth-1)[0]).strip()

class InvokeToCallableAdapter:
'''
'''
def __init__(self, meth):
'''
'''
self.meth = meth

def __call__(self, *args):
'''
'''
return self.meth.Invoke(*args)

def init_runspace():
'''
'''
global shell
#build up a dictionary of native PowerShell commands where
#each value consists of the PS command wrapped within
#the ShellCommand helper class
cmds = {}
for cmdlet in InvokeCommand('get-command'):
cmds[translate(cmdlet.Name)] = ShellCommand(cmdlet.Name)
#look for all aliases and for each of them that map directly
#into a native PowerShell command, support them directly
#from the dictionary
for alias in InvokeCommand('get-alias'):
cmdName = translate(alias.ReferencedCommand.Name)
if cmdName in cmds:
cmds[translate(alias.Name)] = cmds[cmdName]

shell = Shell(cmds)
ShellOutput.__dict__.update(cmds)

init_runspace()

if __name__ == '__main__':
print """Run \'dir(shell)\' to get a list of available PowerShell commands!
In general, IronPython PowerShell commands are accessed using the form:
shell.get_process("cmd").select(First=2)
"""

PowerShell里面有几个对象:RunSpacePSMethodPSObject等,具体可以参看PowerShell SDK。这个PowerShell模块对PowerShell对象进行了一个包装成对象shell,这个对象包装了PS的cmdlets 和aliases。

posted @ 2007-02-12 18:13  张善友  阅读(4586)  评论(2编辑  收藏  举报