PowerShell cmd-let with F#
PS Cmd-let สามารถสร้างได้ 4 แบบ[1] แบบที่เขียนด้วย .NET Language (C#,F#,etc.) เรียกว่า Binary Module ทำได้โดยการ publish .NET class library แล้ว copy ไปไว้ใน directory ของ PowerShell Module Path ($env:PSModulePath
)[2]
Build Cmd-let solution
- สร้าง .NET project file ด้วย
dotnet new classlib -lang F# <module name>
- Reference Nuget
PowerShellStandard.Library
และต้อง markPackageReference
ใน project file ให้เป็นPrivateAssets="all"
ด้วย!
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>ps_hello</RootNamespace>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="Library.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="PowerShellStandard.Library" Version="5.1.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="5.0.1" />
</ItemGroup>
</Project>
- Derive class with
Cmdlet
และ mark class ด้วย attributeCmdlet
และOutputType
- Parameter จะต้องทำเป็น get/set property และ mark ด้วย attribute
Parameter
- Parameter จะต้องทำเป็น get/set property และ mark ด้วย attribute
namespace RZ.PowerShell
open System
open System.Management.Automation
[<Cmdlet(VerbsCommunications.Write, "Word")>]
[<OutputType(typeof<string>)>]
type SayAWord() as this =
inherit Cmdlet()
[<Parameter(Position=0, Mandatory=true, ValueFromPipeline=true, ValueFromPipelineByPropertyName=true)>]
[<ValidateNotNullOrEmpty>]
member val Word = String.Empty with get,set
override _.ProcessRecord() =
base.ProcessRecord()
this.WriteObject $"Hello, {this.Word}"
- Publish project
dotnet publish -c Release -o <module name>
Copy publish project ไปไว้ใน PS module path
เราสามารถใช้ user module path ซึ่งปกติ PowerShell จะ set ไว้ที่ $Home\Documents\PowerShell\Modules
สำหรับ PowerShell .NET Core (หรือ $Home\Documents\WindowsPowerShell\Modules
ถ้าเป็น PowerShell for Windows)
เมื่อ copy ไปใน folder ดังกล่าวแล้ว ให้ run คำสั่ง Import-Module <module name>
แล้วจะสามารถใช้คำสั่ง Write-Word
ได้ โดยครั้งหน้าไม่ต้องสั่งคำสั่งนี้อีก[3]
** สิ่งสำคัญคือ ชื่อ module name ที่ PowerShell คือชื่อของ directory ที่เรา copy ไปวาง และต้องเป็นชื่อเดียวกันกับ dll ในนั้นด้วย เช่น ถ้าเราตั้งชื่อ project เราว่า PsHello เวลา compile ออกมาจะได้ PsHello.dll
และเวลาเรา publish ก็ควรใช้ชื่อ PsHello
จึงจะทำให้เราสามารถใช้คำสั่ง Import-Module PsHello
ได้