文章目录

  • 1. 了解 PowerShell
    • 1-1. 了解重要的 PowerShell 概念
      • 1-1-1. 输出是基于对象的
      • 1-1-2. 命令系列是可扩展的
      • 1-1-3. PowerShell 处理控制台输入和显示
      • 1-1-4. PowerShell 使用某些 C# 语法
    • 1-2. 了解 PowerShell 命令名称
      • 1-2-1. 学习传统 shell 中的命令名称
      • 1-2-2. Cmdlet 使用谓词-名词的名称来减少命令记忆
      • 1-2-3. Cmdlet 使用标准参数
        • 1-2-3-1. 帮助参数
        • 1-2-3-2. 通用参数
        • 1-2-3-3. 建议的参数名称
    • 1-3. 使用熟悉的命令名称
      • 1-3-1. 解释标准别名
      • 1-3-2. 创建新别名
    • 1-4. 获取详细的帮助信息
      • 1-4-1. 获取有关 cmdlet 的帮助
      • 1-4-2. 获取概念帮助
      • 1-4-3. 获取有关提供程序的帮助
      • 1-4-4. 获取有关脚本和函数的帮助
      • 1-4-5. 在线获取帮助
      • 1-4-6. 另请参阅
    • 1-5. 获取有关命令的信息
      • 1-5-1. 显示可用的命令类型
    • 1-6. 使用变量存储对象
      • 1-6-1. 创建变量
      • 1-6-2. 操作变量
      • 1-6-3. 使用 cmd.exe 变量
    • 1-7. 了解管道
      • 1-7-1. PowerShell 管道
      • 1-7-2. 管道中的对象
    • 1-8. 更多 PowerShell 学习
      • 1-8-1. 面向 PowerShell 用户的资源
      • 1-8-2. Channel 9 视频
      • 1-8-3. Microsoft Virtual Academy
      • 1-8-4. 面向 PowerShell 开发人员的资源
    • 1-9. 编写可移植模块
      • 1-9-1. 移植现有模块
        • 1-9-1-1. 移植 PSSnapIn
        • 1-9-1-2. .NET 可移植性分析器 (又称 APIPort)
      • 1-9-2. 创建新模块
        • 1-9-2-1. 安装 PowerShell Standard 模块模板
        • 1-9-2-2. 创建新模块项目
        • 1-9-2-3. 生成模块
        • 1-9-2-4. 测试模块
      • 1-9-3. .NET Standard 库
      • 1-9-4. PowerShell Standard 库
      • 1-9-5. 模块清单
        • 1-9-5-1. 指示与 Windows PowerShell 和 PowerShell Core 的兼容性
        • 1-9-5-2. 指示操作系统兼容性
      • 1-9-6. 本机库的依赖项
  • 2. 用PowerShell进行系统管理的示例脚本
    • 2-1. 使用对象
      • 2-1-1. 查看对象结构 (Get-Member)
      • 2-1-2. 选择对象部件 (Select-Object)
      • 2-1-3. 从管道中删除对象 (Where-Object)
        • 2-1-3-1. 使用 Where-Object 执行简单测试
        • 2-1-3-2. 基于对象属性进行筛选
      • 2-1-4. 对对象进行排序
        • 2-1-4-1. 基本排序
        • 2-1-4-2. 使用哈希表
        • 2-1-4-3. 提示
      • 2-1-5. 为多个对象重复执行任务 (ForEach-Object)
      • 2-1-6. 创建 .NET 和 COM 对象 (New-Object)
        • 2-1-6-1. 使用 New-Object 进行事件日志访问
          • 2-1-6-1-1. 将构造函数与 New-Object 一起使用
          • 2-1-6-1-2. 在变量中存储对象
          • 2-1-6-1-3. 使用 New-Object 访问远程事件日志
          • 2-1-6-1-4. 使用对象方法清除事件日志
        • 2-1-6-2. 使用 New-Object 创建 COM 对象
        • 2-1-6-3. 使用 WScript.Shell 创建桌面快捷方式
        • 2-1-6-4. 从 Windows PowerShell 使用 Internet Explorer
        • 2-1-6-5. 获取有关 .NET Framework 包装的 COM 对象的警告
      • 2-1-7. 使用静态类和方法
        • 2-1-7-1. 使用 System.Environment 获取环境数据
          • 2-1-7-1-1. 引用静态的 System.Environment 类
          • 2-1-7-1-2. 显示 System.Environment 的静态属性
        • 2-1-7-2. 使用 System.Math 做数学
    • 2-2. 管理计算机
      • 2-2-1. 更改计算机状态
        • 2-2-1-1. 锁定计算机
        • 2-2-1-2. 注销当前会话
        • 2-2-1-3. 关闭或重启计算机
      • 2-2-2. 收集有关计算机的信息
        • 2-2-2-1. 列出桌面设置
        • 2-2-2-2. 列出 BIOS 信息
        • 2-2-2-3. 列出处理器信息
        • 2-2-2-4. 列出计算机制造商和型号
        • 2-2-2-5. 列出已安装的修补程序
        • 2-2-2-6. 列出操作系统版本信息
        • 2-2-2-7. 列出本地用户和所有者
        • 2-2-2-8. 获取可用磁盘空间
        • 2-2-2-9. 获取登录会话信息
        • 2-2-2-10. 获取登录到计算机的用户
        • 2-2-2-11. 获取计算机的本地时间
        • 2-2-2-12. 显示服务状态
      • 2-2-3. 使用 FilterHashtable 创建 Get-WinEvent 查询
        • 2-2-3-1. 关于枚举的博客文章
        • 2-2-3-2. 哈希表键值对
        • 2-2-3-3. 使用哈希表生成查询
        • 2-2-3-4. 在哈希表中使用枚举值
          • 2-2-3-4-1. Keywords 静态属性值(可选)
        • 2-2-3-5. 按事件 ID 筛选
        • 2-2-3-6. 按级别筛选
          • 2-2-3-6-1. 枚举中的 Level 静态属性(可选)
    • 2-3. 管理进程与服务
      • 2-3-1. 使用 Process Cmdlet 管理进程
        • 2-3-1-1. 获取进程 (Get-Process)
          • 2-3-1-1-1. 以下命令将获取空闲进程:
        • 2-3-1-2. 停止进程 (Stop-Process)
        • 2-3-1-3. 停止所有其他 Windows PowerShell 会话
        • 2-3-1-4. 启动、调试和等待进程
        • 2-3-1-5. 另请参阅
      • 2-3-2. 管理服务
        • 2-3-2-1. 获取服务
        • 2-3-2-2. 获取必需和从属服务
        • 2-3-2-3. 停止、启动、暂停和重启服务
        • 2-3-2-4. 设置服务属性
        • 2-3-2-5. 另请参阅
      • 2-3-3. 管理 Windows PowerShell 驱动器
        • 2-3-3-1. 添加新的 Windows PowerShell 驱动器 (New-PSDrive)
        • 2-3-3-2. 删除 Windows PowerShell 驱动器 (Remove-PSDrive)
        • 2-3-3-3. 添加和删除 Windows PowerShell 之外的驱动器
      • 2-3-4. 在 Windows 中使用打印机
        • 2-3-4-1. 列出打印机连接
        • 2-3-4-2. 添加网络打印机
        • 2-3-4-3. 设置默认打印机
        • 2-3-4-4. 删除打印机连接
      • 2-3-5. 执行网络任务
        • 2-3-5-1. 列出计算机的 IP 地址
        • 2-3-5-2. 列出 IP 配置数据
        • 2-3-5-3. Ping 计算机
        • 2-3-5-4. 检索网络适配器属性
        • 2-3-5-5. 为网络适配器分配 DNS 域
        • 2-3-5-6. 执行 DHCP 配置任务
          • 2-3-5-6-1. 确定启用 DHCP 的适配器
          • 2-3-5-6-2. 检索 DHCP 属性
          • 2-3-5-6-3. 在每个适配器上启用 DHCP
          • 2-3-5-6-4. 释放和续订特定适配器上的 DHCP 租约
          • 2-3-5-6-5. 释放和续订所有适配器上的 DHCP 租约
        • 2-3-5-7. 创建网络共享
        • 2-3-5-8. 删除网络共享
        • 2-3-5-9. 连接 Windows 可访问网络驱动器
      • 2-3-6. 使用软件安装
        • 2-3-6-1. 列出 Windows Installer 应用程序
        • 2-3-6-2. 列出所有可卸载的应用程序
        • 2-3-6-3. 安装应用程序
        • 2-3-6-4. 删除应用程序
        • 2-3-6-5. 升级 Windows Installer 应用程序
      • 2-3-7. 从正在运行的进程解码 PowerShell 命令
        • 2-3-7-1. 创建一个长时间运行的进程
        • 2-3-7-2. 查看进程
  • 3. Get the current process
  • 4. Convert the Base 64 string to a Byte Array
  • 5. Convert the Byte Array to a string
  • 6. Add the decoded command back to the object
    • 6-1. 管理驱动器与文件
      • 6-1-1. 管理当前位置
        • 6-1-1-1. 获取你的当前位置 (Get-Location)
        • 6-1-1-2. 设置你的当前位置 (Set-Location)
        • 6-1-1-3. 保存和重新调用最近的位置(Push-Location 和 Pop-Location)
      • 6-1-2. 使用文件和文件夹
        • 6-1-2-1. 列出某个文件夹内的所有文件和文件夹
        • 6-1-2-2. 复制文件和文件夹
        • 6-1-2-3. 创建文件和文件夹
        • 6-1-2-4. 删除某个文件夹内的所有文件和文件夹
        • 6-1-2-5. 将本地文件夹映射为驱动器
        • 6-1-2-6. 将文本文件数据读取到数组中
      • 6-1-3. 使用文件、文件夹和注册表项
        • 6-1-3-1. 枚举文件、文件夹和注册表项 (Get-ChildItem)
          • 6-1-3-1-1. 列出所有包含的项 (-Recurse)
          • 6-1-3-1-2. 按名称筛选项 (-Name)
          • 6-1-3-1-3. 强制列出隐藏的项 (-Force)
          • 6-1-3-1-4. 使用通配符匹配项名称
          • 6-1-3-1-5. 排除项 (-Exclude)
          • 6-1-3-1-6. 混合使用 Get-ChildItem 参数
      • 6-1-4. 使用注册表条目
        • 6-1-4-1. 列出注册表条目
        • 6-1-4-2. 获取单个注册表条目
        • 6-1-4-3. 获取单个注册表条目
        • 6-1-4-4. 创建新注册表条目
        • 6-1-4-5. 重命名注册表条目
        • 6-1-4-6. 删除注册表条目
      • 6-1-5. 使用注册表项
        • 6-1-5-1. 列出注册表项的所有子项
        • 6-1-5-2. 复制项
        • 6-1-5-3. 创建项
        • 6-1-5-4. 删除项
        • 6-1-5-5. 删除特定项下的所有项
    • 6-2. 使用输出
      • 6-2-1. 使用 Out-* Cmdlet 重定向数据
        • 6-2-1-1. 分页控制台输出 (Out-Host)
        • 6-2-1-2. 放弃输出 (Out-Null)
        • 6-2-1-3. 打印数据 (Out-Printer)
        • 6-2-1-4. 保存数据 (Out-File)
      • 6-2-2. 使用格式命令更改输出视图
        • 6-2-2-1. 将 Format-Wide 用于 Single-Item 输出
          • 6-2-2-1-1. 使用列控制 Format-Wide 显示
        • 6-2-2-2. 将 Format-List 用于列表视图
          • 6-2-2-2-1. 通过将 Format-List 与通配符搭配使用获取详细信息
        • 6-2-2-3. 将 Format-Table 用于表格输出
          • 6-2-2-3-1. 改进 Format-Table 输出(自动调整大小)
          • 6-2-2-3-2. 让列中的 Format-Table 输出自动换行 (Wrap)
          • 6-2-2-3-3. 组织选项卡输出 (-GroupBy)
    • 6-3. 创建 UI 元素
      • 6-3-1. 创建自定义输入框
        • 6-3-1-1. 创建自定义图形输入框
        • 6-3-1-2. 另请参阅
      • 6-3-2. 创建图形日期选取器
        • 6-3-2-1. 创建图形日期选取器控件
        • 6-3-2-2. 另请参阅
      • 6-3-3. 多选列表框
        • 6-3-3-1. 创建允许进行多选的列表框控件
        • 6-3-3-2. 另请参阅
      • 6-3-4. 从列表框中选择项
        • 6-3-4-1. 创建一个列表框控件,并从中选择项
        • 6-3-4-2. 另请参阅

1. 了解 PowerShell

1-1. 了解重要的 PowerShell 概念

PowerShell 设计集成了很多不同环境的概念。 具有 shell 或编程环境经验的人会熟悉几个概念。 但是,很少有人会了解所有这些概念。 查看其中一些概念可获得有关 Shell 的有用概述。

1-1-1. 输出是基于对象的

不同于传统的命令行接口,PowerShell cmdlet 旨在处理对象。 对象是结构化信息,不仅仅是屏幕上出现的字符串。 命令输出会始终包含你在需要时可使用的额外信息。

如果以前使用过文本处理工具来处理数据,那么在 PowerShell 中使用时,会发现它们的行为有所不同。 在大多数情况下,不需要文本或文本处理工具来提取特定信息。 可以使用标准 PowerShell 对象语法直接访问数据的各部分。

1-1-2. 命令系列是可扩展的

接口(如 cmd.exe )不提供可直接扩展内置命令集的方法。 可以创建在 cmd.exe 中运行的外部命令行工具。 但这些外部工具不包含服务,例如帮助集成。 cmd.exe 不会自动知道这些外部工具是否为有效命令。

PowerShell 中的本机命令称为 cmdlet (读作 command-let)。 可以使用编译的代码或脚本创建自己的 cmdlet 模块和函数。 模块可以向 shell 添加 cmdlet 和提供程序。 PowerShell 还支持类似于 UNIX shell 脚本和 cmd.exe 批处理文件的脚本。

1-1-3. PowerShell 处理控制台输入和显示

当你键入命令时,PowerShell 会始终直接处理命令行输入。 PowerShell 还会对你在屏幕上看到的输出进行格式设置。 这种差异非常重要,因为它减少了每个 cmdlet 必须完成的工作量。 它确保你始终可以使用任何 cmdlet 以相同的方式执行操作。Cmdlet 开发人员无需编写代码来分析命令行参数或格式化输出。

传统的命令行工具有自己的用于请求和显示帮助的方案。 某些命令行工具使用 /? 来触发显示帮助内容;其他工具则使用 -? 、 /H 或 // 。 有些工具会在 GUI 窗口而不是在控制台显示区域显示帮助。 如果你使用的参数有误,该工具可能会忽略你键入的内容并自动开始执行任务。 由于 PowerShell 会自动分析并处理命令行,-? 参数始终意味着“显示关于此命令的帮助”。

备注:如果在 PowerShell 中运行图形应用程序,将随即打开该应用程序的窗口。PowerShell 仅会在处理你提供的命令行输入或返回到控制台窗口中的应用程序输出时才会进行干预。 它不会内在地影响应用程序的工作方式。

1-1-4. PowerShell 使用某些 C# 语法

PowerShell 基于 .NET Framework 构建。 它与 C# 编程语言共享一些语法功能和关键字。 了解 PowerShell 后,就可以更轻松地了解 C#。 如果你已经熟悉了 C#,这种相似性就可以使 PowerShell 的学习变得容易许多。

1-2. 了解 PowerShell 命令名称

学习命令和参数的名称需要在了解大多数命令行接口方面投入大量的时间。 问题是模式很少。 记忆是了解需要定期使用的命令和参数的唯一方法。

使用新命令或参数时,不能总是使用已经知道的内容。 必须找到并了解一个新名称。 按照惯例,命令行界面从一小组工具开始,并随着增量添加而增长。 这就很容易理解命令行界面为什么没有标准结构。 这似乎是命令名称的逻辑,因为每个命令都是一个单独的工具。 PowerShell 有一种更好的方法来处理命令名称。

1-2-1. 学习传统 shell 中的命令名称

大多数命令用于管理操作系统或应用程序中的元素,如服务或进程。 命令具有多个名称,这些名称可能或可能不会纳入一个系列。 例如,在 Windows 系统中,你可以使用 net startnet stop 命令来启动和停止服务。 Sc.exe 是另一个适用于 Windows 的服务控制工具。 该名称不会纳入 net.exe 服务命令的命名模式。 对于流程管理,Windows 使用 tasklist.exe 命令列出进程,使用 taskkill.exe 命令终止进程。

另外,这些命令的参数规范不规则。 不能使用 net start 命令来启动远程计算机上的服务。 sc.exe 命令可以启动远程计算机上的服务。 但是,若要指定远程计算机,则必须在其名称前添加双反斜杠作为前缀。 若要在名为 DC01 的远程计算机上启动后台处理程序服务,请键入 sc.exe \\DC01 start spooler。 若要列出在 DC01 上运行的任务,请使用 /S 参数和不带反斜杠的计算机名称。 例如,tasklist /S DC01

备注:在 PowerShell v6 之前,scSet-Content cmdlet 的别名。 因此,若要在 v6 之前的 PowerShell 版本中运行 sc.exe 命令 ,必须使用包含文件扩展名 exe 的完整文件名 sc.exe 。

服务和进程是计算机上具有明确定义的生命周期的可管理元素的示例。 你可能想要启动或停止服务或进程,或获取所有当前正在运行的服务或进程的列表。 虽然它们之间存在重要的技术差异,但在服务和进程上执行的操作在概念上是相同的。 此外,通过指定参数自定义操作所做的选择从概念上讲也是相似的。

PowerShell 利用这些相似之处减少了解和使用 cmdlet 时需要知道的不同名称的数量。

1-2-2. Cmdlet 使用谓词-名词的名称来减少命令记忆

PowerShell 使用“谓词 - 名词”命名系统。 每个 cmdlet 名称都由一个标准谓词、连字符和特定名词组成。 PowerShell 谓词并不始终是英文谓词,但在 PowerShell 中表达特定的操作。 名词非常类似于任何语言中的名词。 它们描述在系统管理中十分重要的特定类型的对象。 通过查看一些示例,可以很容易地演示这些包含两个部分的名称如何减少学习的负担。

PowerShell 有一套推荐的标准谓词。 名词所受限制较少,但它们应始终描述谓词作用的对象。 PowerShell 具有 Get-ProcessStop-ProcessGet-ServiceStop-Service 等命令。

对于包含两个名词和两个谓词的此示例,一致性并未简化太多学习。 将该列表扩展为一组标准化的 10 个谓词和 10 个名词。 现在你只需要了解 20 个词。 但是这些词可以组合形成 100 个不同的命令名称。

通过阅读其名称,可以很容易地了解 PowerShell 命令的作用。 关闭计算机的命令是 Stop-Computer。 列出网络上所有计算机的命令是 Get-Computer。 获取系统日期的命令是 Get-Date

可以使用 Get-Command 的 Verb 参数列出包含特定谓词的所有命令。 例如,若要查看使用谓词 Get 的所有 cmdlet,键入:

Get-Command -Verb Get

CommandType Name Definition
Cmdlet Get-Acl Get-Acl [[-Path] ]…
Cmdlet Get-Alias Get-Alias [[-Name] PS> Get-Command -Verb Get
CommandType Name Definition
Cmdlet Get-Acl Get-Acl [[-Path] <String[]>]…
Cmdlet Get-Alias Get-Alias [[-Name] <String[]…
Cmdlet Get-AuthenticodeSignature Get-AuthenticodeSignature [-…
Cmdlet Get-ChildItem Get-ChildItem [[-Path] <Stri…

使用 Noun 参数查看将对同一类型的对象产生影响的命令系列。 例如,运行以下命令可以查看用于管理服务的命令:

Get-Command -Noun Service

CommandType Name Definition
Cmdlet Get-Service Get-Service [[-Name] …
Cmdlet Restart-Service Restart-Service [-Name] …
Cmdlet Start-Service Start-Service [-Name] PS> Get-Command -Noun Service
CommandType Name Definition
Cmdlet Get-Service Get-Service [[-Name] <String…
Cmdlet New-Service New-Service [-Name] …
Cmdlet Restart-Service Restart-Service [-Name] <Str…
Cmdlet Resume-Service Resume-Service [-Name] <Stri…
Cmdlet Set-Service Set-Service [-Name] …
Cmdlet Start-Service Start-Service [-Name] <Strin…
Cmdlet Stop-Service Stop-Service [-Name] <String…
Cmdlet Suspend-Service Suspend-Service [-Name] <Str…

1-2-3. Cmdlet 使用标准参数

如前文所述,在传统命令行接口中使用的命令并不总是具有一致的参数名称。 参数通常是易于键入但对新用户来说不能轻松理解的单个字符或缩写词。

不同于大多数其他传统的命令行接口,PowerShell 直接处理参数,并使用参数的这种直接访问权限以及开发人员指南标准化参数名称。 本指南建议但不会保证每个 cmdlet 都符合标准。

PowerShell 还标准化参数分隔符。 使用 PowerShell 命令,参数名称前面始终带有“-”。 请考虑以下示例:
Get-Command -Name Clear-Host

参数的名称为 Name ,但在命令行上用作参数时,将其键入为 -Name

以下是标准参数名称和用法的一些一般特征。

1-2-3-1. 帮助参数

在任何 cmdlet 上指定 -? 参数时,PowerShell 将显示该 cmdlet 的帮助。 未执行此 cmdlet。

1-2-3-2. 通用参数

PowerShell 有几个通用参数 。 这些参数由 PowerShell 引擎控制。 通用参数的行为方式始终相同。 通用参数有 WhatIf、Confirm、Verbose、Debug、Warn、ErrorAction、ErrorVariable、OutVariable 和 OutBuffer

1-2-3-3. 建议的参数名称

对于类似的参数,PowerShell 核心 cmdlet 使用标准名称。 尽管不强制使用这些标准名称,但是具有明确的指南来鼓励进行标准化。

例如,指示计算机的参数的建议名称是 ComputerName ,而不是 Server、Host、System、Node 或其他常见的备选单词。 其他重要的建议参数名称是 Force 、Exclude 、Include 、PassThru 、Path 和 CaseSensitive 。

1-3. 使用熟悉的命令名称

PowerShell 支持别名以通过备用名称引用命令。 别名允许具有其他 Shell 经验的用户使用其已知的常见命令名称在 PowerShell 中执行类似操作。

别名将新名称与其他命令关联。 例如,PowerShell 具有名为 Clear-Host 的内部函数,该函数清空输出窗口。 可以在命令提示符下键入 cls 或 clear 别名。 PowerShell 解释这些别名并运行 Clear-Host 函数。

此功能可帮助用户了解 PowerShell。 首先,大多数 cmd.exe 和 Unix 用户都要使用大量命令,用户通过名称已经了解这些命令。 PowerShell 等效项可能不会产生相同的结果。 但是,结果非常接近,用户可以在不知道 PowerShell 命令名称的情况下完成工作。 学习新的命令 shell 时,“手指记忆”是另一个令人沮丧的主要原因。 如果你已使用 cmd.exe 多年,则可能会条件反射地键入 cls 命令来清除屏幕。 如果没有 Clear-Host 的别名,则会收到一条错误消息,并且不知道如何操作才能清除输出。

以下列表显示可在 PowerShell 中使用的常见 cmd.exe 和 UNIX 命令:

命令 命令 命令 命令
cat dir mount rm
cd echo move rmdir
chdir erase popd sleep
clear h ps sort
cls history pushd tee
copy kill pwd type
del lp r write
diff ls ren

Get-Alias cmdlet 显示与别名关联的本机 PowerShell 命令的真实名称。
PS> Get-Alias cls
Output

CommandType Name Version Source
Alias cls -> Clear-Host

1-3-1. 解释标准别名

我们之前描述的别名时为了实现与其他命令 shell 的名称兼容性而设计的。 PowerShell 中内置的大多数别名都是为了实现简洁性而设计的。 较短的名称更容易键入,但如果你不知道它们所指的是什么,则难以理解。

PowerShell 别名尝试兼顾清晰度和简洁性。 PowerShell 为常见名词和谓词使用一组标准的别名。

示例缩写:

名词或谓词 缩写
Get g
Set s
Item i
Location l
Command cm
Alias al

了解简写名称后,这些别名是可以理解的。

表 3

Cmdlet 名称 Alias
Get-Item gi
Set-Item si
Get-Location gl
Set-Location sl
Get-Command gcm
Get-Alias gal

熟悉 PowerShell 别名后,就很容易猜到 sal 别名指的是 Set-Alias

1-3-2. 创建新别名

可以使用 Set-Alias cmdlet 创建自己的别名。 例如,以下语句创建之前讨论的标准 cmdlet 别名:

Set-Alias -Name gi -Value Get-Item

Set-Alias -Name si -Value Set-Item

Set-Alias -Name gl -Value Get-Location

Set-Alias -Name sl -Value Set-Location

Set-Alias -Name gcm -Value Get-Command

在内部,PowerShell 会在启动过程中使用类似的命令,但这些别名不可更改。 如果尝试执行其中一个命令,你将收到一个错误,该错误说明别名无法进行修改。 例如:
PS> Set-Alias -Name gi -Value Get-Item

Set-Alias : Alias is not writeable because alias gi is read-only or constant and cannot be written to.

At line:1 char:10

  • Set-Alias <<<< -Name gi -Value Get-Item

1-4. 获取详细的帮助信息

PowerShell 包含了详细的帮助文章,其中解释了 PowerShell 概念和 PowerShell 语言。 还有针对每个 cmdlet 和提供程序的帮助文章,以及针对许多函数和脚本的帮助文章。

可以在命令提示符下显示这些帮助文章,或在 PowerShell 文档中在线查看这些文章的最近更新版本。

1-4-1. 获取有关 cmdlet 的帮助

若要获取有关 PowerShell cmdlet 的帮助,请使用 Get-Help cmdlet。 例如,若要获取 Get-ChildItem cmdlet 的帮助,请键入:Get-Help Get-ChildItem

或 Get-ChildItem -?

甚至可以获取有关 Get-Help cmdlet 的帮助。 例如:
Get-Help Get-Help

若要在会话中获取所有 cmdlet 帮助文章的列表,请键入: Get-Help -Category Cmdlet

若要一次显示每篇帮助文章的一页,请使用 help 函数或其别名 man。 例如,若要显示 Get-ChildItem cmdlet 的帮助信息,请键入:man Get-ChildItem


help Get-ChildItem

若要显示详细信息,请使用 Get-Help cmdlet 的 Detailed 参数。 例如,若要获取有关 Get-ChildItem cmdlet 的详细信息,请键入:Get-Help Get-ChildItem -Detailed

若要显示帮助文章中的所有内容,请使用 Get-Help cmdlet 的 Full 参数。 例如,若要显示 Get-ChildItem cmdlet 的帮助文章中的所有内容,请键入:Get-Help Get-ChildItem -Full

若要获取有关 cmdlet 的参数的详细帮助,请使用 Get-Help cmdlet 的 Parameter 参数。 例如,若要获取 Get-ChildItem cmdlet 的所有参数的详细帮助,请键入:Get-Help Get-ChildItem -Parameter *

若要仅显示帮助文章中的示例,请使用 Get-Help 的 Examples 参数。 例如,若要仅显示 Get-ChildItem cmdlet 的帮助文章中的示例,请键入:Get-Help Get-ChildItem -Examples

有关如何为你编写的 cmdlet 编写帮助文章的信息,请参阅如何编写 Cmdlet 帮助主题。

1-4-2. 获取概念帮助

Get-Help cmdlet 也会显示有关 PowerShell 中的概念文章(包括有关 PowerShell 语言的文章)的信息。 概念帮助文章以“about_”前缀开头,例如 about_line_editing。(概念文章的名称必须用英文输入,即使在非英语版本的 PowerShell 中也是如此。)

若要显示概念文章的列表,请键入:Get-Help about_*

若要显示某一特别的帮助文章,请键入文章名称,例如:Get-Help about_command_syntax

Get-Help 的参数(例如 Detailed 、Parameter 和 Examples )对概念帮助文章的显示没有影响。

1-4-3. 获取有关提供程序的帮助

Get-Help cmdlet 显示有关 PowerShell 提供程序的信息。 若要获取有关提供程序的帮助,请键入 Get-Help,后跟提供程序名称。 例如,若要获取有关 Registry 提供程序的帮助,请键入:Get-Help registry

若要获取会话中的所有提供程序帮助文章的列表,请键入 Get-Help -Category provider

Get-Help 的参数(例如 Detailed 、Parameter 和 Examples )对提供程序帮助文章的显示没有影响。

1-4-4. 获取有关脚本和函数的帮助

PowerShell 中的许多脚本和函数都有帮助文章。 使用 Get-Help cmdlet 显示脚本和函数的帮助文章。

若要显示有关某个函数的帮助,请键入 Get-Help,后跟函数名称。 例如,若要获取有关 Disable-PSRemoting 函数的帮助,请键入:Get-Help Disable-PSRemoting

若要显示有关某个脚本的帮助,请键入该脚本文件的路径。 如果该脚本不位于路径环境变量中列出的路径中,则必须使用完全限定的路径。

例如,如果名为“TestScript.ps1”的脚本位于 C:\PS-Test 目录中,要显示有关该脚本的帮助文章,请键入:Get-Help c:\ps-test\TestScript.ps1

用于显示 cmdlet 帮助的参数也适用于脚本和函数帮助。 但是,在运行 Get-Help *时,不会显示函数和脚本的帮助。

有关为函数和脚本编写帮助文章的信息,请参阅以下文章:

  • about_Functions

  • about_Scripts

  • about_Comment_Based_Help

1-4-5. 在线获取帮助

在线查看帮助文章是获得帮助的最佳方式之一。 在线文章更易于更新并提供最新内容。

若要在线获取帮助,请使用 Get-Help cmdlet 的 Online 参数。 PowerShell 附带的所有帮助文章(包括提供程序帮助和概念(关于)帮助文章),都可以在 PowerShell 文档中在线获取。

备注:不能将 Online 参数用于概念 (about_*) 或提供程序帮助文章。 在线帮助一个可选功能,并不适用于每一个 cmdlet、函数或脚本。

例如,若要获取有关 Get-ChildItem cmdlett 的帮助文章的在线版本,请键入: Get-Help Get-ChildItem -Online

PowerShell 在默认浏览器中打开文章。 如果该帮助文章支持在线帮助,也可以查看该帮助文章的 URL。 URL 将显示在帮助文章的“相关链接”部分中。

例如,若要查看 Add-Computer cmdlet 的在线版本的 URL,请键入: Get-Help Add-Computer

该文章“相关链接”部分的第一行如下所示。
Output

Online version: https://go.microsoft.com/fwlink/?LinkId=821564

有关如何提供帮助文章的在线支持的信息,请参阅 about_Comment_Based_Help。

1-4-6. 另请参阅

  • about_Functions

  • about_Scripts

  • about_Comment_Based_Help

  • Get-Help

1-5. 获取有关命令的信息

PowerShell Get-Command 显示在当前会话中可用的命令。 运行 Get-Command cmdlet 时,会看到类似于以下输出的内容:

CommandType Name Version Source
Cmdlet Add-Computer 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Add-Content 3.1.0.0 Microsoft.PowerShell.Management
Cmdlet Add-History 3.0.0.0 Microsoft.PowerShell.Core
Cmdlet Add-JobTrigger 1.1.0.0 PSScheduledJob
Cmdlet Add-LocalGroupMember 1.0.0.0 Microsoft.PowerShell.LocalAccounts
Cmdlet Add-Member 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet Add-PSSnapin 3.0.0.0 Microsoft.PowerShell.Core
Cmdlet Add-Type 3.1.0.0 Microsoft.PowerShell.Utility

该输出与 cmd.exe 的帮助输出非常相似:内部命令的表格式摘要。 在如上所示的 Get-Command 命令输出摘录中,显示的每个命令都具有 Cmdlet 的 CommandType。 cmdlet 是 PowerShell 的内部命令类型。 此类型大致对应于 cmd.exe 中的 dir 和 cd 等命令,或者像 bash 这样的 Unix shell 的内置命令。

Get-Command cmdlet 具有可返回每个 cmdlet 语法的 Syntax 参数。 下面的示例演示如何获取 Get-Help cmdlet 的语法:
Get-Command Get-Help -Syntax
output

Get-Help [[-Name] ] [-Path ] [-Category <String[]>] [-Component <String[]>] [-Functionality <String[]>] [-Role <String[]>] [-Full] [-Online] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ]

Get-Help [[-Name] ] [-Path ] [-Category <String[]>] [-Component <String[]>] [-Functionality <String[]>] [-Role <String[]>] [-Detailed] [-Online] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ]

Get-Help [[-Name] ] [-Path ] [-Category <String[]>] [-Component <String[]>] [-Functionality <String[]>] [-Role <String[]>] [-Examples] [-Online] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ]

Get-Help [[-Name] ] [-Path ] [-Category <String[]>] [-Component <String[]>] [-Functionality <String[]>] [-Role <String[]>] [-Parameter ] [-Online] [-Verbose] [-Debug] [-ErrorAction ] [-WarningAction ] [-ErrorVariable ] [-WarningVariable ] [-OutVariable ] [-OutBuffer ]

1-5-1. 显示可用的命令类型

Get-Command 命令仅列出当前会话中的 cmdlet。 实际上,PowerShell 支持几种其他类型的命令:

  • 别名

  • 功能

  • 脚本

外部可执行文件,或具有已注册的文件类型处理程序的文件也被归类为命令。

若要获取会话中的所有命令,请键入:
Get-Command *

此列表包含搜索路径中的外部命令,因此它可能包含数千个项。 查看一组缩减的命令更加有用。

备注:星号 () 用于 PowerShell 命令参数中的通配符匹配。 * 表示“匹配一个或多个任意字符”。 可以键入 Get-Command a 查找所有以字母“a”开头的命令。 与 cmd.exe 中的通配符匹配不同,PowerShell 的通配符还会匹配句点。

使用 Get-Command 的 CommandType 参数可以获取其他类型的本机命令。 cmdlet。

若要获取命令别名(即命令的已分配昵称),请键入: Get-Command -CommandType Alias

若要获取当前会话中的函数,请键入: Get-Command -CommandType Function

若要显示 PowerShell 搜索路径中的脚本,请键入: Get-Command -CommandType Script

1-6. 使用变量存储对象

PowerShell 处理对象。 使用 PowerShell 可以创建称为“变量”的命名对象。 变量名称可以包含下划线字符和任何字母数字字符。 在 PowerShell 中使用时,始终使用变量名称后跟的 $ 字符指定变量。

1-6-1. 创建变量

可以通过键入有效的变量名称来创建变量:
PS> $loc

此示例不会返回任何结果,因为 $loc 不具有值。 你可以在同一步骤中创建变量并为其赋值。 如果不存在,PowerShell 将仅创建变量。 否则,它将指定的值分配给现有变量。 下面的示例将当前位置存储在变量 $loc 中:
$loc = Get-Location

键入此命令时,PowerShell 不会显示任何输出。 PowerShell 将“Get-Location”的输出发送到 $loc。 在 PowerShell 中,未分配或未重定向的数据将发送到屏幕。 键入 $loc 将显示当前位置:
PS> $loc

Path


C:\temp

可以使用 Get-Member 显示有关变量内容的信息。 Get-Member 表示 $loc 是 PathInfo 对象,类似于来自 Get-Location 的输出:
PS> $loc | Get-Member -MemberType Property
TypeName: System.Management.Automation.PathInfo

Name MemberType Definition
Drive Property System.Management.Automation.PSDriveInfo Drive {get;}
Path Property System.String Path {get;}
Provider Property System.Management.Automation.ProviderInfo Provider {…
ProviderPath Property System.String ProviderPath {get;}

1-6-2. 操作变量

PowerShell 提供多个用以操作变量的命令。 你可以通过键入以下内容看到可读形式的完整列表:
Get-Command -Noun Variable | Format-Table -Property Name,Definition -AutoSize -Wrap

PowerShell 还会创建系统定义的多个变量。 可以使用 Remove-Variable cmdlet 来删除当前会话中所有不受 PowerShell 控制的变量。 键入以下命令来清除所有变量:
Remove-Variable -Name * -Force -ErrorAction SilentlyContinue

运行上述命令后,Get-Variable cmdlet 显示 PowerShell 系统变量。

PowerShell 还会创建一个变量驱动器。 使用下面的示例显示使用变量驱动器的所有 PowerShell 变量:
Get-ChildItem variable:

1-6-3. 使用 cmd.exe 变量

PowerShell 可以使用任何 Windows 进程可用的相同环境变量,其中包括 cmd.exe 。 这些变量通过名为 env: 的驱动器公开。 可以通过键入以下命令查看这些变量:
Get-ChildItem env:

标准 *-Variable cmdlet 未设计为使用环境变量。 使用 env: 驱动器前缀访问环境变量。 例如,cmd.exe 中的 %SystemRoot% 变量包含操作系统的根目录名称。 在 PowerShell 中,使用 $env:SystemRoot 可访问相同的值。
PS> $env:SystemRoot
C:\WINDOWS

还可以从 PowerShell 内部创建和修改环境变量。 PowerShell 中的环境变量遵循操作系统中其他地方使用的环境变量的相同规则。 下面的示例创建一个新的环境变量:
$env:LIB_PATH=’/usr/local/lib’

尽管没有要求,但环境变量名称通常使用全部大写字母。

1-7. 了解管道

管道的行为就像一系列连接的管道段一样。 沿着管道移动的项会通过每个管道段。 若要在 PowerShell 中创建管道,请使用管道运算符“|”将命令连接在一起。 每个命令的输出都将被用作下一命令的输入。

用于管道的符号类似于其他 shell 中使用的符号。 初看起来 PowerShell 中管道的不同之处可能并不明显。 尽管你会在屏幕上看到文本,但 PowerShell 通过管道在命令之间传递对象,而不是文本。

1-7-1. PowerShell 管道

管道可能是命令行界面中使用的最有价值的概念。 如果使用得当,管道可以减少使用复杂命令的工作量,并且可以更轻松地查看命令的工作流程。 管道中的每个命令(称为管道元素)将其输出逐项传递到管道中的下一个命令。 命令不必一次处理多个项目。 结果是减少了资源消耗,并且能够立即开始获取输出。

例如,如果使用 Out-Host cmdlet 来强制逐页显示来自于另一个命令的输出,那么这一输出看起来就像分页显示在屏幕上的普通文本:
Get-ChildItem -Path C:\WINDOWS\System32 | Out-Host -Paging
Output

Directory: C:\WINDOWS\system32

Mode LastWriteTime Length Name
d----- 4/12/2018 2:15 AM 0409
d----- 5/13/2018 11:31 PM 1033
d----- 4/11/2018 4:38 PM AdvancedInstallers
d----- 5/13/2018 11:13 PM af-ZA
d----- 5/13/2018 11:13 PM am-et
d----- 4/11/2018 4:38 PM AppLocker
d----- 5/13/2018 11:31 PM appmgmt
d----- 7/11/2018 2:05 AM appraiser
d—s- 4/12/2018 2:20 AM AppV
d----- 5/13/2018 11:10 PM ar-SA
d----- 5/13/2018 11:13 PM as-IN
d----- 8/14/2018 9:03 PM az-Latn-AZ
d----- 5/13/2018 11:13 PM be-BY
d----- 5/13/2018 11:10 PM BestPractices
d----- 5/13/2018 11:10 PM bg-BG
d----- 5/13/2018 11:13 PM bn-BD
d----- 5/13/2018 11:13 PM bn-IN
d----- 8/14/2018 9:03 PM Boot
d----- 8/14/2018 9:03 PM bs-Latn-BA
d----- 4/11/2018 4:38 PM Bthprops
d----- 4/12/2018 2:19 AM ca-ES
d----- 8/14/2018 9:03 PM ca-ES-valencia
d----- 5/13/2018 10:46 PM CatRoot
d----- 8/23/2018 5:07 PM catroot2

next page; next line; Q quit

分页还会降低 CPU 利用率,因为准备好显示完整页面时,会转为处理 Out-Host cmdlet。 管道中位于前面的 cmdlet 暂停执行,直到输出的下一页可用。

通过比较以下命令可以看到管道对 Windows 任务管理器中的 CPU 和内存使用情况的影响:

Get-ChildItem C:\Windows -Recurse

Get-ChildItem C:\Windows -Recurse | Out-Host -Paging

备注:并非所有的 PowerShell 主机都支持 Paging 参数。 例如,当你尝试在 PowerShell ISE 中使用 Paging 参数时,会看到以下错误:

Output

out-lineoutput : The method or operation is not implemented.

At line:1 char:1

  • Get-ChildItem C:\Windows -Recurse | Out-Host -Paging

  • + CategoryInfo         : NotSpecified: (:) [out-lineoutput], NotImplementedException+ FullyQualifiedErrorId : System.NotImplementedException,Microsoft.PowerShell.Commands.OutLineOutputCommand

1-7-2. 管道中的对象

在 PowerShell 中运行 cmdlet 时,可以看到文本输出,因为必须在控制台窗口中以文本形式表示对象。 文本输出可能不会显示输出的对象的所有属性。

例如,请考虑 Get-Location cmdlet。 如果运行 Get-Location,而当前位置是 C 驱动器的根路径,将看到以下输出:
PS> Get-Location

Path


C:\

文本输出是信息摘要,而非 Get-Location 返回的对象的完整表示形式。 输出中的标题通过格式化屏幕显示数据的过程添加。

通过管道将输出传递到 Get-Member cmdlet 后,可以获取有关 Get-Location 返回的对象信息。
Get-Location | Get-Member
Output

TypeName: System.Management.Automation.PathInfo

Name MemberType Definition
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Drive Property System.Management.Automation.PSDriveInfo Drive {get;}
Path Property string Path {get;}
Provider Property System.Management.Automation.ProviderInfo Provider {get;}
ProviderPath Property string ProviderPath {get;}

Get-Location 返回 PathInfo 对象,其中包含当前路径和其他信息。

1-8. 更多 PowerShell 学习

1-8-1. 面向 PowerShell 用户的资源

除了命令行中提供的帮助之外,以下资源还为想运行 PowerShell 的用户提供了详细信息。

  • PowerShell 团队博客。 直接来自 PowerShell 产品团队的最佳学习资源。

  • 你好,脚本专家!博客文章以方案为核心,并且采用精彩且生动的方式编写。

  • 有关于使用 PowerShell 的问题? 与对 PowerShell Community 页面上列出的多个社区论坛之一具有相似兴趣的数百人联系。

1-8-2. Channel 9 视频

Channel 9 是我们的视频发布平台。 有数百个关于 PowerShell 的可用视频。 搜索“PowerShell”以查看哪些视频可用。

1-8-3. Microsoft Virtual Academy

Microsoft Virtual Academy 视频已移至 Channel 9。

  • Microsoft PowerShell 快速入门

  • 高级工具以及使用 PowerShell 3.0 编写脚本快速入门

  • 使用 Pester 测试 PowerShell

  • PowerShell Desired State Configuration (DSC) 入门

  • 高级 PowerShell DSC 和自定义资源

  • 使用 DSC 实现 SharePoint 自动化

1-8-4. 面向 PowerShell 开发人员的资源

以下资源提供可帮助开发人员创建他们自己的 PowerShell 模块、函数、cmdlet、提供程序和托管应用程序的资源。

  • PowerShell SDK

  • PowerShell SDK API 浏览器

1-9. 编写可移植模块

Windows PowerShell 是为 .NET Framework 编写的,而 PowerShell Core 是为 .NET Core 编写的。 可移植模块是同时适用于 Windows PowerShell 和 PowerShell Core 的模块。 虽然 .Net Framework 和 .Net Core 高度兼容,但它们之间的可用 API 有所不同。 Windows PowerShell 和 PowerShell Core 中的可用 API 也有所不同。 打算在这两种环境中使用的模块需要了解这些差异。

1-9-1. 移植现有模块

1-9-1-1. 移植 PSSnapIn

PowerShell SnapIns 在 PowerShell Core 中不受支持。 然而,将 PSSnapIn 转换为 PowerShell 模块非常简单。 通常,PSSnapIn 注册代码位于派生自 PSSnapIn 的类的单个源文件中。 从生成中删除此源文件;不再需要该文件。

使用 New-ModuleManifest 创建一个新的模块清单,进而无需 PSSnapIn 注册代码。PSSnapIn 中的某些值(例如 Description)可以在模块清单中重复使用。

模块清单中的 RootModule 属性应设置为实施 cmdlet 的程序集 (dll) 的名称。

1-9-1-2. .NET 可移植性分析器 (又称 APIPort)

若要移植为 Windows PowerShell 编写的模块以使用 PowerShell Core,可以从 .NET 可移植性分析器开始。 对编译后的程序集运行此工具,以确定模块中使用的 .NET API 是否与 .NET Framework、.NET Core 以及其他 .NET 运行时兼容。 工具将建议使用替代 API(若存在)。 否则,可能需要添加运行时检查并限制特定运行时中不可用的功能。

1-9-2. 创建新模块

如果创建一个新模块,建议使用 .NET CLI。

1-9-2-1. 安装 PowerShell Standard 模块模板

安装 .NET CLI 后,请安装模板库以生成一个简单的 PowerShell 模块。 该模块将与 Windows PowerShell、PowerShell Core、Windows、Linux 和 macOS 兼容。

下面的示例演示如何安装模板:
dotnet new -i Microsoft.PowerShell.Standard.Module.Template
output

Restoring packages for C:\Users\Steve.templateengine\dotnetcli\v2.1.302\scratch\restore.csproj…

Installing Microsoft.PowerShell.Standard.Module.Template 0.1.3.

Generating MSBuild file C:\Users\Steve.templateengine\dotnetcli\v2.1.302\scratch\obj\restore.csproj.nuget.g.props.

Generating MSBuild file C:\Users\Steve.templateengine\dotnetcli\v2.1.302\scratch\obj\restore.csproj.nuget.g.targets.

Restore completed in 1.66 sec for C:\Users\Steve.templateengine\dotnetcli\v2.1.302\scratch\restore.csproj.

Usage: new [options]

Options:

选项 作用
-h, --help Displays help for this command.
-l, --list Lists templates containing the specified name. If no name is specified, lists all templates.
-n, --name The name for the output being created. If no name is specified, the name of the current directory is used.
-o, --output Location to place the generated output.
-i, --install Installs a source or a template pack.
-u, --uninstall Uninstalls a source or a template pack.
–nuget-source Specifies a NuGet source to use during install.
–type Filters templates based on available types. Predefined values are “project”, “item” or “other”.
–force Forces content to be generated even if it would change existing files.
-lang, --language Filters templates based on language and specifies the language of the template to create.
Templates Short Name Language Tags
Console Application console [C#], F#, VB Common/Console
Class library classlib [C#], F#, VB Common/Library
PowerShell Standard Module psmodule [C#] Library/PowerShell/Module

1-9-2-2. 创建新模块项目

安装模板后,可以使用该模板创建一个新的 PowerShell 模块项目。 在此示例中,示例模块名为“myModule”。
mkdir myModule

Directory: C:\Users\Steve

Mode LastWriteTime Length Name


d----- 8/3/2018 2:41 PM myModule

PS> cd myModule

PS C:\Users\Steve\myModule> dotnet new psmodule

The template "PowerShell Standard Module" was created successfully.

Processing post-creation actions…

Running ‘dotnet restore’ on C:\Users\Steve\myModule\myModule.csproj…

Restoring packages for C:\Users\Steve\myModule\myModule.csproj…

Installing PowerShellStandard.Library 5.1.0.

Generating MSBuild file C:\Users\Steve\myModule\obj\myModule.csproj.nuget.g.props.

Generating MSBuild file C:\Users\Steve\myModule\obj\myModule.csproj.nuget.g.targets.

Restore completed in 1.76 sec for C:\Users\Steve\myModule\myModule.csproj.

Restore succeeded.

" style=“box-sizing: inherit; font-family: SFMono-Regular, Consolas, “Liberation Mono”, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;”>PS> mkdir myModule

Directory: C:\Users\Steve

Mode LastWriteTime Length Name


d----- 8/3/2018 2:41 PM myModule

PS> cd myModule

PS C:\Users\Steve\myModule> dotnet new psmodule

The template “PowerShell Standard Module” was created successfully.

Processing post-creation actions…

Running ‘dotnet restore’ on C:\Users\Steve\myModule\myModule.csproj…

Restoring packages for C:\Users\Steve\myModule\myModule.csproj…

Installing PowerShellStandard.Library 5.1.0.

Generating MSBuild file C:\Users\Steve\myModule\obj\myModule.csproj.nuget.g.props.

Generating MSBuild file C:\Users\Steve\myModule\obj\myModule.csproj.nuget.g.targets.

Restore completed in 1.76 sec for C:\Users\Steve\myModule\myModule.csproj.

Restore succeeded.

1-9-2-3. 生成模块

使用标准 .NET CLI 命令来生成项目。
dotnet build
output

dotnet build

Microsoft ® Build Engine version 15.7.179.6572 for .NET Core

Copyright © Microsoft Corporation. All rights reserved.

Restore completed in 76.85 ms for C:\Users\Steve\myModule\myModule.csproj.

myModule -> C:\Users\Steve\myModule\bin\Debug\netstandard2.0\myModule.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Time Elapsed 00:00:05.40

" style=“box-sizing: inherit; font-family: SFMono-Regular, Consolas, “Liberation Mono”, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;”>PS C:\Users\Steve\myModule> dotnet build

Microsoft ® Build Engine version 15.7.179.6572 for .NET Core

Copyright © Microsoft Corporation. All rights reserved.

Restore completed in 76.85 ms for C:\Users\Steve\myModule\myModule.csproj.

myModule -> C:\Users\Steve\myModule\bin\Debug\netstandard2.0\myModule.dll

Build succeeded.

0 Warning(s)

0 Error(s)

Time Elapsed 00:00:05.40

1-9-2-4. 测试模块

在生成模块之后,可以导入它并执行示例 cmdlet。


ipmo .\bin\Debug\netstandard2.0\myModule.dllTest-SampleCmdlet -?Test-SampleCmdlet -FavoriteNumber 7 -FavoritePet Cat

output

ipmo .\bin\Debug\netstandard2.0\myModule.dll

PS C:\Users\Steve\myModule> Test-SampleCmdlet -?

NAME

Test-SampleCmdlet

SYNTAX

Test-SampleCmdlet [-FavoriteNumber] [[-FavoritePet] {Cat | Dog | Horse}] []

ALIASES

None

REMARKS

None

PS C:\Users\Steve\myModule> Test-SampleCmdlet -FavoriteNumber 7 -FavoritePet Cat

FavoriteNumber FavoritePet


  7 Cat

" style=“box-sizing: inherit; font-family: SFMono-Regular, Consolas, “Liberation Mono”, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;”>PS C:\Users\Steve\myModule> ipmo .\bin\Debug\netstandard2.0\myModule.dll

PS C:\Users\Steve\myModule> Test-SampleCmdlet -?

NAME

Test-SampleCmdlet

SYNTAX

Test-SampleCmdlet [-FavoriteNumber] [[-FavoritePet] {Cat | Dog | Horse}] []

ALIASES

None

REMARKS

None

PS C:\Users\Steve\myModule> Test-SampleCmdlet -FavoriteNumber 7 -FavoritePet Cat

FavoriteNumber FavoritePet


  7 Cat

以下各节详细说明了此模板使用的一些技术。

1-9-3. .NET Standard 库

.NET Standard 是可在所有 .NET 实现中使用的 .NET API 的正式规范。 以 .NET Standard 为目标的托管代码适用于与该版本的 .NET Standard 兼容的 .NET Framework 和 .NET Core 版本。

备注:尽管 .Net Standard 中可能存在 API,但 .Net Core 中的 API 实现可能会在运行时引发 PlatformNotSupportedException,因此,要验证与 Windows PowerShell 和 PowerShell Core 的兼容性,最佳做法是在这两个环境中运行模块测试。 如果模块是跨平台的,还可以在 Linux 和 macOS 上运行测试。

以 .Net Standard 为目标有助于确保随着模块的发展,不会意外地将不兼容的 API 引入到模块中。 不兼容性是在编译时而不是运行时发现的。

但是,只要使用兼容 API,则不需要以 .NET Standard 为目标来让模块来同时适用于 Windows PowerShell 和 PowerShell Core。 中间语言 (IL) 在两个运行时之间是兼容的。 可面向 .Net Framework 4.6.1,它与 .Net Standard 2.0 兼容。 如果不使用 .Net Standard 2.0 之外的 API,模块将适用于 PowerShell Core 6,而无需重新编译。

1-9-4. PowerShell Standard 库

PowerShell Standard 库是 PowerShell API 的正式规范,适用于所有大于或等于该标准版本的 PowerShell 版本。

例如,PowerShell Standard 5.1 与 Windows PowerShell 5.1 和 PowerShell Core 6.0 或更新版本兼容。

建议使用 PowerShell Standard 库编译模块。 该库确保 API 同时适用于 Windows PowerShell 和 PowerShell Core 6 并可在两者中实现。 PowerShell Standard 旨在始终向前兼容。 使用 PowerShell Standard 库 5.1 生成的模块将始终与 PowerShell 的未来版本兼容。

1-9-5. 模块清单

1-9-5-1. 指示与 Windows PowerShell 和 PowerShell Core 的兼容性

在验证模块同时适用于 Windows PowerShell 和 PowerShell Core 之后,模块清单应使用 CompatiblePSEditions 属性显式指示兼容性。 值 Desktop 表示模块与 Windows PowerShell 兼容,而值 Core 表示模块与 PowerShell Core 兼容。 同时包含 DesktopCore 意味着该模块同时与 Windows PowerShell 和 PowerShell Core 兼容。

备注:Core 并不自动意味着模块与 Windows、Linux 和 macOS 兼容。 PowerShell v5 中引入了 CompatiblePSEditions 属性。 在 PowerShell v5 之前的版本中,将无法加载使用 CompatiblePSEditions 属性的模块清单。

1-9-5-2. 指示操作系统兼容性

首先,验证模块是否适用于 Linux和 macOS。 接下来,在模块清单中指示与这些操作系统的兼容性。 这使得用户在发布到 PowerShell 库时可以更轻松地找到适用于其操作系统的模块。

在模块清单中,PrivateData 属性有一个 PSData 子属性。 PSData 的可选 Tags 属性采用一组在 PowerShell 库中显示的值。 PowerShell 库支持以下兼容性值:

表 1标记 | 说明

PSEdition_Core | 与 PowerShell Core 6 兼容

PSEdition_Desktop | 与 Windows PowerShell 兼容

Windows | 与 Windows 兼容

Linux | 与 Linux(无特定发行版)兼容

macOS | 与 macOS 兼容

示例:
@{

GUID = “4ae9fd46-338a-459c-8186-07f910774cb8”

Author = “Microsoft Corporation”

CompanyName = “Microsoft Corporation”

Copyright = “© Microsoft Corporation. All rights reserved.”

HelpInfoUri = “https://go.microsoft.com/fwlink/?linkid=855962”

ModuleVersion = “1.2.4”

PowerShellVersion = “3.0”

ClrVersion = “4.0”

RootModule = “PackageManagement.psm1”

Description = 'PackageManagement (a.k.a. OneGet) is a new way to discover and install software packages from around the web.

It is a manager or multiplexer of existing package managers (also called package providers) that unifies Windows package management with a single Windows PowerShell interface. With PackageManagement, you can do the following.

  • Manage a list of software repositories in which packages can be searched, acquired and installed

  • Discover software packages

  • Seamlessly install, uninstall, and inventory packages from one or more software repositories’

CmdletsToExport = @(

'Find-Package','Get-Package','Get-PackageProvider','Get-PackageSource','Install-Package','Import-PackageProvider''Find-PackageProvider''Install-PackageProvider''Register-PackageSource','Set-PackageSource','Unregister-PackageSource','Uninstall-Package''Save-Package'

)

FormatsToProcess = @(‘PackageManagement.format.ps1xml’)

PrivateData = @{

PSData = @{Tags = @('PackageManagement', 'PSEdition_Core', 'PSEdition_Desktop', 'Windows', 'Linux', 'macOS')ProjectUri = 'https://oneget.org'}

}
}

1-9-6. 本机库的依赖项

旨在跨不同操作系统或处理器体系结构使用的模块可能依赖于托管库,而托管库本身又依赖于一些本机库。

在使用 PowerShell 7 之前,必须使用自定义代码来加载适当的本机 dll,以便托管库能够正确找到它。

借助 PowerShell 7,可以在托管库位置(在 .NET RID 目录表示法的子集后面)的子文件夹中搜索要加载的本机二进制文件。

managed.dll folder

|--- 'win-x64' folder|    |--- native.dll|--- 'win-x86' folder|     |--- native.dll|--- 'win-arm' folder|     |--- native.dll|--- 'win-arm64' folder|       |--- native.dll|--- 'linux-x64' folder|       |--- native.so|--- 'linux-x86' folder|    |--- native.so|--- 'linux-arm' folder|    |--- native.so|--- 'linux-arm64' folder|      |--- native.so|--- 'osx-x64' folder|      |--- native.dylib`

2. 用PowerShell进行系统管理的示例脚本

2-1. 使用对象

2-1-1. 查看对象结构 (Get-Member)

由于对象在 Windows PowerShell 中扮演了如此重要的角色,因此存在几个用于处理任意对象类型的本机命令。 最重要的一个是 Get-Member 命令。

分析命令返回的对象的最简单方法是通过管道将该命令的输出传递到 Get-Member cmdlet。 Get-Member cmdlet 向你显示对象类型的正式名称及其成员的完整列表。 有时返回的元素数目可能非常巨大。 例如,一个进程对象可以拥有 100 多个成员。

若要查看进程对象的所有成员并分页显示输出,以便于你可以全部查看,请键入: Get-Process | Get-Member | Out-Host -Paging

此命令的输出将如下所示:

TypeName: System.Diagnostics.Process

Name MemberType Definition


Handles AliasProperty Handles = Handlecount

Name AliasProperty Name = ProcessName

NPM AliasProperty NPM = NonpagedSystemMemorySize

PM AliasProperty PM = PagedMemorySize

VM AliasProperty VM = VirtualMemorySize

WS AliasProperty WS = WorkingSet

add_Disposed Method System.Void add_Disposed(Event…

我们可以通过筛选想要查看的元素,让这个冗长的信息列表更易于使用。 Get-Member 命令仅允许你列出属性成员。 属性的形式有数种。 如果将 Get-Member MemberType 参数设置为值属性,则 cmdlet 将显示任何类型的属性 。 生成的列表仍会很长,但较之前更易于管理:
PS> Get-Process | Get-Member -MemberType Properties
TypeName: System.Diagnostics.Process

Name MemberType Definition


Handles AliasProperty Handles = Handlecount

Name AliasProperty Name = ProcessName

ExitCode Property System.Int32 ExitCode {get;}

Handle Property System.IntPtr Handle {get;}

CPU ScriptProperty System.Object CPU {get=$this.Total…

Path ScriptProperty System.Object Path {get=$this.Main…

备注:MemberType 的允许值有 AliasProperty、CodeProperty、Property、NoteProperty、ScriptProperty、Properties、PropertySet、Method、CodeMethod、ScriptMethod、Methods、ParameterizedProperty、MemberSet 以及 All。

一个进程有 60 多个属性。 对于任何已知的对象,Windows PowerShell 通常仅显示少许属性,这是因为显示所有属性会导致产生无法管理的信息量。

备注:Windows PowerShell 通过使用存储在以 .format.ps1xml 结尾的 XML 文件中的信息来决定某种类型的对象的显示方式。 进程对象(即 .NET System.Diagnostics.Process 对象)的格式设置数据存储在 DotNetTypes.format.ps1xml 中。

如果需要查看 Windows PowerShell 默认显示的属性之外的属性,则需要自己对输出数据进行格式化。 这可以通过使用格式 cmdlet 实现。

2-1-2. 选择对象部件 (Select-Object)

可以使用 Select-Object cmdlet 创建新的自定义 PowerShell 对象(包含从用于创建它们的对象中选择的属性)。 键入下面的命令以创建仅包括 Win32_LogicalDisk WMI 类的 Name 和 FreeSpace 属性的新对象:
Get-CimInstance -Class Win32_LogicalDisk | Select-Object -Property Name,FreeSpace
Output

Name FreeSpace


C: 50664845312

可以使用 Select-Object 创建计算属性。 这样即可以以十亿字节为单位显示 FreeSpace,而非以字节为单位。
Get-CimInstance -Class Win32_LogicalDisk |
Select-Object -Property Name, @{

label=‘FreeSpace’

expression={($_.FreeSpace/1GB).ToString(‘F2’)}
}
Output

Name FreeSpace


C: 47.18

2-1-3. 从管道中删除对象 (Where-Object)

在 PowerShell 中,你通常会生成和传递比预期更多的对象到管道中。 可以通过使用 Format-* cmdlet 指定特定对象的属性进行显示,但是这对从显示中删除整个对象的问题没有任何帮助。 你可能希望在管道末尾之前筛选对象,以便你可以只对初始生成对象的子集执行操作。

借助 PowerShell 中的 Where-Object cmdlet,可以测试管道中的每个对象,并沿管道仅传递满足特定测试条件的对象。 将从管道中删除未通过测试的对象。 测试条件以 FilterScript 参数值的形式提供。

2-1-3-1. 使用 Where-Object 执行简单测试

FilterScript 值是计算结果为 True 或 False 的脚本块 ,即由大括号 ({}) 括起来的一个或多个 PowerShell 命令。 这些脚本块可能非常简单,但是创建它们需要了解有关 PowerShell 的另一个概念,即比较运算符。 比较运算符比较其每一侧显示的项。 比较运算符以连字符 (-) 开头,后跟名称。 基本比较运算符适用于几乎任何类型的对象。 更高级的比较运算符可能仅适用于文本或数组。

备注:默认情况下,在处理文本时,PowerShell 比较运算符不区分大小写。

出于分析考虑,<、> 和 = 等符号不用作比较运算符。 相反,比较运算符由字母组成。

下表中列出了基本比较运算符。

比较运算符 | 含义 | 示例(返回 True)

-eq | 等于 | 1 -eq 1

-ne | 不等于 | 1 -ne 2

-lt | 小于 | 1 -lt 2

-le | 小于或等于 | 1 -le 2

-gt | 大于 | 2 -gt 1

-ge | 大于或等于 | 2 -ge 1

-like | 相似(文本的通配符比较) | “file.doc” -like “f*.do?”

-notlike | 不相似(文本的通配符比较) | “file.doc” -notlike “p*.doc”

-contains | 包含 | 1,2,3 -contains 1

-notcontains | 不包含 | 1,2,3 -notcontains 4

Where-Object 脚本块使用特殊变量 $_ 来指代管道中的当前对象。 以下是其工作原理示例。 如果你有一个数字列表,且希望仅返回小于 3 的数字,则可使用 Where-Object 通过键入以下内容来筛选数字:

1,2,3,4 | Where-Object {$_ -lt 3}

1

2

2-1-3-2. 基于对象属性进行筛选

由于 $_ 指代当前管道对象,因此可以访问它的属性进行测试。

例如,我们可以看看 WMI 中的 Win32_SystemDriver 类。 一个特定的系统上可能有数百个系统驱动程序,但是你可能只对特定一些系统驱动程序感兴趣,例如那些当前正在运行的程序。 对于 Win32_SystemDriver 类,相关属性是 State 。 你可以筛选系统驱动程序,通过键入以下内容仅选择正在运行的驱动程序:
Get-CimInstance -Class Win32_SystemDriver | Where-Object {$_.State -eq ‘Running’}

这仍会生成一个较长的列表。 你可能还希望进行筛选,以通过测试 StartMode 值仅选择自动启动的驱动程序集:
Get-CimInstance -Class Win32_SystemDriver |

Where-Object {KaTeX parse error: Expected 'EOF', got '}' at position 22: …e -eq "Running"}̲ | Where-Object…_.StartMode -eq “Auto”}

Output

DisplayName : RAS Asynchronous Media Driver

Name : AsyncMac

State : Running

Status : OK

Started : True

DisplayName : Audio Stub Driver

Name : audstub

State : Running

Status : OK

Started : True

这为我们提供了大量不再需要的信息,因为我们知道驱动程序正在运行。 事实上,此时我们可能需要的唯一信息就是名称和显示名。 下面的命令仅包括这两种属性,从而使输出更简单:
Get-CimInstance -Class Win32_SystemDriver |

Where-Object {$_.State -eq “Running”} |

Where-Object {$_.StartMode -eq "Manual"} |Format-Table -Property Name,DisplayName

Output

Name DisplayName


AsyncMac RAS Asynchronous Media Driver

bindflt Windows Bind Filter Driver

bowser Browser

CompositeBus Composite Bus Enumerator Driver

condrv Console Driver

HdAudAddService Microsoft 1.1 UAA Function Driver for High Definition Audio Service

HDAudBus Microsoft UAA Bus Driver for High Definition Audio

HidUsb Microsoft HID Class Driver

HTTP HTTP Service

igfx igfx

IntcDAud Intel® Display Audio

intelppm Intel Processor Driver

上面的命令包含两个 Where-Object 元素,但是可以使用 -and 逻辑运算符将其表示为一个 Where-Object 元素,如下所示:
Get-CimInstance -Class Win32_SystemDriver |
Where-Object {(.State−eq′Running′)−and(_.State -eq 'Running') -and (.​State−eq′Running′)−and(_.StartMode -eq ‘Manual’)} |

Format-Table -Property Name,DisplayName

下表中列出了标准逻辑运算符。

逻辑运算符 | 含义 | 示例(返回 True)

-and | Logical and;如果两侧都为 True,则返回 True | (1 -eq 1) -and (2 -eq 2)

-or | Logical or;如果某一侧为 True,则返回 True | (1 -eq 1) -or (1 -eq 2)

-not | Logical not;反转 True 和 False | -not (1 -eq 2)

! | Logical not;反转 True 和 False | !(1 -eq 2)

2-1-4. 对对象进行排序

可以通过使用 Sort-Object cmdlet 组织已显示的数据,使其更易于扫描。 Sort-Object 依据一个或多个属性的名称进行排序,并返回按这些属性的值进行排序的数据。

2-1-4-1. 基本排序

请考虑列出当前目录中的子目录和文件的问题。 如果想要依次按 LastWriteTime 和 Name 进行排序,可键入:
Get-ChildItem |

Sort-Object -Property LastWriteTime, Name |

Format-Table -Property LastWriteTime, Name

output

LastWriteTime Name


11/6/2017 10:10:11 AM .localization-config

11/6/2017 10:10:11 AM .openpublishing.build.ps1

11/6/2017 10:10:11 AM appveyor.yml

11/6/2017 10:10:11 AM LICENSE

11/6/2017 10:10:11 AM LICENSE-CODE

11/6/2017 10:10:11 AM ThirdPartyNotices

11/6/2017 10:10:15 AM tests

6/6/2018 7:58:59 PM CONTRIBUTING.md

6/6/2018 7:58:59 PM README.md

也可通过指定 Descending 开关参数按相反顺序对对象进行排序。

Get-ChildItem |

Sort-Object -Property LastWriteTime, Name -Descending |

Format-Table -Property LastWriteTime, Name

output

LastWriteTime Name


12/1/2018 10:13:50 PM reference

12/1/2018 10:13:50 PM dsc

6/6/2018 7:58:59 PM README.md

6/6/2018 7:58:59 PM CONTRIBUTING.md

11/6/2017 10:10:15 AM tests

11/6/2017 10:10:11 AM ThirdPartyNotices

11/6/2017 10:10:11 AM LICENSE-CODE

11/6/2017 10:10:11 AM LICENSE

11/6/2017 10:10:11 AM appveyor.yml

11/6/2017 10:10:11 AM .openpublishing.build.ps1

11/6/2017 10:10:11 AM .localization-config

2-1-4-2. 使用哈希表

可以使用数组中的哈希表按不同顺序对不同属性进行排序。 每个哈希表使用 Expression 键将属性名称指定为字符串,并使用 Ascending 或 Descending 键按 $true 或 $false 指定排序顺序。 Expression 键是必需的。 Ascending 或 Descending 键是可选的。

下面的示例按 LastWriteTime 降序和 Name 升序对对象进行排序。
Get-ChildItem |

Sort-Object -Property @{ Expression = ‘LastWriteTime’; Descending = $true }, @{ Expression = ‘Name’; Ascending = $true } |

Format-Table -Property LastWriteTime, Name

output

LastWriteTime Name


12/1/2018 10:13:50 PM dsc

12/1/2018 10:13:50 PM reference

11/29/2018 6:56:01 PM .openpublishing.redirection.json

11/29/2018 6:56:01 PM gallery

11/24/2018 10:33:22 AM developer

11/20/2018 7:22:19 PM .markdownlint.json

还可以将 scriptblock 设置为 Expression 键。 运行 Sort-Object cmdlet 时,将执行 scriptblock 并使用结果进行排序。

下面的示例按 CreationTime 和 LastWriteTime 之间的时间跨度以降序对对象进行排序。

Get-ChildItem |

Sort-Object -Property @{ Expression = { $.LastWriteTime - $.CreationTime }; Descending = $true } |

Format-Table -Property LastWriteTime, CreationTime

output

LastWriteTime CreationTime


12/1/2018 10:13:50 PM 11/6/2017 10:10:11 AM

12/1/2018 10:13:50 PM 11/6/2017 10:10:11 AM

11/7/2018 6:52:24 PM 11/6/2017 10:10:11 AM

11/7/2018 6:52:24 PM 11/6/2017 10:10:15 AM

11/3/2018 9:58:17 AM 11/6/2017 10:10:11 AM

10/26/2018 4:50:21 PM 11/6/2017 10:10:11 AM

11/17/2018 1:10:57 PM 11/29/2017 5:48:30 PM

11/12/2018 6:29:53 PM 12/7/2017 7:57:07 PM

2-1-4-3. 提示

可以省略 Property 参数名称,如下所示:
Sort-Object LastWriteTime, Name

此外,可以通过其内置别名 sort 来引用 Sort-Object:
sort LastWriteTime, Name

用于排序的哈希表中的键可以缩写为:
Sort-Object @{ e = ‘LastWriteTime’; d = $true }, @{ e = ‘Name’; a = $true }

在此示例中,e 代表 Expression ,d 代表 Descending ,a 代表 Ascending 。

为了提高可读性,可以将哈希表置于一个单独的变量中:
$order = @(

@{ Expression = ‘LastWriteTime’; Descending = $true }

@{ Expression = ‘Name’; Ascending = $true }
)
Get-ChildItem |

Sort-Object $order |

Format-Table LastWriteTime, Name

2-1-5. 为多个对象重复执行任务 (ForEach-Object)

ForEach-Object cmdlet 为当前管道对象使用脚本块和 $_ 描述符,以便你可以对管道中的每个对象运行命令。 这可用于执行某些复杂的任务。

一种有帮助的情况就是操纵数据使其更为有用。 例如,WMI 的 Win32_LogicalDisk 类可用于返回每个本地磁盘的可用空间信息。 返回以字节表示的数据,但是,这也将增加阅读的难度:
Get-CimInstance -Class Win32_LogicalDisk

Output

DeviceID DriveType ProviderName VolumeName Size FreeSpace


C: 3 Local Disk 203912880128 50665070592

通过将每个值除以 1 MB,可以将 FreeSpace 值转换为以十亿字节为单位。 你可通过键入以下内容在 ForEach-Object 脚本块中实现此操作:
Get-CimInstance -Class Win32_LogicalDisk |

ForEach-Object -Process {($_.FreeSpace)/1MB}

Output

48318.01171875

遗憾的是,该输出现在是没有关联标签的数据。 因为这样的 WMI 属性为只读,所以不能直接转换 FreeSpace。 如果键入以下内容:
Get-CimInstance -Class Win32_LogicalDisk |

ForEach-Object -Process {.FreeSpace=(_.FreeSpace = (.​FreeSpace=(_.FreeSpace)/1MB}

则将收到错误消息:

Output

“FreeSpace” is a ReadOnly property.

At line:2 char:28