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:IronPythonSamplesIPPowerShell>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.CoreFileSystem::D:IronPythonSamplesIPPowerShel 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里面有几个对象:RunSpace,PSMethod,PSObject等,具体可以参看PowerShell SDK。这个PowerShell模块对PowerShell对象进行了一个包装成对象shell,这个对象包装了PS的cmdlets 和aliases。