使用F#编写PowerShell模块

▲F#和PowerShell模块
作为可能是人类世界最强大的Shell,PowerShell最大的特点是能够直接在命令间传递.NET对象,而支持这种能力的命令被称作cmdlet。自己编写PowerShell模块,就能给PowerShell扩展更多的cmdlet。
为何要写本文
通常来讲,PowerShell模块有两种:脚本模块和二进制模块。顾名思义,脚本模块基本上就是一组PowerShell脚本,而二进制模块,实质上是一个.NET类库。微软对于二进制模块的官方文档中,只提供了C#的范例;但鉴于F#和C#几乎是同等强大的,我在想,使用F#也能编写出可以工作的PowerShell模块。经过一小段时间的研究和整理,我决定将可行的方案分享给之家的朋友们。
任务目标
使用F#编写一个PowerShell模块,提供一个名为Get-Sum的cmdlet,完成对一个整数数组求和的功能。至于为什么选择“求和”,是因为递归求和函数通常是F#这类函数式编程语言第一课必学的例子,这种递归的思想也算是函数式语言的特色之一。
正式开始
1、建立项目
开始上手操作之前,确保你安装了.NET Core SDK,并经过适当配置,可以在任意位置使用“dotnet”命令。
打开PowerShell,在你通常保存项目代码的地方创建一个目录,作为整个项目的根。在这个目录下,使用dotnet new命令创建一个F#的类库项目和一个解决方案文件,并将项目添加进解决方案中。

如此,我们便建立了解决方案fsharp-module和F#类库工程testmodule。
2、添加用于编写/生成PowerShell模块的组装件
使用dotnet add package为工程testmodule添加名为PowerShellStandard.Library的组装件,这个组装件由微软提供,并将为工程提供System.Management.Automation名称空间和必要的类型。

如此,我们建立的F#类库已经可以用于编写PowerShell模块了。
3、编写代码
使用自己喜爱的代码编辑器修改testmodule\Library.fs,代码内容如下,我将在代码的下方解释一些要点。

注0:代码中的向右的箭头是->两个字符,向右的三角形是|>两个字符。这种连体字由著名字体FiraCode提供。灰色注释是VSCode相关插件自动生成的;
注1:此名称空间包含了编写PowerShell模块必须的类型;
注2:任何作cmdlet存在的类型必须加上Cmdlet属性(Attribute)。任何cmdlet的名称都由两部分组成:动词(Verb)和名词(Noun),最终形成“Verb-Noun”形式的名称。在这里,我们定义VerbName为Get,NounName为Sum,即得到最终的cmdlet名称Get-Sum。需要注意的是,Verb的选择需要遵守微软的规范。如果你执意要使用奇怪的Verb,构建代码时和导入模块时就会产生警告。任何cmdlet类都必须继承于PSCmdlet类;
注3:一个很经典的递归求和函数。我知道这功能可以干脆使用Array.sum方法来实现,但作为函数式语言的标志性操作之一,展示出来可以展现函数式语言和命令式语言的某种区别;
注4:Parameter属性(Attribute)标记的InputArray属性(Property)用来接收传递过来的参数对象。可以在Parameter属性(Attribute)中指定关于这个参数的更多细节,比如参数的位置、能否从管道中接收等等;
注5:重写基类(部分Java程序员会称作父类,其实都一样)的EndProcessing方法(命令处理完成后)执行求和操作并输出结果。类似的可供重写的虚函数还有BeginProcessing、ProcessRecord和StopProcessing,它们分别表示命令开始执行之前、命令执行的主体和命令中断时的过程。原则上求和应放在ProcessRecord中执行,但由于我们命令的功能很简单,干脆直接在EndProcessing里直接输出求和的结果。
4、编译模块并测试
使用dotnet publish命令发布这个类库。之所以使用publish而不是build,是因为F#程序还依赖另一个组装件:FSharp.Core来运行,而build默认不包含该组装件,该模块将不能被导入PowerShell中。
发布完成后,使用Import-Module命令导入我们编写的模块,并测试功能。

其实,别看这个cmdlet输出的是看似文本的5050,其实它输出的是一个System.Int32,你可以使用GetType()函数来证明这一点:

也正是这种在管道中传递对象的能力,使PowerShell比别的一些Shell拥有更高的潜力。
使用F#编写PowerShell模块的更多相关文章
- 【转】PowerShell入门(十一):编写脚本模块
转至:http://www.cnblogs.com/ceachy/archive/2013/03/08/PowerShell_Script_Module.html 现在通过编写模块就可以在PowerS ...
- 【转】PowerShell入门(十二):编写PowerShell管理单元和二进制模块
转至:http://www.cnblogs.com/ceachy/archive/2013/03/13/PowerShell_SnapIn.html PowerShell一开始就提出利用管理单元来实现 ...
- 使用 Azure PowerShell 模块创建和管理 Windows VM
Azure 虚拟机提供完全可配置的灵活计算环境. 本教程介绍 Azure 虚拟机的基本部署项目,例如选择 VM 大小.选择 VM 映像和部署 VM. 你将学习如何执行以下操作: 创建并连接到 VM 选 ...
- [转]使用 C 编写 Lua 模块
Lua 作为一种小巧的语言,一般都是嵌入到 C/C++ 中作为扩展语言,但是也可以作为独立的脚本语言使用,并且可以使用 C/C++ 编写扩展模块.在参考资料 [1] 中有怎样用 C/C++ 编写模块的 ...
- 用Perl编写Apache模块续二 - SVN动态鉴权实现SVNAuth 禅道版
代码地址:https://code.csdn.net/x3dcn/svnauth 以禅道项目管理系统的数据库结构为标准,实现了可用的svn authz验证功能. 以用户名.密码.项目的acl开发程度o ...
- 用Perl编写Apache模块
前言 Apache被许多大流量网站所嫌弃,但很多企业级的场景则更为适用. Apache httpd 从 2.0 之后,已经不仅仅局限于一个 http 的服务器,更是一个完善而强大.灵活而健壮且容易扩展 ...
- 为Lua5.3编写C模块简单示例
为Lua5.3编写C模块简单示例 一.编译安装Lua5.3 MSVC 命令行安装脚本: @echo off md bin md lib md include cd src cl /c /nologo ...
- 支持国内版Office 365的PowerShell模块现已发布
作者:陈希章 发表于2017年5月12日 上一篇文章我详细介绍了如何在PowerShell中访问到Office 365的Graph API,在文章结尾处我留了一个问题,希望有朋友可以根据那个思路,尝试 ...
- 新版Azure Automation Account 浅析(二) --- 更新Powershell模块和创建Runbook
前篇我们讲了怎样创建一个自动化账户以及创建时候"Run As Account"选项背后的奥秘.这一篇针对在Azure自动化账户中使用Powershell Runbook的用户讲一下 ...
随机推荐
- .Net Core微服务——服务发现:Consul(一)
先思考一些问题:它是做什么的.以及怎么使用它.带着这些问题往下走. consul是做什么的 consul用于微服务下的服务治理.服务治理是什么?它包含但不限于:服务发现.服务配置.健康检查.键值存储. ...
- 日常学习-001-Get和Post的区别
首先说明参考链接:https://mp.weixin.qq.com/s/W68JzNIoUpm9hyXinOzkMw 以下为个人观后总结. 初级理解: GET和POST的区别 1.get传送的参数长度 ...
- ASP.NET 检测当前计算机及登录用户名
TextBox1.Text = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
- 学生信息管理系统--基于jsp技术和MySQL的简单增删改查
web实现增删改查的方式有很多啊,对于初学者来说当然是要先了解各部分的传值的方式.本篇博客从jsp技术的最基础方面进行说明. 一.什么是jsp技术 首先,我们要了解什么是jsp技术. jsp技术是基于 ...
- [刘阳Java]_MyBatis_其他方式来实现多表查询的操作_第9讲
MyBatis其他方式来实现多表查询的操作 利用Java中的集合框架(List,Map) 其中List存储多个查询返回的记录 Map查询返回字段,同时记录表中一条数据 <?xml version ...
- ssh保持长连接的方式
方法有以下三种:1.修改server端的etc/ssh/sshd_configClientAliveInterval 60 #server每隔60秒发送一次请求给client,然后client响应,从 ...
- C标准库学习
前言 C标准库源码可通过下列两个网站进行查看:The GNU C Library.Welcome to uClibc-ng! - Embedded C library 以下学习记录也是以这两个网站提供 ...
- uiautomator2 入门教程
一.前言 在 Android 自动化测试方面,Google 提供了一个基于 Java 开发的库 UiAutomator,基本上支持所有的 Android 事件操作,使用简单. 在此基础上,有大佬开发出 ...
- 【模拟】报名签到 luogu-4445
AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...
- 免费,好用的天气预报API
不多说直接上! 一.API服务,天气API 网站:http://api.help.bj.cn/api/ 怎么使用网站有很详细的解释 $.ajax({ type: "GET", // ...