模块

模块是一段可以重复使用的代码。PowerShell中的大量命令是以模块的方式提供的。

管理模块

使用Get-Module命令可以查看模块。不带参数得到的是当前已加载的模块。

Get-Modlue

使用Get-Module -ListAvailable可以查看所有可用的模块。

可以直接使用所有可用模块中的命令,如果命令所在的模块未被加载,会自动加载。

Resolve-DnsName baidu.com

Resolve-DnsName命令位于DnsClient模块,使用命令时会自动加载。

使用Import-Module命令可以手动加载模块,包括可用模块或自定义模块。

Import-Module DnsClient
Import-Module "D:/MyModule.psd1"

较老版本需要手动加载模块,较新版本则可以直接使用可用的模块。

使用Remove-Module命令可以卸载模块。通常,不需要主动卸载模块。

Remove-Module DnsClient

编写自定义模块

模块分为模块清单.psd1文件和模块脚本.psm1

编写模块清单

使用New-ModuleManifest命令可以创建一个模块清单的样板。

模块清单中包含模块的名称、作者、导出的命令和引用的模块等信息。

Get-Module -ListAvaliable正是通过模块清单确定可用成员,再动态加载这些模块的。

MyModule.psd1

@{
    GUID="522846DA-7A1A-4A56-BD28-46A5EE8637DB" # 脚本Guid
    Author="" # 作者
    CompanyName="" # 公司
    Copyright="" # 版权
    ModuleVersion="0.0.0.1" # 模块版本
    CmdletsToExport= "" # 导出的命令,用于程序集
    FunctionsToExport= "My-Add" # 导出的函数,用于模块脚本
    AliasesToExport= "" # 导出的别名
    NestedModules="MyModule.psm1" # 引入模块脚本和程序集
    CompatiblePSEditions = @() # 兼容的PS版本,包括Desktop和Core两种
}

可以看到,模块清单是PowerShell脚本,使用字典定义模块信息。

在名为NestedModules键保存引入的模块脚本或程序集,支持多项,允许多种类型混合。

如果只有一个模块,也可在名为RootModule的键中保存模块脚本。

编写模块脚本

模块脚本和一般的脚本并无不同。 一般在模块脚本中定义多个函数,在模块清单的FunctionsToExport键中保存需要导出的函数。

MyModule.psm1


function My-Add($a,$b)
{
    $a + $b
}

使用自定义模块

定位到模块所在目录,可以加载和使用模块。

# 定位模块所在目录
Import-Module MyModule # 加载模块,可以省略后缀.psd1
My-Add 100 200 # 使用模块

模块目录

如果需要自定义模块也支持自动加载,需要将模块放到PowerShell的模块目录。

使用环境变量PSModulePath设置模块目录。

默认PowerShell为我们设定了多个目录,其中包括我的文档中的模块目录,他也被设定在最优先,建议使用该目录保存模块。

如果愿意,也可以修改环境变量PSModulePath,自行定义模块目录。注意存放时每个模块一个文件夹。

# 输出模块目录
$env:PSModulePath

将我们编写的模块放到模块目录后,可以通过Get-Module -ListAvailable 查询到,并且也无需加载就能使用其中的命令和函数等。

使用其他语言编写模块

可以使用.NET的其他语言如C#编写模块代码来替代模块脚本。

通过继承自Cmdlet类并实现其中的方法,来完成和脚本中函数相似的功能。

这种模块是.dll后缀的程序集,和.psm1格式模块一样,也需要模块清单。

在模块清单的NestedModules中,填写的是程序集的名称。

创建一个C#类库,名称是MyPSModule。 引用System.Management.Automation.dll程序集。

MyAdd.cs

using System.Management.Automation;

namespace MyPSModule
{
    [Cmdlet("My", "Add")]
    public class MyAdd : Cmdlet
    {
        [Parameter(Position = 1)]
        public int A { get; set; }
        [Parameter(Position = 2)]
        public int B { get; set; }

        protected override void ProcessRecord()
        {
            WriteObject(A + B);
        }
    }
}

MyPSModule.psd1

@{
    GUID="6D19F5DE-5C33-4101-8533-95288F00E38A"
    Author=""
    CompanyName=""
    Copyright=""
    ModuleVersion="0.0.0.1"
    CmdletsToExport= "My-Add" # 导出的命令,用于程序集
    FunctionsToExport= ""
    AliasesToExport= ""
    NestedModules="MyPSModule.dll" # 引入的程序集
    CompatiblePSEditions = @() #
}

将模块放到模块目录,可以直接使用。

也可以使用Import-Module从其他目录中加载模块。

My-Add 100 200

管理单元(PSSnapin)

PowerShell1.0中不存在模块,使用管理单元(PSSnapin)扩展功能。

现在推荐使用模块,而非管理单元。模块有以下优点:

查看管理单元

使用Get-PSSnapin可以查看已加载的管理单元。

Get-PSSnapin

使用Get-PSSnapin -Registered,可以查看所有已注册的管理单元。

添加管理单元

使用Add-PSSnapin命令可以添加已注册的管理单元。

Add-PSSnapin SqlServerCmdletSnapin100 #

添加管理单元后,可以使用其中的命令。

Invoke-SqlCmd -UserName "sa" -Password "***" -Query "select * from sys.databases" | select name

要使用管理单元中的命令,必须事先添加,而不能像模块一样可以按需加载。

删除管理单元

使用Remove-PSSnapin命令可以删除已添加的管理单元。

编写管理单元

管理单元是一个程序集,只能使用如C#等语言编写。

管理单元需要一个继承自PSSnapin类型的类,使用RunInstallerAttribute属性修饰。

PSSnapin类相当于模块的模块清单。

程序集中可以包括多个继承自Cmdlet类的命令。

编写好的管理单元程序集必须使用instalutil.exe程序安装,安装后才可以使用Add-PSSnapin加载使用。

创建一个C#类库,名称是MyPSSnapi。 引用System.Management.Automation.dll程序集。

MyPSSnapin.cs

using System;
using System.ComponentModel;
using System.Management.Automation;

namespace MyPSSnapin
{
    [RunInstaller(true)]
    public class MyPSSnapin : PSSnapIn
    {
        public override String Description => "My Description";

        public override String Name => "MyPSSnapin";

        public override String Vendor => "";
    }
}

MyAdd.cs

using System.Management.Automation;

namespace MyPSSnapin
{
    [Cmdlet("My", "Add")]
    public class MyAdd : Cmdlet
    {
        [Parameter(Position = 1)]
        public int A { get; set; }
        [Parameter(Position = 2)]
        public int B { get; set; }

        protected override void ProcessRecord()
        {
            WriteObject(A + B);
        }
    }
}

使用instalutil.exe MyPSSnapin.dll命令,可以注册管理单元。

注册后,使用Add-PSSnapin MyPSSnapin命令,可以加载管理单元。

加载后,使用My-Add 100 200,可以使用其中的命令。

如果不需要该管理单元了,可以使用instalutil.exe /u MyPSSnapin.dll命令,卸载管理单元。