开发 Nano Server 的 PowerShell CmdletDeveloping PowerShell Cmdlets for Nano Server

适用于:Windows Server 2016Applies To: Windows Server 2016

重要

自 Windows Server 版本 1709 开始,Nano Server 将仅用作容器基本 OS 映像Starting in Windows Server, version 1709, Nano Server will be available only as a container base OS image. 查看对 Nano Server 进行的更改以了解其含义。Check out Changes to Nano Server to learn what this means.

概述Overview

默认情况下,Nano Server 在所有 Nano Server 安装中都包括 PowerShell Core。Nano Server includes PowerShell Core by default in all Nano Server installations. PowerShell Core 是基于 .NET Core 构建的 PowerShell 占用空间减小版本,在占用空间减小版本的 Windows (例如,Nano Server 和 Windows IoT Core)上运行。PowerShell Core is a reduced-footprint edition of PowerShell that is built on .NET Core and runs on reduced-footprint editions of Windows, such as Nano Server and Windows IoT Core. PowerShell Core 与其他 PowerShell 版本(例如 Windows Server 2016 上运行的 Windows PowerShell)运行方式相同。PowerShell Core functions in the same way as other editions of PowerShell, such as Windows PowerShell running on Windows Server 2016. 然而,Nano Server 占用空间减少意味着不是所有 Windows Server 2016 中的 PowerShell 功能都在 Nano Server 上的 PowerShell Core 中可用。However, the reduced footprint of Nano Server means that not all PowerShell features from Windows Server 2016 are available in PowerShell Core on Nano Server.

如果要在 Nano Server 上运行现有 PowerShell cmdlet 或为此开发新的 PowerShell cmdlet,本主题中包含的提示和建议会使其更加简单。If you have existing PowerShell cmdlets that you'd like to run on Nano Server, or are developing new ones for that purpose, this topic includes tips and suggestions that should help make that easier.

PowerShell 版本PowerShell editions

从 5.1 版本开始,PowerShell 在具有不同功能集和平台兼容性的不同版本中可用。Starting with version 5.1, PowerShell is available in different editions which denote varying feature sets and platform compatibility.

  • 桌面版: 基于 .NET Framework 而构建,兼容面向在 Windows 完整占用空间版本(例如,Server Core 和 Windows Desktop)上运行的 PowerShell 版本的脚本和模块。Desktop Edition: Built on .NET Framework and provides compatibility with scripts and modules targeting versions of PowerShell running on full footprint editions of Windows such as Server Core and Windows Desktop.
  • 核心版: 基于 .NET Core 而构建,兼容面向在 Windows 占用空间减小版本(例如,Nano Server 和 Windows IoT)上运行的 PowerShell 版本的脚本和模块。Core Edition: Built on .NET Core and provides compatibility with scripts and modules targeting versions of PowerShell running on reduced footprint editions of Windows such as Nano Server and Windows IoT.

当前运行的 PowerShell 版本显示在 $PSVersionTable 的 PSEdition 属性中。The running edition of PowerShell is shown in the PSEdition property of $PSVersionTable.

$PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.14300.1000
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
CLRVersion                     4.0.30319.42000
BuildVersion                   10.0.14300.1000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

模块作者可使用 CompatiblePSEditions 模块清单秘钥声明模块兼容一个或多个 PowerShell 版本。Module authors can declare their modules to be compatible with one or more PowerShell editions using the CompatiblePSEditions module manifest key. 仅 PowerShell 5.1 或更高版本支持此密钥。This key is only supported on PowerShell 5.1 or later.

New-ModuleManifest -Path .\TestModuleWithEdition.psd1 -CompatiblePSEditions Desktop,Core -PowerShellVersion 5.1
$moduleInfo = Test-ModuleManifest -Path \TestModuleWithEdition.psd1
$moduleInfo.CompatiblePSEditions
Desktop
Core

$moduleInfo | Get-Member CompatiblePSEditions

   TypeName: System.Management.Automation.PSModuleInfo

Name                 MemberType Definition
----                 ---------- ----------
CompatiblePSEditions Property   System.Collections.Generic.IEnumerable[string] CompatiblePSEditions {get;}

获取可用模块列表后,可按 PowerShell 版本筛选列表。When getting a list of available modules, you can filter the list by PowerShell edition.

Get-Module -ListAvailable | ? CompatiblePSEditions -Contains Desktop

    Directory: C:\Program Files\WindowsPowerShell\Modules


ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   1.0        ModuleWithPSEditions

Get-Module -ListAvailable | ? CompatiblePSEditions -Contains Core | % CompatiblePSEditions
Desktop
Core

脚本作者可在 #requires 语句中使用 PSEdition 参数来阻止脚本执行,除非其在兼容的 PowerShell 版本上运行。Script authors can prevent a script from executing unless it is run on a compatible edition of PowerShell using the PSEdition parameter on a #requires statement.

Set-Content C:\script.ps1 -Value #requires -PSEdition Core
Get-Process -Name PowerShell
Get-Content C:\script.ps1
#requires -PSEdition Core
Get-Process -Name PowerShell

C:\script.ps1
C:\script.ps1 : The script 'script.ps1' cannot be run because it contained a #requires statement for PowerShell editions 'Core'. The edition of PowerShell that is required by the script does not match the currently running PowerShell Desktop edition.
At line:1 char:1
+ C:\script.ps1
+ ~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (script.ps1:String) [], RuntimeException
    + FullyQualifiedErrorId : ScriptRequiresUnmatchedPSEdition

安装 Nano ServerInstalling Nano Server

有关在虚拟或物理计算机上安装 Nano Server 的快速入门和详细步骤,请参阅本主题的父主题 - 安装 Nano ServerQuick-start and detailed steps for installing Nano Server on virtual or physical machines are provided in Install Nano Server, which is the parent topic for this one.

备注

使用 New-NanoServerImage 的 -Development 参数安装 Nano Server 可能会有助于 Nano Server 上的开发工作。For development work on Nano Server, you might find it useful to install Nano Server by using the -Development parameter of New-NanoServerImage. 这将允许安装未签名的驱动程序、复制调试程序二进制、打开调试端口、启用测试签名和允许安装 AppX 程序包,且无需开发者许可证。This will enable installation of unsigned drivers, copy debugger binaries, open a port for debugging, enable test signing and enable installation of AppX packages without a developer license. 例如:For example:

New-NanoServerImage -DeploymentType Guest -Edition Standard -MediaPath \\Path\To\Media\en_us -BasePath .\Base -TargetPath .\NanoServer.wim -Development

决定 cmdlet 实现类型Determining the type of cmdlet implementation

PowerShell 支持多种 cmdlet 实现类型,你使用的类型决定其创建或移植相关的过程和工具,以使其在 Nano Server 上运行。PowerShell supports a number of implementation types for cmdlets, and the one you've used determines the process and tools involved in creating or porting it to work on Nano Server. 支持的实现类型包括:Supported implementation types are:

  • CIM - 由分层置放在 CIM (WMIv2) 提供程序上的 CDXML 文件组成CIM - consists of CDXML files layered over CIM (WMIv2) providers
  • .NET - 由实现托管的 cmdlet 接口组成,通常使用 C# 语言编写.NET - consists of .NET assemblies implementing managed cmdlet interfaces, typically written in C#
  • PowerShell 脚本 - 由 PowerShell 语言编写的脚本模块 (.psm1) 或脚本 (.ps1) 组成PowerShell Script - consists of script modules (.psm1) or scripts (.ps1) written in the PowerShell language

如果不确定要移植的现有 cmdlet 已使用的实现,请安装产品或功能,然后在以下位置中查找 PowerShell 模块文件:If you're not sure which implementation you've used for existing cmdlets you want to port, install your product or feature and then look for the PowerShell module folder in one of the following locations:

  • %windir%\system32\WindowsPowerShell\v1.0\Modules%windir%\system32\WindowsPowerShell\v1.0\Modules

  • %ProgramFiles%\WindowsPowerShell\Modules%ProgramFiles%\WindowsPowerShell\Modules

  • %UserProfile%\Documents\WindowsPowerShell\Modules%UserProfile%\Documents\WindowsPowerShell\Modules

  • <your product installation location>

    检查这些位置以获取详细信息:Check in these locations for these details:

    • CIM cmdlet 具有.cdxml 文件扩展名。CIM cmdlets have .cdxml file extensions.
    • .NET cmdlet 具有.dll 文件扩展名,或具有安装到 RootModule、ModuleToProcess 或 NestedModules 字段下 .psd1 文件中所列出的 GAC 的程序集。.NET cmdlets have .dll file extensions, or have assemblies installed to the GAC listed in the .psd1 file under the RootModule, ModuleToProcess, or NestedModules fields.
  • PowerShell 脚本 cmdlet 具有.psm1 或.ps1 文件扩展名。PowerShell script cmdlets have .psm1 or .ps1 file extensions.

移植 CIM cmdletPorting CIM cmdlets

通常情况下,这些 cmdlet 可在 Nano Server 中运行,无需任何转换。Generally, these cmdlets should work in Nano Server without any conversion necessary. 但是,如果尚未进行此操作,则必须移植基础 WMI v2 提供程序以使其在 Nano Server 上运行。However, you must port the underlying WMI v2 provider to run on Nano Server if that has not already been done.

生成适用于 Nano Server 的 C++Building C++ for Nano Server

若要使 C++ DLL 在 Nano Server 上运行,请将其编译为适用于 Nano Server 而非某特定版本。To get C++ DLLs working on Nano Server, compile them for Nano Server rather than for a specific edition.

有关在 Nano Server 上开发 C++ 的先决条件和操作示例,请参阅 Developing Native Apps on Nano Server(在 Nano Server 上开发本机应用)。For prerequisites and a walkthrough of developing C++ on Nano Server, see Developing Native Apps on Nano Server.

移植 .NET cmdletPorting .NET cmdlets

Nano Server 上支持大多数 C# 代码。Most C# code is supported on Nano Server. 可使用 ApiPort 扫描不兼容的 API。You can use ApiPort to scan for incompatible APIs.

Powershell Core SDKPowershell Core SDK

模块 Microsoft.PowerShell.NanoServer.SDK 在 PowerShell Gallery(PowerShell 库)中可通过 Visual Studio 2015 Update 2 用于简化面向 Nano Server 中可用 CoreCLR 和 PowerShell Core 版本的 .NET cmdlet 的开发。The module Microsoft.PowerShell.NanoServer.SDK is available in the PowerShell Gallery to facilitate developing .NET cmdlets using Visual Studio 2015 Update 2 that target the versions of CoreCLR and PowerShell Core available in Nano Server. 可按照此命令使用 PowerShellGet 安装该模块:You can install the module using PowerShellGet with this command:

Find-Module Microsoft.PowerShell.NanoServer.SDK -Repository PSGallery | Install-Module -Scope <scope>

PowerShell Core SDK 模块会暴露 cmdlet 来设置正确的 CoreCLR 和 PowerShell Core 引用程序集、在 Visual Studio 2015 中创建面向这些引用程序集的 C# 项目,并在 Nano Server 计算机上设置远程调试程序,从而使开发人员可在 Visual Studio 2015 中远程调试 Nano Server 上运行的 .NET cmdlet。The PowerShell Core SDK module exposes cmdlets to set up the correct CoreCLR and PowerShell Core reference assemblies, create a C# project in Visual Studio 2015 targeting those reference assemblies, and set up the remote debugger on a Nano Server machine so that developers can debug their .NET cmdlets running on Nano Server remotely in Visual Studio 2015.

PowerShell Core SDK 模块需要 Visual Studio 2015 Update 2。The PowerShell Core SDK module requires Visual Studio 2015 Update 2. 如未安装 Visual Studio 2015,可安装 Visual Studio Community 2015If you do not have Visual Studio 2015 installed, you can install Visual Studio Community 2015.

该 SDK 模块还取决于 Visual Studio 2015 中要安装的以下功能:The SDK module also depends on the following feature to be installed in Visual Studio 2015:

  • Windows 和 Web 开发 -> 通用 Windows 应用开发工具 -> 工具 (1.3.1) 和 Windows 10 SDKWindows and Web Development -> Universal Windows App Development Tools -> Tools (1.3.1) and Windows 10 SDK

使用此 SDK 模块之前请检查 Visual Studio 安装,以确保满足这些先决条件。Review your Visual Studio installation before using the SDK module to ensure these prerequisites are satisfied. 安装 Visual Studio 过程中,请务必选择安装上述功能,或修改现有 Visual Studio 2015 安装以进行安装。Make sure you select to install the above feature during the Visual Studio installation, or modify your existing Visual Studio 2015 installation to install it.

PowerShell Core SDK 模块包括以下 cmdlet:The PowerShell Core SDK module includes the following cmdlets:

  • New-NanoCSharpProject:创建新的 Visual Studio C# 项目,该项目面向 Nano Server 的 Windows Server 2016 版本中包含的 CoreCLR 和 PowerShell Core。New-NanoCSharpProject: Creates a new Visual Studio C# project targeting CoreCLR and PowerShell Core included in the Windows Server 2016 release of Nano Server.
  • Show-SdkSetupReadMe:在文件资源管理器中打开 SDK 根文件夹并打开用于手动设置的 README.txt 文件。Show-SdkSetupReadMe: Opens the SDK root folder in File Explorer and opens the README.txt file for manual setup.
  • Install-RemoteDebugger:在 Nano Server 计算机上安装和配置 Visual Studio 远程调试程序。Install-RemoteDebugger: Installs and configures the Visual Studio remote debugger on a Nano Server machine.
  • Start-RemoteDebugger:在运行 Nano Server 的远程计算机上启动远程调试程序。Start-RemoteDebugger: Starts the remote debugger on a remote machine running Nano Server.
  • Stop-RemoteDebugger:在运行 Nano Server 的远程计算机上停止远程调试程序。Stop-RemoteDebugger: Stops the remote debugger on a remote machine running Nano Server.

有关如何使用这些 cmdlet 的详细信息,请在安装和导入该模块后,在每个 cmdlet 上运行 Get-Help,如下所示:For detailed information about how to use those cmdlets, run Get-Help on each cmdlet after installing and importing the module as follows:

Get-Command -Module Microsoft.PowerShell.NanoServer.SDK | Get-Help -Full

搜索兼容的 APISearching for compatible APIs

可在 API 目录中搜索 .NET Core,或反汇编 Core CLR 引用程序集。You can search in the API catalog for .NET Core or disassemble Core CLR reference assemblies. 有关 .NET API 平台可移植性的详细信息,请参阅 Platform Portability(平台可移植性)For more information about platform portability of .NET APIs, see Platform Portability

PInvokePInvoke

在 Nano Server 使用的 Core CLR 中,kernel32.dll 和 advapi32.dll 等基础 DLL 已拆分为多个 API 集,因此需确保 PInvoke 引用了正确的 API。In the Core CLR that Nano Server uses, some fundamental DLLs such as kernel32.dll and advapi32.dll were split into numerous API sets, so you'll need to ensure that your PInvokes reference the correct API. 任何不兼容性将表现为运行时错误。Any incompatibility will manifest as a runtime error.

有关 Nano Server 上支持的本机 API 的列表,请参阅 Nano 服务器 APIFor a list of native APIs supported on Nano Server, see Nano Server APIs.

生成适用于 Nano Server 的 C#Building C# for Nano Server

通过使用 New-NanoCSharpProject 在 Visual Studio 2015 中创建 C# 项目后,只需单击“生成” 菜单并选择“生成项目” 或“生成解决方案” 便可生成项目。Once a C# project is created in Visual Studio 2015 by using New-NanoCSharpProject, you can simply build it in Visual Studio by clicking the Build menu and selecting Build Project or Build Solution. 生成的程序集将面向 Nano Server 中正确的 CoreCLR 和 PowerShell Core,只需将这些程序集复制到运行 Nano Server 的计算机便可使用。The generated assemblies will be targeting the correct CoreCLR and PowerShell Core shipped in Nano Server, and you can just copy the assemblies to a computer running Nano Server and use them.

生成适用于 Nano Server 的托管 C++ (CPP/CLI)Building managed C++ (CPP/CLI) for Nano Server

托管 C++ 不支持 CoreCLR。Managed C++ is not supported for CoreCLR. 移植到 CoreCLR 后,使用 C# 重新编写托管 C++ 代码,并通过 PInvoke 进行所有的本机调用。When porting to CoreCLR, rewrite managed C++ code in C# and make all native calls through PInvoke.

移植 PowerShell 脚本 cmdletPorting PowerShell script cmdlets

PowerShell Core 具有其他 PowerShell 版本(包括 Windows Server 2016 和 Windows 10 中运行的版本)的完整 PowerShell 语言奇偶校验。PowerShell Core has full PowerShell language parity with other editions of PowerShell, including the edition running on Windows Server 2016 and Windows 10. 但是,将 PowerShell 脚本 cmdlet 移植到 Nano Server 时,请考虑这些因素:However, when porting PowerShell script cmdlets to Nano Server, keep these factors in mind:

  • 其他 cmdlet 上存在依赖关系吗?Are there dependencies on other cmdlets? 如果存在,这些 cmdlet 是否在 Nano Server 上可用?If so, are those cmdlets available on Nano Server. 有关不可用内容的详细信息,请参阅 Nano Server 上的 PowerShellSee PowerShell on Nano Server for information about what is not available.
  • 如果运行时加载的程序集上存在依赖关系,其是否仍然有效?If you have dependencies on assemblies that are loaded at runtime, will they still work?
  • 如何远程调试脚本?How can you debug the script remotely?
  • 如何从 WMI .Net 迁移到 MI .Net?How can you migrate from WMI .Net to MI .Net?

内置 cmdlet 上的依赖关系Dependency on built-in cmdlets

并非所有 Windows Server 2016 中的 cmdlet 都在 Nano Server 上可用(请参阅 Nano Server 上的 PowerShell)。Not all cmdlets in Windows Server 2016 are available on Nano Server (see PowerShell on Nano Server). 最佳方法是设置 Nano Server 虚拟机,然后检查所需 cmdlet 是否可用。The best approach is to set up a Nano Server virtual machine and discover whether the cmdlets you need are available. 若要执行此操作,请运行 Enter-PSSession 以连接到目标 Nano Server,然后运行 Get-Command -CommandType Cmdlet, Function 获取可用 cmdlet 的列表。To do this, run Enter-PSSession to connect to the target Nano Server and then run Get-Command -CommandType Cmdlet, Function to get the list of available cmdlets.

考虑使用 PowerShell 类Consider using PowerShell classes

Nano Server 上支持 Add-Type 编译内联 C# 代码。Add-Type is supported on Nano Server for compiling inline C# code. 如果要编写新代码或移植现有代码,也可考虑使用 PowerShell 类来定义自定义类型。If you're writing new code or porting existing code, you might also consider using PowerShell classes to define custom types. PowerShell 类可用于属性包方案和 Enums。You can use PowerShell classes for property bag scenarios as well as for Enums. 如需执行 PInvoke,请通过 C# 使用 Add-Type 或在预编译程序集中执行。If you need to do a PInvoke, do this via C# using Add-Type or in a pre-compiled assembly. 演示 Add-Type 使用的示例如下:Here's a sample showing the use of Add-Type:

Add-Type -ReferencedAssemblies ([Microsoft.Management.Infrastructure.Ciminstance].Assembly.Location) -TypeDefinition @'
public class TestNetConnectionResult
{
   // The compute name
   public string ComputerName = null;
   // The Remote IP address used for connectivity
   public System.Net.IPAddress RemoteAddress = null;
}
'@
# Create object and set properties
$result = New-Object TestNetConnectionResult
$result.ComputerName = Foo
$result.RemoteAddress = 1.1.1.1

此示例演示在 Nano Server 上使用 PowerShell 类:This sample shows using PowerShell classes on Nano Server:

class TestNetConnectionResult
{
   # The compute name
  [string] $ComputerName

  #The Remote IP address used for connectivity
  [System.Net.IPAddress] $RemoteAddress
}
# Create object and set properties
$result = [TestNetConnectionResult]::new()
$result.ComputerName = Foo
$result.RemoteAddress = 1.1.1.1

远程调试脚本Remotely debugging scripts

若要远程调试脚本,请使用 Enter-PSsession 从 PowerShell ISE 连接到远程计算机。To remotely debug a script, connect to the remote computer using Enter-PSsession from the PowerShell ISE. 进入会话后,可运行 psedit <file_path>,这会在本地 PowerShell ISE 中打开该文件的副本。Once inside the session, you can run psedit <file_path> and a copy of the file will be open in your local PowerShell ISE. 然后,通过设置断点,可像本地运行脚本一样调试该脚本。Then, you can debug the script as if it were running locally by setting breakpoints. 此外,对此文件所做的任何更改将保存在远程版本中。Also, any changes you make to this file will be saved in the remote version.

从 WMI .NET 迁移到 MI .NETMigrating from WMI .NET to MI .NET

由于不支持 WMI .NET,因此必须将所有使用旧版 API 的 cmdlet 迁移到受支持的 WMI API:MI.NET 中。WMI .NET is not supported, so all cmdlets using the old API must migrate to the supported WMI API: MI. NET. 可通过 C# 或 CimCmdlets 模块中的 cmdlet 直接访问 MI .NET。You can access MI .NET directly through C# or through the cmdlets in the CimCmdlets module.

CimCmdlets 模块CimCmdlets module

Nano Server 上不支持 WMI v1 cmdlet(例如,Get-WmiObject)。The WMI v1 cmdlets (e.g., Get-WmiObject) are not supported on Nano Server. 但是,支持 CimCmdlets 模块中的 CIM cmdlet(例如,Get-CimInstance)。However, the CIM cmdlets (e.g., Get-CimInstance) in the CimCmdlets module are supported. CIM cmdlet 会非常紧密地映射到 WMI v1 cmdlet。The CIM cmdlets map pretty closely to the WMI v1 cmdlets. 例如,Get-WmiObject 使用非常类似的参数与 Get-CimInstance 进行关联。For example, Get-WmiObject correlates with Get-CimInstance using very similar parameters. 方法调用语法略有不同,但会通过 Invoke-CimMethod 详细记录。Method invocation syntax is slightly different, but is well documented via Invoke-CimMethod. 注意参数键入。Be careful regarding parameter typing. MI .NET 在方法参数类型方面具有更严格的要求。MI .NET has stricter requirements regarding method parameter types.

C# APIC# API

WMI .NET 包装 WMIv1 接口,而 MI .NET 包装 WMIv2 (CIM) 接口。WMI .NET wraps the WMIv1 interface, while MI .NET wraps the WMIv2 (CIM) interface. 暴露的类可能不同,但基本操作非常相似。The classes exposed might be different, but the underlying operations are very similar. 枚举或获取对象实例,并在其上调用操作来完成任务。You enumerate or get instances of objects and invoke operations on them to accomplish tasks.