我纪念我想要实现为二进制模块的模块。我还没有创造一个使用的 电源外壳标准库 所以这觉得很好。我能用它 创建跨平台二进制模块 在没有任何障碍的情况下创建此模块的指南。我们将走同样的过程,我将在路上添加一些额外的评论。
-Update: - 我找到了一种更简单的方法来做一些二进制模块步骤,我将它们添加到文章的末尾。
指数
Powershell标准图书馆是什么?
电源外壳标准库允许我们创建在og体育核心和Windows og体育 5.1(或3.0)中工作的跨平台模块。
规划我们的模块
The plan for this module is to create a src
folder for the C# code and structure the rest of the module like I would for a script module. This includes using a build script to compile everything into an output
folder. The folder structure will look like this:
MyModule
├───src
├───Output
│ └───MyModule
├───MyModule
│ ├───Data
│ ├───Private
│ └───Public
└───Tests
入门
我通常使用膏药模板,但我的当前模板尚未有任何二进制模块支持。不是大不了的,我会用这次用手创造这个。
First I need to create the folder and create the git repo. I will be using $module
as a place holder for the module name. This should make it easier for you to reuse these examples if needed.
$module = 'MyModule'
New-Item -Path $module -Type Directory
Set-Location $module
git init
然后创建根级文件夹。
New-Item -Path 'src' -Type Directory
New-Item -Path 'Output' -Type Directory
New-Item -Path 'Tests' -Type Directory
New-Item -Path $module -Type Directory
二进制模块设置
这将在二进制模块上的焦点,以便我们将在哪里开始。本节从中拉动示例 创建跨平台二进制模块 指导。如果您需要更多详细信息或有任何问题,请查看该指南。
我们要做的第一件事就是检查版本 dotnet core sdk. 我们已安装过。我正在使用2.1.4,但在继续之前,你应该有2.0.0或更新。
PS:> dotnet --version
2.1.4
I will be working out of the src
folder for this section.
Set-Location 'src'
使用dotnet命令,创建一个新的类库。
dotnet new classlib --name $module
这在子文件夹中创建了库项目,但我不希望额外的嵌套级别。我将要将这些文件提升到一个级别。
Move-Item -Path .\$module\* -Destination .\
Remove-Item $module -Recurse
为项目设置.NET Core SDK版本。我有2.1 SDK,所以我要指定2.1.0。如果您使用的是2.0 SDK,请使用2.0.0。
dotnet new globaljson --sdk-version 2.1.0
添加 电源外壳标准库 package to the project. Make sure you use the most recent version available for the level of compatibility that you need. I would default to version 5.1.0-preview-05
but I don’t think this module will leverage anything newer than what PS 3.0 provides.
dotnet add package og体育Standard.Library --version 3.0.0-preview-02
我们应该有一个SRC文件夹,如下所示:
PS:> Get-ChildItem
Directory: \MyModule\src
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 7/14/2018 9:51 PM obj
-a---- 7/14/2018 9:51 PM 86 Class1.cs
-a---- 7/14/2018 10:03 PM 259 MyModule.csproj
-a---- 7/14/2018 10:05 PM 45 global.json
我们现在准备将自己的代码添加到项目中。
构建二进制cmdlet
We need to update the src\Class1.cs
to contain this starter cmdlet:
using System;
using System.Management.Automation;
namespace MyModule
{
[Cmdlet( VerbsDiagnostic.Resolve , "MyCmdlet")]
public class ResolveMyCmdletCommand : PSCmdlet
{
[Parameter(Position=0)]
public Object InputObject { get; set; }
protected override void EndProcessing()
{
this.WriteObject(this.InputObject);
base.EndProcessing();
}
}
}
我们将重命名文件以匹配类名。
Rename-Item .\Class1.cs .\ResolveMyCmdletCommand.cs
然后我们可以构建我们的模块。
PS:> dotnet build
Microsoft (R) Build Engine version 15.5.180.51428 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
Restore completed in 18.19 ms for C:\workspace\MyModule\src\MyModule.csproj.
MyModule -> C:\workspace\MyModule\src\bin\Debug\netstandard2.0\MyModule.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:02.19
We can call Import-Module
on the new dll and it will load our new CMDlet.
PS:> Import-Module .\bin\Debug\netstandard2.0\$module.dll
PS:> Get-Command -Module $module
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Resolve-MyCmdlet 1.0.0.0 MyModule
如果导入在系统上失败,请尝试更新.NET到4.7.1或更新。这 使用.NET核心命令行接口工具创建跨平台二进制模块 Guide更详细地了解.NET支持和较旧版本的.NET的兼容性。
模块清单
我们可以将DLL导入并具有工作模块很酷。我想继续使用它并创建模块清单。如果我们稍后想发布到Psgallery,我们将需要这个。
从我们项目的根源,我们可以运行此命令以创建我们需要的模块清单。
$manifestSplat = @{
Path = ".\$module\$module.psd1"
Author = 'Kevin Marquette'
NestedModules = @('bin\MyModule.dll')
RootModule = "$module.psm1"
FunctionsToExport = @('Resolve-MyCmdlet')
}
New-ModuleManifest @manifestSplat
我还将为未来的og体育函数创建一个空的根模块。
Set-Content -Value '' -Path ".\$module\$module.psm1"
这允许我在同一项目中混合普通og体育函数和二进制cmdlet。
构建完整模块
I compile everything together into an output folder. We need to create a build script to do that. I would normally add this to an Invoke-Build
script, but we can keep it simple for this example. Add this to a build.ps1
at the root of the project.
$module = 'MyModule'
Push-Location $PSScriptroot
dotnet build $PSScriptRoot\src -o $PSScriptRoot\output\$module\bin
Copy-Item "$PSScriptRoot\$module\*" "$PSScriptRoot\output\$module" -Recurse -Force
Import-Module "$PSScriptRoot\Output\$module\$module.psd1"
Invoke-Pester "$PSScriptRoot\Tests"
This will build our DLL and place it into our output\$module\bin
folder. It will then copy the other module files into place.
Output
└───MyModule
│ MyModule.psd1
│ MyModule.psm1
│
└───bin
MyModule.deps.json
MyModule.dll
MyModule.pdb
此时,我们能够使用PSD1文件导入模块。
Import-Module ".\Output\$module\$module.psd1"
From here, we can drop the .\Output\$module
folder into our $env:PSModulePath
directory and it will auto-load our command whenever we need it.
重要细节
在我们结束本文之前,这里有一些值得一提的详细信息。
卸下DLL
一旦加载二进制模块,您无法真正卸载它。将锁定DLL文件,直到卸载它。当开发时,这可能会很烦人,因为每次更改并想要构建它时,文件通常会被锁定。解决此问题的唯一可靠方法是关闭加载DLL的og体育会话。
vscode重新加载窗口操作
我做了大部分Powershell开发工作 vscode.. When I am working on a binary module (or a module with classes), I have gotten myself into the habit of reloading VSCode every time I build. Ctrl + Shift + P
will pop the command window and Reload Window
is always at the top of my list.
嵌套的powershell会议
另一种选择是具有良好的纠缠测试覆盖。然后您可以调整build.ps1脚本以启动新的og体育会话,执行构建,运行测试,然后关闭会话。
更新已安装的模块
在尝试更新本地安装的模块时,此锁定可能会很烦人。如果任何会话都装满了,你必须去追捕并关闭它。从PSGallery安装时,这是较少的问题,因为模块版本控制将新的文件夹放置在另一个文件夹中。
您可以设置本地PSGallery并将其发布为构建的一部分。然后从该PSGallery执行本地安装。这听起来像很多工作,但这可以像开局码头容器一样简单。我覆盖了在我的帖子中这样做的方法 使用NuGet服务器进行PSRepository.
为什么二元模块?
我跳进了如何制作一个二进制模块,并没有提到你想要制作一个原因。实际上,您正在编写C#并放弃轻松访问og体育 cmdlet和功能。这是我不早在二元模块转移到二元模块的重要原因。
但是,如果您正在创建一个不依赖于大量其他og体育命令的模块,则性能效益可能相当大。通过删除C#,您可以通过og体育来缩小添加的开销。 og体育针对管理员进行了优化,而不是计算机,并且增加了一点开销。
在工作中,我们有一个关键的过程,与JSON和HASHTABLE有很多工作。我们尽可能多地优化og体育,但此过程仍在运行12分钟。该模块已包含很多C#样式og体育。这使得转换为二元模块非常干净,易于做。我们的转换将从12分钟减少到4分钟以下。那一点睁开眼睛。
混合模块
You can mix binary Cmdlets with og体育 advanced functions. That is exactly what I am doing in this guide. You can take everything you know about script modules and it all applies the same way. The empty psm1
file that I created today is there just so you can drop in other og体育 functions later.
几乎所有我们创建的编译cmdlet都以og体育功能开始。所有的二进制模块都是混合模块。
构建脚本
I kept the build script simple here. I generally use a large Invoke-Build
script as part of my CI/CD pipeline. It does more magic like running Pester tests, running PSSciptAnalyzer, managing versioning, and publishing to the PSGallery. Once I started using a build script for my modules, I was able to find lots of things to add to it.
最后的想法
二进制模块很容易创建。我没有触摸C#语法以创建cmdlet,但它有很多文档。 Windows og体育 SDK.。这绝对是值得尝试的,作为踏脚石进入更严重的C#。
更新:Dotnet New PsModule
I learned that there is a PSModule
dotnet new
template.
It'S值得加入Dotnet新的最近添加了PS的模板:
—Chris Bergmeister [MVP](@cbergmeister) 2018年8月5日
dotnet new -i microsoft.powershell.standard.module.template
dotnet new psmodule.
(取自 @tylerleonhardt : //t.co/RGLVcjGXUF)
我上面概述的所有步骤仍然有效,但这种模板会削减很多。它仍然是一个相当新的模板,仍然得到一些抛光剂。期待它从这里保持更好。
这是您使用安装的方式和使用PSModule模板。
dotnet new -i Microsoft.og体育.Standard.Module.Template
dotnet new psmodule
dotnet build
Import-Module "bin\Debug\netstandard2.0\$module.dll"
Get-Module $module
此最小可行模板负责添加.NET SDK,og体育标准库,并在项目中创建示例类。您可以立即构建并立即运行它。