PowerShell cmdlet与.NET类

时间:2017-04-20 13:49:08

标签: .net powershell cmdlets

编写PowerShell脚本时,有两个选项可供选择:

  1. 致电cmdlet
  2. 使用.NET Framework Class library
  3. 在后台,cmdlet可能更多地使用.NET库。

    在Powershell脚本中哪一个更好用,性能明智?

    我倾向于更喜欢直接使用.NET库,因为它更接近C#。

3 个答案:

答案 0 :(得分:14)

  

编写Powershell脚本时,有两个选项可供选择:

     
      
  1. 调用cmdlet
  2.   
  3. 使用.NET Framework类库
  4.   

TBH,我认为这是对PowerShell 的过度简化。

值得指出的第一件事是PowerShell(API powershell.exe主机应用程序)首先在.NET中实现,因此根据定义,PowerShell中的所有内容都是&# 34;使用.NET"。

作为示例,cmdlet实际上是一个.NET对象 - 看看Get-Command返回的CmdletInfo对象:

PS C:\> (Get-Command Get-Command) |Format-List Name,CommandType,DLL,ImplementingType


Name             : Get-Command
CommandType      : Cmdlet
DLL              : C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad36
                   4e35\System.Management.Automation.dll
ImplementingType : Microsoft.PowerShell.Commands.GetCommandCommand

查看实现类型Microsoft.PowerShell.Commands.GetCommandCommand - 它只是一个常规的.NET类 - 当你发出命令Get-Command时,powershell会创建一个这个类的实例,调用一些 - 定义的方法,然后调用执行实际工作的.NET方法。

PowerShell(或Monad, as it was originally called)背后的整个理念是,开发时间更好地专注于做一件事情的小型自包含单元/功能( monad 原始概念),非常类似于UNIX实用程序背后的原始哲学。

这个想法是,一旦你有一个框架将这些单元连接在一起,你就可以通过连接更简单的单元来虚拟地编写任何程序。

这个想法的具体化是 cmdlet - 它有一些明确定义的输入绑定行为,允许你组成管道

Get-AThing | Filter-TheThing | Write-ToAFile C:\path\to\file\name.ext

在我的拙见中,像上面这样的管道方式比例如:

更具可读性
[System.IO.File]::WriteAllText('C:\path\to\file\name.ext', [System.Linq.Enumerable]::Select([Thing]::EnumerateThings(),{param([thing]$in) $in -eq $someCriteria}))

这是主观的,但我想要了解的是,如果你利用PowerShell免费提供的一些核心功能,那么你就是在欺骗自己。沟道cmdlet的方式

现在,对于实际问题:是的,直接调用单个.NET方法比调用cmdlet更快,并且开销更少,这反过来使PowerShell运行一些额外的代码,最终只包装相同的.NET方法调用。 / p>

话虽如此,如果您正在运行较新版本的PowerShell(4.0,5.0,5.1或6.0),在许多情况下开销可以忽略不计。

例如,从磁盘读取文件的速度比解析已经在内存中的.NET方法调用链(这是PowerShell对您透明的操作)的速度要慢一些,这仅仅是因为从旋转磁盘移动电子通过磁盘控制器和内存总线进入内存是一个受光速限制的操作。

我个人优化性能的策略是在我开始考虑cmdlet与直接方法调用之前,检查我使用的算法/例程和数据结构。

如果我做了一些愚蠢的事情,使得我的脚本需要10倍的CPU周期来计算,那么它就不会帮助尝试追逐边际开销。

如果你已经达到了这个策略的极限,考虑在C#或VB.NET中编写cmdlet - 编译后的代码(几乎)总是比解释代码更快: - )

答案 1 :(得分:2)

两者之间的差异应该是最小的。 cmdlet将调用.NET Framework方法,因此行为将相同。

因此,如果不使用cmdlet,您可能会看到一些极小的性能提升;但它可以忽略不计。

为什么不考虑更好的读取并坚持下去?

答案 2 :(得分:0)

对我来说,在使用两者之后,选择真的归结为代码维护。脚本化cmdlet允许更轻松地对托管类进行代码维护,并进行结构化重新编译和发布。

除非处理速度至关重要,否则每次都会选择脚本化cmdlet。