PowerShell说明摘要

文章目录

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

CommandTypeNameDefinition
CmdletGet-AclGet-Acl [[-Path] ]…
CmdletGet-AliasGet-Alias [[-Name] PS> Get-Command -Verb Get
CommandTypeNameDefinition
CmdletGet-AclGet-Acl [[-Path] <String[]>]…
CmdletGet-AliasGet-Alias [[-Name] <String[]…
CmdletGet-AuthenticodeSignatureGet-AuthenticodeSignature [-…
CmdletGet-ChildItemGet-ChildItem [[-Path] <Stri…

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

Get-Command -Noun Service

CommandTypeNameDefinition
CmdletGet-ServiceGet-Service [[-Name] …
CmdletRestart-ServiceRestart-Service [-Name] …
CmdletStart-ServiceStart-Service [-Name] PS> Get-Command -Noun Service
CommandTypeNameDefinition
CmdletGet-ServiceGet-Service [[-Name] <String…
CmdletNew-ServiceNew-Service [-Name] …
CmdletRestart-ServiceRestart-Service [-Name] <Str…
CmdletResume-ServiceResume-Service [-Name] <Stri…
CmdletSet-ServiceSet-Service [-Name] …
CmdletStart-ServiceStart-Service [-Name] <Strin…
CmdletStop-ServiceStop-Service [-Name] <String…
CmdletSuspend-ServiceSuspend-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 命令:

命令命令命令命令
catdirmountrm
cdechomovermdir
chdirerasepopdsleep
clearhpssort
clshistorypushdtee
copykillpwdtype
dellprwrite
difflsren

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

CommandTypeNameVersionSource
Aliascls->Clear-Host

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

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

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

示例缩写:

名词或谓词缩写
Getg
Sets
Itemi
Locationl
Commandcm
Aliasal

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

表 3

Cmdlet 名称Alias
Get-Itemgi
Set-Itemsi
Get-Locationgl
Set-Locationsl
Get-Commandgcm
Get-Aliasgal

熟悉 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 *时,不会显示函数和脚本的帮助。

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

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. 另请参阅

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

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

CommandTypeNameVersionSource
CmdletAdd-Computer3.1.0.0Microsoft.PowerShell.Management
CmdletAdd-Content3.1.0.0Microsoft.PowerShell.Management
CmdletAdd-History3.0.0.0Microsoft.PowerShell.Core
CmdletAdd-JobTrigger1.1.0.0PSScheduledJob
CmdletAdd-LocalGroupMember1.0.0.0Microsoft.PowerShell.LocalAccounts
CmdletAdd-Member3.1.0.0Microsoft.PowerShell.Utility
CmdletAdd-PSSnapin3.0.0.0Microsoft.PowerShell.Core
CmdletAdd-Type3.1.0.0Microsoft.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

NameMemberTypeDefinition
DrivePropertySystem.Management.Automation.PSDriveInfo Drive {get;}
PathPropertySystem.String Path {get;}
ProviderPropertySystem.Management.Automation.ProviderInfo Provider {…
ProviderPathPropertySystem.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

ModeLastWriteTimeLengthName
d-----4/12/2018 2:15 AM0409
d-----5/13/2018 11:31 PM1033
d-----4/11/2018 4:38 PMAdvancedInstallers
d-----5/13/2018 11:13 PMaf-ZA
d-----5/13/2018 11:13 PMam-et
d-----4/11/2018 4:38 PMAppLocker
d-----5/13/2018 11:31 PMappmgmt
d-----7/11/2018 2:05 AMappraiser
d—s-4/12/2018 2:20 AMAppV
d-----5/13/2018 11:10 PMar-SA
d-----5/13/2018 11:13 PMas-IN
d-----8/14/2018 9:03 PMaz-Latn-AZ
d-----5/13/2018 11:13 PMbe-BY
d-----5/13/2018 11:10 PMBestPractices
d-----5/13/2018 11:10 PMbg-BG
d-----5/13/2018 11:13 PMbn-BD
d-----5/13/2018 11:13 PMbn-IN
d-----8/14/2018 9:03 PMBoot
d-----8/14/2018 9:03 PMbs-Latn-BA
d-----4/11/2018 4:38 PMBthprops
d-----4/12/2018 2:19 AMca-ES
d-----8/14/2018 9:03 PMca-ES-valencia
d-----5/13/2018 10:46 PMCatRoot
d-----8/23/2018 5:07 PMcatroot2

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

NameMemberTypeDefinition
EqualsMethodbool Equals(System.Object obj)
GetHashCodeMethodint GetHashCode()
GetTypeMethodtype GetType()
ToStringMethodstring ToString()
DrivePropertySystem.Management.Automation.PSDriveInfo Drive {get;}
PathPropertystring Path {get;}
ProviderPropertySystem.Management.Automation.ProviderInfo Provider {get;}
ProviderPathPropertystring ProviderPath {get;}

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

1-8. 更多 PowerShell 学习

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

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

1-8-2. Channel 9 视频

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

1-8-3. Microsoft Virtual Academy

Microsoft Virtual Academy 视频已移至 Channel 9。

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

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

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, --helpDisplays help for this command.
-l, --listLists templates containing the specified name. If no name is specified, lists all templates.
-n, --nameThe name for the output being created. If no name is specified, the name of the current directory is used.
-o, --outputLocation to place the generated output.
-i, --installInstalls a source or a template pack.
-u, --uninstallUninstalls a source or a template pack.
–nuget-sourceSpecifies a NuGet source to use during install.
–typeFilters templates based on available types. Predefined values are “project”, “item” or “other”.
–forceForces content to be generated even if it would change existing files.
-lang, --languageFilters templates based on language and specifies the language of the template to create.
TemplatesShort NameLanguageTags
Console Applicationconsole[C#], F#, VBCommon/Console
Class libraryclasslib[C#], F#, VBCommon/Library
PowerShell Standard Modulepsmodule[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.dll

Test-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 {( . S t a t e − e q ′ R u n n i n g ′ ) − a n d ( _.State -eq 'Running') -and ( .StateeqRunning)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 { . F r e e S p a c e = ( _.FreeSpace = ( .FreeSpace=(_.FreeSpace)/1MB}

则将收到错误消息:

Output

“FreeSpace” is a ReadOnly property.

At line:2 char:28

  • ForEach-Object -Process { . F r e e S p a c e = ( _.FreeSpace = ( .FreeSpace=(_.FreeSpace)/1MB}

  •   					~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
  • CategoryInfo : NotSpecified: (😃 [], SetValueException

  • FullyQualifiedErrorId : ReadOnlyCIMProperty

可以通过使用一些高级技术重新组织数据,但更简单的方法是通过使用 Select-Object 创建新对象。

2-1-6. 创建 .NET 和 COM 对象 (New-Object)

存在具有 .NET Framework 和 COM 接口的软件组件,使用它们可执行许多系统管理任务。 Windows PowerShell 允许你使用这些组件,因此你将不限于执行可通过使用 cmdlet 执行的任务。 Windows PowerShell 初始版本中的许多 cmdlet 对远程计算机无效。 我们将演示如何通过直接从 Windows PowerShell 使用 .NET Framework System.Diagnostics.EventLog 类在管理事件日志时绕过此限制。

2-1-6-1. 使用 New-Object 进行事件日志访问

.NET Framework 类库包括一个名为 System.Diagnostics.EventLog 的类,该类可用于管理事件日志。 可以通过使用具有 TypeName 参数的 New-Object cmdlet 创建 .NET Framework 类的新实例。 例如,以下命令将创建事件日志引用:
PS> New-Object -TypeName System.Diagnostics.EventLog
Max(K) Retain OverflowAction Entries Name


尽管该命令创建了 EventLog 类的实例,但该实例不包含任何数据。 这是因为我们未指定特定的事件日志。 如何获取真正的事件日志?

2-1-6-1-1. 将构造函数与 New-Object 一起使用

若要引用特定的事件日志,需要指定日志的名称。 New-Object 具有 ArgumentList 参数。 作为值传递到此形参的实参将由对象的特殊的启动方法使用。 此方法叫做构造函数,因为它将用于构造对象。 例如,若要对获取应用程序日志的引用,请指定字符串“Application”作为实参:
PS> New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

Max(K) Retain OverflowAction Entries Name


16,384 7 OverwriteOlder 2,160 Application

备注:由于大多数 .NET Framework 核心类都包含在 System 命名空间中,所以如果 Windows PowerShell 找不到你指定的类型名称的匹配项,它将自动尝试查找你在 System 命名空间中指定的类。 这意味着你可以指定 Diagnostics.EventLog 而不指定 System.Diagnostics.EventLog。

2-1-6-1-2. 在变量中存储对象

你可能需要存储对对象的引用,以便在当前的 Shell 中使用。 尽管 Windows PowerShell 允许使用管道执行大量操作,减少了对变量的需求,但有时在变量中存储对对象的引用可以更方便地操纵这些对象。

Windows PowerShell 允许你创建实质上是命名对象的变量。 来自任何有效 Windows PowerShell 命令的输出都可以存储在变量中。 变量名始终以 $ 开头。 如果想要将应用程序日志引用存储在名为 $AppLog 的变量中,请键入该变量的名称,后跟一个等号,然后键入用于创建应用程序日志对象的命令:
PS> $AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

如果随后键入 $AppLog,你将可以看到它包含应用程序日志:
PS> $AppLog

Max(K) Retain OverflowAction Entries Name


16,384 7 OverwriteOlder 2,160 Application

2-1-6-1-3. 使用 New-Object 访问远程事件日志

上一节中使用的命令以本地计算机为目标;Get-EventLog cmdlet 可做到这一点。 若要访问远程计算机上的应用程序日志,必须同时将日志名称和计算机名称(或 IP 地址)作为参数提供。
PS> $RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application,192.168.1.81
PS> $RemoteAppLog

Max(K) Retain OverflowAction Entries Name


512 7 OverwriteOlder 262 Application

我们已经有了对存储在 $RemoteAppLog 变量中的事件日志的引用,那么可以对它执行什么任务呢?

2-1-6-1-4. 使用对象方法清除事件日志

对象通常具有可调用以执行任务的方法。 可以使用 Get-Member 来显示与对象关联的方法。 下面的命令和已选的输出将显示 EventLog 类的一些方法:
PS> $RemoteAppLog | Get-Member -MemberType Method

TypeName: System.Diagnostics.EventLog

Name MemberType Definition


Clear Method System.Void Clear()

Close Method System.Void Close()

GetType Method System.Type GetType()

ModifyOverflowPolicy Method System.Void ModifyOverflowPolicy(Overfl…

RegisterDisplayName Method System.Void RegisterDisplayName(String …

ToString Method System.String ToString()

WriteEntry Method System.Void WriteEntry(String message),…

WriteEvent Method System.Void WriteEvent(EventInstance in…

Clear() 方法可以用于清除事件日志。 调用方法时,即使该方法不需要参数,也必须始终在方法名称后紧跟括号。 这使得 Windows PowerShell 方法能够区分该方法和具有相同名称的潜在属性。 键入以下命令以调用 Clear 方法:
PS> $RemoteAppLog.Clear()

键入以下命令以显示日志。 你将看到事件日志已清除,并且现在有 0 个条目而不是 262 个:
PS> $RemoteAppLog

Max(K) Retain OverflowAction Entries Name


512 7 OverwriteOlder 0 Application

2-1-6-2. 使用 New-Object 创建 COM 对象

可以使用 New-Object 来处理组件对象模型 (COM) 组件。 组件的范围从 Windows 脚本宿主 (WSH) 包含的各种库到 ActiveX 应用程序(如大多数系统上安装的 Internet Explorer)。

New-Object 使用 .NET Framework 运行时可调用的包装器创建 COM 对象,因此调用 COM 对象时它与 .NET Framework 具有相同的限制。 若要创建 COM 对象,需要为 ComObject 参数指定要使用的 COM 类的编程标识符(或 ProgId)。 COM 用途限制的全面讨论和确定系统上可用的 ProgId 已超出本用户指南的范围,但来自环境的大多数已知对象(如 WSH)都可在 Windows PowerShell 内使用。

可以通过指定以下 progid 来创建 WSH 对象:WScript.Shell 、WScript.Network 、Scripting.Dictionary 和 Scripting.FileSystemObject 。 以下命令将创建这些对象:

New-Object -ComObject WScript.Shell

New-Object -ComObject WScript.Network

New-Object -ComObject Scripting.Dictionary

New-Object -ComObject Scripting.FileSystemObject

尽管在 Windows PowerShell 中可通过其他方法使用这些类的大多数功能,但使用 WSH 类执行某些任务(如创建快捷方式)仍更加简单。

2-1-6-3. 使用 WScript.Shell 创建桌面快捷方式

可以使用 COM 对象快速执行的一个任务是创建快捷方式。 假设你想要在桌面上创建链接到 Windows PowerShell 主文件夹的快捷方式。 首先需要创建对 WScript.Shell 的引用,我们会将其存储在名为 $WshShell 的变量中:
$WshShell = New-Object -ComObject WScript.Shell

Ge-Member 可用于 COM 对象,因此你可以通过键入以下内容浏览对象的成员:
PS> $WshShell | Get-Member
TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name MemberType Definition


AppActivate Method bool AppActivate (Variant, Va…

CreateShortcut Method IDispatch CreateShortcut (str…

Get-Member 具有可选 InputObject 参数,你可以使用这个参数而不使用管道为 Get-Member 提供输入。 如果改用命令 Get-Member-InputObject $WshShell,你会得到与如上所示相同的输出。 如果使用 InputObject,它将视其参数为单个项。 这意味着,如果变量中有几个对象,那么 Get-Member 会将它们视为一个对象数组。 例如:
PS> $a = 1,2,“three”
PS> Get-Member -InputObject $a

TypeName: System.Object[]

Name MemberType Definition


Count AliasProperty Count = Length

WScript.Shell CreateShortcut 方法接受单个参数,即要创建的快捷方式文件的路径。 我们可以键入桌面的完整路径,但还有更简单的方法。 桌面通常由当前用户的主文件夹内名为 Desktop 的文件夹表示。 Windows PowerShell 具有变量 $Home,它包含此文件夹的路径。 我们可以通过使用此变量指定主文件夹的路径,然后通过键入以下内容添加 Desktop 文件夹的名称和要创建的快捷方式的名称:
$lnk = W s h S h e l l . C r e a t e S h o r t c u t ( " WshShell.CreateShortcut(" WshShell.CreateShortcut("Home\Desktop\PSHome.lnk")

当你在双引号内使用外观类似变量名称的项时,Windows PowerShell 将尝试替换匹配的值。 如果使用单引号,Windows PowerShell 将不会替换该变量值。 例如,请尝试键入以下命令:
PS> "KaTeX parse error: Undefined control sequence: \Desktop at position 5: Home\̲D̲e̲s̲k̲t̲o̲p̲\PSHome.lnk" C:…Home\Desktop\PSHome.lnk’
$Home\Desktop\PSHome.lnk

我们现在有一个名为 $lnk 的变量,其中包含新的快捷方式引用。 如果想要查看其成员,你可以通过管道将它传递到 Get-Member。 下面的输出显示了完成创建快捷方式所需使用的成员:
PS> $lnk | Get-Member

TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}

Name MemberType Definition


Save Method void Save ()

TargetPath Property string TargetPath () {get} {set}

我们需要指定 TargetPath(它是 Windows PowerShell 的应用程序文件夹),然后通过调用 Save 方法保存快捷方式 $lnk。 Windows PowerShell 应用程序文件夹路径存储在变量 $PSHome 中,因此我们可以通过键入以下内容执行此操作:
$lnk.TargetPath = $PSHome
$lnk.Save()

2-1-6-4. 从 Windows PowerShell 使用 Internet Explorer

使用 COM 可以使许多应用程序(包括 Microsoft Office 系列应用程序和 Internet Explorer)自动执行。 Internet Explorer 阐明了有关使用基于 COM 的应用程序的一些典型方法和涉及的问题。

通过指定 Internet Explorer ProgId InternetExplorer.Application 创建 Internet Explorer 实例:
$ie = New-Object -ComObject InternetExplorer.Application

此命令将启动 Internet Explorer,但不显示它。 如果你键入 Get-Process,将可以看到名为 iexplore 的进程正在运行。 事实上,如果你退出 Windows PowerShell,该过程将继续运行。 必须重启计算机或使用任务管理器等工具结束 iexplore 进程。

备注:作为独立进程(通常称为 ActiveX 可执行文件)启动的 COM 对象启动时可能显示也可能不显示用户界面窗口。 如果它们创建而不显示窗口(如 Internet Explorer),则焦点通常会移到 Windows 桌面,这时必须显示窗口才能与其进行交互。

通过键入 $ie | Get-Member,可以查看 Internet Explorer 的属性和方法。 若要查看 Internet Explorer 窗口,请通过键入以下内容将 Visible 属性设置为 $true:
$ie.Visible = $true

然后可以通过使用 Navigate 方法导航到特定的 Web 地址:
$ie.Navigate(“https://devblogs.microsoft.com/scripting/”)

使用 Internet Explorer 对象模型的其他成员,可以从网页中检索文本内容。 下面的命令将在当前网页的正文中显示 HTML 文本:
$ie.Document.Body.InnerText

若要从 PowerShell 内部关闭 Internet Explorer,请调用其 Quit() 方法:
$ie.Quit()

这将强制其关闭。 尽管 $ie 变量仍然显示为 COM 对象,但它将不再包含有效引用。 如果你尝试使用它,你将收到一个自动化错误:
PS> $ie | Get-Member

Get-Member : Exception retrieving the string representation for property "Appli

cation" : "The object invoked has disconnected from its clients. (Exception fro

m HRESULT: 0x80010108 (RPC_E_DISCONNECTED))"

At line:1 char:16

  • $ie | Get-Member <<<<

你可以使用 $ie = $null 等命令删除剩余的引用,或通过键入以下内容完全删除该变量:
Remove-Variable ie

备注:删除对 ActiveX 可执行文件的引用时,它会退出还是继续运行没有通用标准。 具体取决于不同情况(如应用程序是否可见、已编辑的文档是否正在其中运行甚至 Windows PowerShell 是否仍在运行),应用程序可能退出也可能不退出。 因此,应该为想要在 Windows PowerShell 中使用的每个 ActiveX 可执行文件测试终止行为。

2-1-6-5. 获取有关 .NET Framework 包装的 COM 对象的警告

在某些情况下,COM 对象可能具有相关联的 .NET Framework 运行时可调用包装器(或称 RCW),它将由 New-Object 使用。 因为 RCW 的行为可能与普通 COM 对象的行为不同,所以 New-Object 具有 Strict 参数,它将对访问 RCW 进行警告。 如果指定 Strict 参数然后创建使用 RCW 的 COM 对象,你会收到一条警告消息:
PS> $xl = New-Object -ComObject Excel.Application -Strict

New-Object : The object written to the pipeline is an instance of the type "Mic

rosoft.Office.Interop.Excel.ApplicationClass" from the component’s primary inte

rop assembly. If this type exposes different members than the IDispatch members

, scripts written to work with this object might not work if the primary intero

p assembly is not installed.

At line:1 char:17

  • $xl = New-Object <<<< -ComObject Excel.Application -Strict

尽管仍将创建该对象,但将警告你它不是标准 COM 对象。

2-1-7. 使用静态类和方法

不是所有 .NET Framework 类都可使用 New-Object 来创建。 例如,如果你尝试使用 New-Object 创建 System.Environment 或 System.Math 对象,你将收到以下错误消息:
PS> New-Object System.Environment

New-Object : Constructor not found. Cannot find an appropriate constructor for

type System.Environment.

At line:1 char:11

  • New-Object <<<< System.Environment

PS> New-Object System.Math

New-Object : Constructor not found. Cannot find an appropriate constructor for

type System.Math.

At line:1 char:11

  • New-Object <<<< System.Math

之所以发生这些错误,是因为无法从这些类创建新的对象。 这些类是不更改状态的方法和属性的引用库。 你无需创建这些类,只需要使用它们。 这样的类和方法称为静态类,因为它们不会被创建、销毁或更改。 为了明确这一点,我们将提供静态类的使用示例。

2-1-7-1. 使用 System.Environment 获取环境数据

通常,在 Windows PowerShell 中使用对象的第一步是使用 Get-Member 找出其所包含的成员。 使用静态类,进程会稍有不同,因为实际类不是对象。

2-1-7-1-1. 引用静态的 System.Environment 类

可以通过使用方括号将类名称括起来以引用静态类。 例如,可以通过在括号内键入名称来引用 System.Environment。 执行此操作会显示某些泛型类型的信息:

复制

PS> [System.Environment]

IsPublic IsSerial Name BaseType


True False Environment System.Object

备注:正如我们之前提到的,当你使用 New-Object 时,Windows PowerShell 会 使用 New-Object.时输入名称。 使用被括号括起来的类型名称时也会发生同样的情况,因此可以将 [System.Environment] 指定为 [Environment] 。

System.Environment 类包含关于当前进程工作环境的一般信息,如果是在 Windows PowerShell 内工作,该进程为 powershell.exe。

如果尝试通过键入 [System.Environment] | Get-Member 来查看此类的详细信息,对象类型将报告为 System.RuntimeType,而不是 System.Environment:

复制

PS> [System.Environment] | Get-Member

TypeName: System.RuntimeType

若要使用 Get-Member 查看静态成员,请指定 Static 参数:

复制

PS> [System.Environment] | Get-Member -Static

TypeName: System.Environment

Name MemberType Definition


Equals Method static System.Boolean Equals(Object ob…

Exit Method static System.Void Exit(Int32 exitCode)

CommandLine Property static System.String CommandLine {get;}

CurrentDirectory Property static System.String CurrentDirectory …

ExitCode Property static System.Int32 ExitCode {get;set;}

HasShutdownStarted Property static System.Boolean HasShutdownStart…

MachineName Property static System.String MachineName {get;}

NewLine Property static System.String NewLine {get;}

OSVersion Property static System.OperatingSystem OSVersio…

ProcessorCount Property static System.Int32 ProcessorCount {get;}

StackTrace Property static System.String StackTrace {get;}

SystemDirectory Property static System.String SystemDirectory {…

TickCount Property static System.Int32 TickCount {get;}

UserDomainName Property static System.String UserDomainName {g…

UserInteractive Property static System.Boolean UserInteractive …

UserName Property static System.String UserName {get;}

Version Property static System.Version Version {get;}

WorkingSet Property static System.Int64 WorkingSet {get;}

TickCount ExitCode

现在我们可以从 System.Environment 选择要查看的属性。

2-1-7-1-2. 显示 System.Environment 的静态属性

System.Environment 的属性也是静态的,并且必须使用与常规属性不同的方式进行指定。 我们使用 :: 向 Windows PowerShell 指示我们要使用静态方法或属性。 若要查看用于启动 Windows PowerShell 的命令,我们通过键入以下内容来检查 CommandLine 属性:

复制

PS> [System.Environment]::Commandline

“C:\Program Files\Windows PowerShell\v1.0\powershell.exe”

若要检查操作系统版本,通过键入以下内容显示 OSVersion 属性:

复制

PS> [System.Environment]::OSVersion

	   Platform ServicePack		 Version			 VersionString

	   -------- -----------		 -------			 -------------

		Win32NT Service Pack 2	  5.1.2600.131072	 Microsoft Windows...

我们可以通过显示 HasShutdownStarted 属性来检查计算机是否处于关机进程中:

复制

PS> [System.Environment]::HasShutdownStarted

False

2-1-7-2. 使用 System.Math 做数学

System.Math 静态类可用于执行某些数学运算。 System.Math 的大多数重要成员是方法,我们可以用过使用 Get-Member 来显示它们。

备注:System.Math 的一些方法具有相同的名称,但可以按其参数的类型对其进行区分。

键入以下内容来列出 System.Math 类的方法。
PS> [System.Math] | Get-Member -Static -MemberType Methods

TypeName: System.Math

Name MemberType Definition


Abs Method static System.Single Abs(Single value), static Sy…

Acos Method static System.Double Acos(Double d)

Asin Method static System.Double Asin(Double d)

Atan Method static System.Double Atan(Double d)

Atan2 Method static System.Double Atan2(Double y, Double x)

BigMul Method static System.Int64 BigMul(Int32 a, Int32 b)

Ceiling Method static System.Double Ceiling(Double a), static Sy…

Cos Method static System.Double Cos(Double d)

Cosh Method static System.Double Cosh(Double value)

DivRem Method static System.Int32 DivRem(Int32 a, Int32 b, Int3…

Equals Method static System.Boolean Equals(Object objA, Object …

Exp Method static System.Double Exp(Double d)

Floor Method static System.Double Floor(Double d), static Syst…

IEEERemainder Method static System.Double IEEERemainder(Double x, Doub…

Log Method static System.Double Log(Double d), static System…

Log10 Method static System.Double Log10(Double d)

Max Method static System.SByte Max(SByte val1, SByte val2), …

Min Method static System.SByte Min(SByte val1, SByte val2), …

Pow Method static System.Double Pow(Double x, Double y)

ReferenceEquals Method static System.Boolean ReferenceEquals(Object objA…

Round Method static System.Double Round(Double a), static Syst…

Sign Method static System.Int32 Sign(SByte value), static Sys…

Sin Method static System.Double Sin(Double a)

Sinh Method static System.Double Sinh(Double value)

Sqrt Method static System.Double Sqrt(Double d)

Tan Method static System.Double Tan(Double a)

Tanh Method static System.Double Tanh(Double value)

Truncate Method static System.Decimal Truncate(Decimal d), static…

这会显示多种数学方法。 以下是一个命令列表,展示了某些常用方法的工作原理:
PS> [System.Math]::Sqrt(9)

3
PS> [System.Math]::Pow(2,3)

8
PS> [System.Math]::Floor(3.3)

3
PS> [System.Math]::Floor(-3.3)

-4
PS> [System.Math]::Ceiling(3.3)

4
PS> [System.Math]::Ceiling(-3.3)

-3
PS> [System.Math]::Max(2,7)

7
PS> [System.Math]::Min(2,7)

2
PS> [System.Math]::Truncate(9.3)

9
PS> [System.Math]::Truncate(-9.3)

-9

2-2. 管理计算机

2-2-1. 更改计算机状态

若要在 PowerShell 中重置计算机,请使用标准命令行工具、WMI 或 CIM 类。 尽管你使用 PowerShell 仅仅是为了运行该工具,但了解如何在 PowerShell 中更改计算机的电源状态将阐明有关在 PowerShell 中使用外部工具的一些重要详细信息。

2-2-1-1. 锁定计算机

使用标准可用工具直接锁定计算机的唯一方法是调用 user32.dll 中的 LockWorkstation() 函数:
rundll32.exe user32.dll,LockWorkStation

此命令将立即锁定工作站。 它使用 rundll32.exe ,后者运行 Windows DLL(并保存其库以便重复使用)以运行 user32.dll(Windows 管理函数的库)。

如果在启用了“快速用户切换”时锁定工作站(例如在 Windows XP 中),则计算机将显示用户登录屏幕,而不会启动当前用户的屏幕保护程序。

若要关闭终端服务器上的特定会话,请使用 tsshutdn.exe 命令行工具。

2-2-1-2. 注销当前会话

可以使用多种不同的方法来注销本地系统上的会话。 最简单的方法是使用远程桌面/终端服务命令行工具 logoff.exe (若要了解有关详细信息,请在 PowerShell 提示符处键入 logoff /?)。 若要注销当前活动会话,请键入 logoff 而不带参数。

你还可以使用具 shutdown.exe 工具及其 logoff 选项:
shutdown.exe -l

另一种方法是使用 WMI。 Win32_OperatingSystem 类具有 Shutdown 方法。 调用具有 0 标志的方法将启动注销:

有关 Shutdown 方法的详细信息,请参阅 Win32_OperatingSystem 类的 Shutdown 方法

Get-CimInstance -Classname Win32_OperatingSystem | Invoke-CimMethod -MethodName Shutdown

2-2-1-3. 关闭或重启计算机

关闭和重启计算机通常是相同类型的任务。 关闭计算机的工具通常也可以重启计算机,反之亦然。 从 PowerShell 重启计算机有两个直接的选项。 使用 tsshutdn.exe 或 shutdown.exe 及其相应参数。 你可以从 tsshutdn.exe /? 或 shutdown.exe /? 获取详细的使用信息。

也可以直接从 PowerShell 执行关闭和重启操作。

要关闭计算机,请使用 Stop-Computer 命令
Stop-Computer

要重启操作系统,请使用 Restart-Computer 命令
Restart-Computer

要强制立即重新启动计算机,请使用 -Force 参数。
Restart-Computer -Force

2-2-2. 收集有关计算机的信息

CimCmdlets 模块中的 cmdlet 是对常规系统管理任务最重要的 cmdlet 。 所有关键子系统设置都通过 WMI 公开。 此外,WMI 将数据视为一个或多个项的集合中的对象。 由于 Windows PowerShell 也可以使用对象,且具有允许你以相同方式处理单个和多个对象的管道,因此通过泛型 WMI 访问可以非常轻易地执行某些高级任务。

2-2-2-1. 列出桌面设置

我们将首先处理用于收集有关本地计算机上桌面信息的命令。
Get-CimInstance -ClassName Win32_Desktop

这将返回所有桌面的信息,无论它们是否正在使用中。

备注:WMI 类返回的某些信息可能非常详细,且通常包括有关 WMI 类的元数据。

因为这些元数据属性大多具有以 Cim 开头的名称,因此可以使用 Select-Object 筛选属性 。 指定值为“Cim*”的 -ExcludeProperty 参数 。 例如:
Get-CimInstance -ClassName Win32_Desktop | Select-Object -ExcludeProperty “CIM*”

若要筛选掉元数据,请使用管道运算符 (|),将 Get-CimInstance 命令的结果发送到 Select-Object -ExcludeProperty “CIM*”。

2-2-2-2. 列出 BIOS 信息

WMI Win32_BIOS 类返回有关本地计算机上系统 BIOS 的高度压缩的完整信息 :
Get-CimInstance -ClassName Win32_BIOS

2-2-2-3. 列出处理器信息

可以通过使用 WMI 的 Win32_Processor 类检索常规处理器信息 ,尽管很可能需要筛选信息:
Get-CimInstance -ClassName Win32_Processor | Select-Object -ExcludeProperty “CIM*”

对于该处理器系列的常规描述字符串,可以仅返回 SystemType 属性:
Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -Property SystemType

SystemType


X86-based PC

2-2-2-4. 列出计算机制造商和型号

Win32_ComputerSystem 中也提供了计算机型号信息。 标准显示输出不需要任何筛选便可提供 OEM 数据:
Get-CimInstance -ClassName Win32_ComputerSystem
Output

Name PrimaryOwnerName Domain TotalPhysicalMemory Model Manufacturer


MyPC Jane Doe WORKGROUP 804765696 DA243A-ABA 6415cl NA910 Compaq Presario 06

像这种来自命令的输出(它直接从某个硬件返回信息)仅相当于你拥有的数据。 某些信息未由硬件制造商正确配置,因此可能不可用。

2-2-2-5. 列出已安装的修补程序

可以通过使用 Win32_QuickFixEngineering 列出所有已安装的修补程序:
Get-CimInstance -ClassName Win32_QuickFixEngineering

此类将返回如下所示的修补程序列表:
Output

Source Description HotFixID InstalledBy InstalledOn PSComputerName


Security Update KB4048951 Administrator 12/16/2017 .

为了使输出更简洁,可能需要排除某些属性。 尽管可以使用 Get-CimInstance 的 Property 参数以仅选择 HotFixID,但这样做实际上将返回更多信息,因为默认显示所有元数据 :
Get-CimInstance -ClassName Win32_QuickFixEngineering -Property HotFixID
Output

InstalledOn :

Caption :

Description :

InstallDate :

Name :

Status :

CSName :

FixComments :

HotFixID : KB4533002

InstalledBy :

ServicePackInEffect :

PSComputerName :

CimClass : root/cimv2:Win32_QuickFixEngineering

CimInstanceProperties : {Caption, Description, InstallDate, Name…}

CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

返回额外数据是因为 Get-CimInstance 中的 Property 参数限制从 WMI 类实例返回的属性,而不限制返回到 PowerShell 的对象。 若要减少输出,请使用 Select-Object:
Get-CimInstance -ClassName Win32_QuickFixEngineering -Property HotFixId | Select-Object -Property HotFixId
Output

HotFixId


KB4048951

2-2-2-6. 列出操作系统版本信息

Win32_OperatingSystem 类属性包括版本和服务包信息。 你可以明确仅选择这些属性,以从 Win32_OperatingSystem 获取版本信息摘要:
Get-CimInstance -ClassName Win32_OperatingSystem |
Select-Object -Property BuildNumber,BuildType,OSType,ServicePackMajorVersion,ServicePackMinorVersion

也可以将通配符用于 Select-Object 的 Property 参数 。 因为在此处使用以 Build 或 ServicePack 开头的所有属性很重要,所以我们可以将此缩短为下列形式:
Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -Property Build*,OSType,ServicePack*
Output

BuildNumber : 18362

BuildType : Multiprocessor Free

OSType : 18

ServicePackMajorVersion : 0

ServicePackMinorVersion : 0

2-2-2-7. 列出本地用户和所有者

本地常规用户信息(许可的用户数、当前用户数和所有者名称)可通过选择 Win32_OperatingSystem 类的属性找到 。 你可以明确选择使属性显示如下:
Get-CimInstance -ClassName Win32_OperatingSystem |

Select-Object -Property NumberOfLicensedUsers,NumberOfUsers,RegisteredUser

使用通配符的更简洁版本是:
Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -Property user

2-2-2-8. 获取可用磁盘空间

若要查看本地驱动器的磁盘空间和可用空间,可以使用 Win32_LogicalDisk WMI 类。 仅需要查看具有 DriveType 3(WMI 将此值用作固定硬盘)的实例。
Get-CimInstance -ClassName Win32_LogicalDisk -Filter “DriveType=3”
Output

DeviceID DriveType ProviderName VolumeName Size FreeSpace PSComputerName


C: 3 Local Disk 203912880128 65541357568 .

Q: 3 New Volume 122934034432 44298250240 .

Get-CimInstance -ClassName Win32_LogicalDisk -Filter “DriveType=3” |
Measure-Object -Property FreeSpace,Size -Sum |

Select-Object -Property Property,Sum
Output

Property Sum


FreeSpace 109839607808

Size 326846914560

2-2-2-9. 获取登录会话信息

可通过 Win32_LogonSession WMI 类获取有关与用户相关联的登录会话的常规信息 :
Get-CimInstance -ClassName Win32_LogonSession

2-2-2-10. 获取登录到计算机的用户

可以使用 Win32_ComputerSystem 显示已登录到特定计算机系统的用户。 此命令将仅返回登录到系统桌面的用户:
Get-CimInstance -ClassName Win32_ComputerSystem -Property UserName

2-2-2-11. 获取计算机的本地时间

可以通过使用 Win32_LocalTime WMI 类检索指定计算机上的当前本地时间 。
Get-CimInstance -ClassName Win32_LocalTime
Output

Day : 23

DayOfWeek : 1

Hour : 8

Milliseconds :

Minute : 52

Month : 12

Quarter : 4

Second : 55

WeekInMonth : 4

Year : 2019

PSComputerName :

2-2-2-12. 显示服务状态

若要查看指定计算机上所有服务的状态,可以本地使用 Get-Service cmdlet。 对于远程系统,可以使用 Win32_Service WMI 类 。 如果还使用 Select-Object 来筛选 Status、Name 和 DisplayName 的结果,则输出格式将与 Get-Service 的输出格式几乎完全相同 :
Get-CimInstance -ClassName Win32_Service | Select-Object -Property Status,Name,DisplayName

若要完整显示具有极长名称的临时服务的名称,可能需要使用具有 AutoSize 和 Wrap 参数的 Format-Table,用于优化列宽并允许较长名称换行而不是被截断 :
Get-CimInstance -ClassName Win32_Service | Format-Table -Property Status,Name,DisplayName -AutoSize -Wrap

2-2-3. 使用 FilterHashtable 创建 Get-WinEvent 查询

请参阅通过 PowerShell 使用 FilterHashTable 筛选事件日志,以查看 2014 年 6 月 3 日的原创“脚本专家”博客文章。

本文摘录自此原创博客文章,并说明了如何使用 Get-WinEvent cmdlet 的 FilterHashtable 参数筛选事件日志。 PowerShell 的 Get-WinEvent cmdlet 是一种功能强大的方法,可用于筛选 Windows 事件和诊断日志。 Get-WinEvent 查询使用 FilterHashtable 参数时,性能将得到改进。

处理大型事件日志时,如果将对象沿管道下发到 Where-Object 命令,效率将较低。 在 PowerShell 6 之前,Get-EventLog cmdlet 曾是另一个用于获取日志数据的方法。 例如,使用下面的命令筛选 Microsoft-Windows-Defrag 日志时,效率较低 :
Get-EventLog -LogName Application | Where-Object Source -Match defrag

Get-WinEvent -LogName Application | Where-Object { $_.ProviderName -Match ‘defrag’ }

下面的命令使用了可提升性能的哈希表:
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’*defrag’
}

2-2-3-1. 关于枚举的博客文章

本文提供了如何在哈希表中使用枚举值的相关信息。 有关枚举的详细信息,请参阅 “脚本专家”博客文章。 若要创建用于返回枚举值的函数,请参阅枚举和值。 有关详细信息,请参阅关于枚举的“脚本专家”系列博客文章

2-2-3-2. 哈希表键值对

若要生成高效查询,请将 Get-WinEvent cmdlet 和 FilterHashtable 参数结合使用 。FilterHashtable 允许哈希表作为筛选器,以从 Windows 事件日志获取特定信息。 哈希表将使用键值对。 有关哈希表的详细信息,请参阅 about_Hash_Tables

键值对均位于同一行时,必须使用分号将它们分隔开来。 每个键值对位于单独的行时,则无需使用分号。 例如,本文将键值对均放置在单独的行上,因此未使用分号。

本示例使用多个 FilterHashtable 参数的键值对。 完成的查询包括 LogName、ProviderName、Keywords、ID 和 Level。

下表显示了允许的键值对,关于 Get-WinEvent FilterHashtable 参数的文档也包含这些键值对。

下表显示了键名称、数据类型以及数据值是否接受通配符。

键名称 | 值数据类型 | 是否接受通配符?

LogName | <String[]> | 是

ProviderName | <String[]> | 是

路径 | <String[]> | 否

Keywords | <Long[]> | 否

ID | <Int32[]> | 否

层次 | <Int32[]> | 否

StartTime | <DateTime> | 否

EndTime | <DateTime> | 否

UserID | <SID> | 否

数据 | <String[]> | 否

<named-data> | <String[]> | 否

键表示命名事件数据字段。 例如,Perflib 事件 1008 可以包含以下事件数据:


<EventData>

  <Data Name="Service">BITS</Data>

  <Data Name="Library">C:\Windows\System32\bitsperf.dll</Data>

  <Data Name="Win32Error">2</Data>

</EventData>

可以使用以下命令查询这些事件:
Get-WinEvent -FilterHashtable @{LogName=‘Application’; ‘Service’=‘Bits’}

备注:PowerShell 6 中添加了查询 的功能。

2-2-3-3. 使用哈希表生成查询

若要验证结果并解决问题,它帮助生成一次包含一个键值对的哈希表。 查询从“Application”日志获取数据。 哈希表等效于 Get-WinEvent –LogName Application。

首先创建 Get-WinEvent 查询。 使用 FilterHashtable 参数的键值对,其中键为“LogName”,值为“Application”。
Get-WinEvent -FilterHashtable @{

LogName=‘Application’
}

继续使用 ProviderName 键生成哈希表。 ProviderName 是在“Windows 事件查看器”的“源”字段中显示的名称。 例如,下面的屏幕截图中的“.NET 运行时”:

“Windows 事件查看器”源的图片。

更新哈希表,并包含键为 **ProviderName 且值为 .NET 运行时的键值对。
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’.NET Runtime’
}

若查询需要从存档的事件日志获取数据,请使用 Path 键。 Path 值指定日志文件的完整路径。 有关详细信息,请参阅“脚本专家” 博客文章使用 PowerShell 分析保存的事件日志以查找错误

2-2-3-4. 在哈希表中使用枚举值

Keywords 是哈希表中的下一个 键。 Keywords 数据类型是一个包含大量数字的 [long] 值类型的数组。 使用下面的命令查找 [long] 的最大值:
[long]::MaxValue

Output

9223372036854775807

对于 Keywords 键,PowerShell 使用数字,而不是字符串(如 Security)。 “Windows 事件查看器”将 Keywords 显示为字符串,但它们是枚举值。 在哈希表中使用包含字符串值的 Keywords 键时,将显示错误消息。

打开“Windows 事件查看器”,从“操作”窗格单击“筛选当前日志”。 “关键字”下拉菜单将显示可用的关键字,如下面的屏幕截图所示:

“Windows 事件查看器”关键字的图片。

使用下面的命令显示 StandardEventKeywords 属性名称。
[System.Diagnostics.Eventing.Reader.StandardEventKeywords] | Get-Member -Static -MemberType Property

Output

TypeName: System.Diagnostics.Eventing.Reader.StandardEventKeywords

Name MemberType Definition

—- ———- ———-

AuditFailure Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

AuditSuccess Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

CorrelationHint Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

CorrelationHint2 Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

EventLogClassic Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

None Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

ResponseTime Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

Sqm Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

WdiContext Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

WdiDiagnostic Property static System.Diagnostics.Eventing.Reader.StandardEventKey…

枚举值将记录在 .NET Framework 中。 有关详细信息,请参阅 StandardEventKeywords 枚举

Keywords 名称和枚举值如下所示:

名称 | 值

AuditFailure | 4503599627370496

AuditSuccess | 9007199254740992

CorrelationHint2 | 18014398509481984

EventLogClassic | 36028797018963968

Sqm | 2251799813685248

WdiDiagnostic | 1125899906842624

WdiContext | 562949953421312

ResponseTime | 281474976710656

无 | 0

更新哈希表,并包含键为 Keywords 且 EventLogClassic 枚举值为 36028797018963968 的键值对。
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’.NET Runtime’

Keywords=36028797018963968

}

2-2-3-4-1. Keywords 静态属性值(可选)

枚举 Keywords 键,但可以在哈希表查询中使用静态属性名称。 必须使用 Value__ 属性将属性名称转换为值,而非使用返回值。

例如,下面的脚本就使用了 Value__ 属性。
$C = [System.Diagnostics.Eventing.Reader.StandardEventKeywords]::EventLogClassic
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’.NET Runtime’

Keywords=$C.Value__
}

2-2-3-5. 按事件 ID 筛选

若要获取更多特定数据,请按事件 ID 筛选查询的结果。 哈希表将“事件 ID”引用为键 ID,其值为特定的“事件 ID”。 “Windows 事件查看器”将显示“事件 ID”。 此示例使用“事件 ID 1023”。

更新哈希表,并包含键为 ID 且值为 1023 的键值对。
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’.NET Runtime’

Keywords=36028797018963968

ID=1023
}

2-2-3-6. 按级别筛选

若要进一步优化结果并仅包含属于错误的事件,请使用 Level 键。 “Windows 事件查看器”将 Level 显示为字符串值,但它们是枚举值。 在哈希表中使用包含字符串值的 Level 键时,将显示错误消息。

Level 包含诸如“错误”、“警告”或“信息性”等值。 使用下面的命令显示 StandardEventLevel 属性名称。
[System.Diagnostics.Eventing.Reader.StandardEventLevel] | Get-Member -Static -MemberType Property
Output

TypeName: System.Diagnostics.Eventing.Reader.StandardEventLevel

Name MemberType Definition


Critical Property static System.Diagnostics.Eventing.Reader.StandardEventLevel Critical {get;}

Error Property static System.Diagnostics.Eventing.Reader.StandardEventLevel Error {get;}

Informational Property static System.Diagnostics.Eventing.Reader.StandardEventLevel Informational {get;}

LogAlways Property static System.Diagnostics.Eventing.Reader.StandardEventLevel LogAlways {get;}

Verbose Property static System.Diagnostics.Eventing.Reader.StandardEventLevel Verbose {get;}

Warning Property static System.Diagnostics.Eventing.Reader.StandardEventLevel Warning {get;}

枚举值将记录在 .NET Framework 中。 有关详细信息,请参阅 StandardEventLevel 枚举

Level 键的名称和枚举值如下所示:

名称 | 值

Verbose | 5

信息 | 4

警告 | 3

错误 | 2

严重 | 1

LogAlways | 0

完成的查询的哈希表包括 Level 键和值 2。
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’.NET Runtime’

Keywords=36028797018963968

ID=1023

Level=2
}

2-2-3-6-1. 枚举中的 Level 静态属性(可选)

枚举 Level 键,但可以在哈希表查询中使用静态属性名称。 必须使用 Value__ 属性将属性名称转换为值,而非使用返回值。

例如,下面的脚本就使用了 Value__ 属性。
$C = [System.Diagnostics.Eventing.Reader.StandardEventLevel]::Informational
Get-WinEvent -FilterHashtable @{

LogName=‘Application’

ProviderName=’.NET Runtime’

Keywords=36028797018963968

ID=1023

Level=$C.Value__
}

2-3. 管理进程与服务

2-3-1. 使用 Process Cmdlet 管理进程

可以在 Windows PowerShell 中使用 Process cmdlet 来管理 Windows PowerShell 中的本地和远程进程。

2-3-1-1. 获取进程 (Get-Process)

若要获取在本地计算机上运行的进程,请运行不具有参数的 Get-Process。

你可以通过指定其进程名称或进程 ID 来获取特定进程。

2-3-1-1-1. 以下命令将获取空闲进程:

Get-Process -id 0

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


0 0 0 16 0 0 Idle

" 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> Get-Process -id 0

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


0 0 0 16 0 0 Idle

尽管某些情况下 cmdlet 不会返回任何数据很正常,但当你按其 ProcessId 指定一个进程时,如果未找到任何匹配项,Get-Process 将生成一个错误,因为通常的目的是检索一个已知的正在运行的进程。 如果按该 ID 找不到进程,则很可能该 ID 不正确或相关进程已退出:
Get-Process -Id 99

Get-Process : No process with process ID 99 was found.

At line:1 char:12

  • Get-Process PS> Get-Process -Id 99

Get-Process : No process with process ID 99 was found.

At line:1 char:12

  • Get-Process <<<< -Id 99

你可以使用 Get-Process cmdlet 的 Name 参数来基于进程名称指定进程的子集。Name 参数可以采用多个名称(在列表中以逗号分隔),并且支持使用通配符,因此,你可以键入名称模式。

例如,以下命令将获取名称以“ex”开头的进程。
Get-Process -Name ex*

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


234 7 5572 12484 134 2.98 1684 EXCEL

555 15 34500 12384 134 105.25 728 explorer

" 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> Get-Process -Name ex*

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


234 7 5572 12484 134 2.98 1684 EXCEL

555 15 34500 12384 134 105.25 728 explorer

由于 .NET System.Diagnostics.Process 类是 Windows PowerShell 进程的基础,因此它遵循 System.Diagnostics.Process 使用的某些约定。 其中一个约定是可执行文件的进程名从不在可执行文件名的末尾包含“.exe”。

Get-Process 还接受 Name 参数的多个值。
Get-Process -Name exp*,power*

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


540 15 35172 48148 141 88.44 408 explorer

605 9 30668 29800 155 7.11 3052 powershell

" 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> Get-Process -Name exp*,power*

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


540 15 35172 48148 141 88.44 408 explorer

605 9 30668 29800 155 7.11 3052 powershell

可以使用 Get-Process 的 ComputerName 参数获取远程计算机上的进程。 例如,以下命令将获取本地计算机(表示为“localhost”)和两台远程计算机上的 PowerShell 进程。
Get-Process -Name PowerShell -ComputerName localhost, Server01, Server02

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


258 8 29772 38636 130 3700 powershell

398 24 75988 76800 572 5816 powershell

605 9 30668 29800 155 7.11 3052 powershell

" 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> Get-Process -Name PowerShell -ComputerName localhost, Server01, Server02

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


258 8 29772 38636 130 3700 powershell

398 24 75988 76800 572 5816 powershell

605 9 30668 29800 155 7.11 3052 powershell

计算机名在此显示中不可见,但是它们存储在 Get-Process 返回的进程对象的 MachineName 属性中。 下面的命令使用 Format-Table cmdlet 显示进程对象的进程 ID、ProcessName 和 MachineName (ComputerName) 属性。
Get-Process -Name PowerShell -ComputerName localhost, Server01, Server01

Format-Table -Property ID, ProcessName, MachineName

Id ProcessName MachineName


3700 powershell Server01

3052 powershell Server02

5816 powershell localhost

" 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> Get-Process -Name PowerShell -ComputerName localhost, Server01, Server01

Format-Table -Property ID, ProcessName, MachineName

Id ProcessName MachineName


3700 powershell Server01

3052 powershell Server02

5816 powershell localhost

这一更为复杂的命令将 MachineName 属性添加到标准 Get-Process 显示中。
Get-Process powershell -ComputerName localhost, Server01, Server02

Format-Table -Property Handles,

@{Label=&quot;NPM(K)&quot;;Expression={[int]($_.NPM/1024)}},

@{Label=&quot;PM(K)&quot;;Expression={[int]($_.PM/1024)}},

@{Label=&quot;WS(K)&quot;;Expression={[int]($_.WS/1024)}},

@{Label=&quot;VM(M)&quot;;Expression={[int]($_.VM/1MB)}},

@{Label=&quot;CPU(s)&quot;;Expression={if ($_.CPU -ne $()){$_.CPU.ToString(&quot;N&quot;)}}},

Id, ProcessName, MachineName -auto

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName MachineName


258 8 29772 38636 130 3700 powershell Server01

398 24 75988 76800 572 5816 powershell localhost

605 9 30668 29800 155 7.11 3052 powershell Server02

" 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> Get-Process powershell -ComputerName localhost, Server01, Server02

Format-Table -Property Handles,

@{Label="NPM(K)";Expression={[int]($_.NPM/1024)}},

@{Label="PM(K)";Expression={[int]($_.PM/1024)}},

@{Label="WS(K)";Expression={[int]($_.WS/1024)}},

@{Label="VM(M)";Expression={[int]($_.VM/1MB)}},

@{Label="CPU(s)";Expression={if ($_.CPU -ne $()){$_.CPU.ToString("N")}}},

Id, ProcessName, MachineName -auto

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName MachineName


258 8 29772 38636 130 3700 powershell Server01

398 24 75988 76800 572 5816 powershell localhost

605 9 30668 29800 155 7.11 3052 powershell Server02

2-3-1-2. 停止进程 (Stop-Process)

Windows PowerShell 可以灵活地列出进程,但停止进程呢?

Stop-Process cmdlet 将采用 Name 或 ID 来指定想要停止的进程。 能否停止进程取决于你的权限。 某些进程无法停止。 例如,如果你尝试停止空闲进程,则会出现错误:
Stop-Process -Name Idle

Stop-Process : Process ‘Idle (0)’ cannot be stopped due to the following error:

Access is denied

At line:1 char:13

  • Stop-Process PS> Stop-Process -Name Idle

Stop-Process : Process ‘Idle (0)’ cannot be stopped due to the following error:

Access is denied

At line:1 char:13

  • Stop-Process <<<< -Name Idle

你也可以通过使用 Confirm 参数进行强制提示。 如果你在指定进程名称时使用通配符,此参数会特别有用,因为可能会意外地匹配到你不想要停止的一些进程:
Stop-Process -Name t*,e* -Confirm

Confirm

Are you sure you want to perform this action?

Performing operation "Stop-Process" on Target "explorer (408)".

[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help

(default is "Y"):n

Confirm

Are you sure you want to perform this action?

Performing operation "Stop-Process" on Target "taskmgr (4072)".

[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help

(default is "Y"):n

" 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> Stop-Process -Name t*,e* -Confirm

Confirm

Are you sure you want to perform this action?

Performing operation “Stop-Process” on Target “explorer (408)”.

[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help

(default is “Y”):n

Confirm

Are you sure you want to perform this action?

Performing operation “Stop-Process” on Target “taskmgr (4072)”.

[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help

(default is “Y”):n

可以通过使用某些对象筛选 cmdlet 来实现复杂的过程操作。 因为 Process 对象具有 Responding 属性,当程序不再响应时该属性为 true,你可以使用以下命令停止所有无响应的应用程序:
Get-Process | Where-Object -FilterScript {$_.Responding -eq $false} | Stop-Process

在其他情况下,可以使用相同的方法。 例如,假设用户启动另一个应用程序时,辅助通知区域的应用程序将自动运行。 你可能会发现在“终端服务”会话中它无法正常工作,但你仍想要将其保留在物理计算机控制台上运行的会话中。 连接到物理计算机桌面的会话始终具有一个为 0 的会话 ID,这样你可以通过使用 Where-Object 和进程 SessionId 停止在其他会话中的所有进程的实例:
Get-Process -Name BadApp | Where-Object -FilterScript {$_.SessionId -neq 0} | Stop-Process

Stop-Process cmdlet 不具有 ComputerName 参数。 因此,若要在远程计算机上运行停止进程,需要使用 Invoke-Command cmdlet。 例如,若要停止 Server01 远程计算器上的 PowerShell 进程,请键入: Invoke-Command -ComputerName Server01 {Stop-Process Powershell}

2-3-1-3. 停止所有其他 Windows PowerShell 会话

这可能对停止当前会话之外的所有正在运行的 Windows PowerShell 会话偶尔有用。如果会话正在使用过多资源或无法访问(它可能正在远程运行或在另一个桌面会话中运行),可能不能直接将其停止。 如果你尝试停止所有正在运行的会话,但是,这可能会终止当前会话。

每个 Windows PowerShell 会话都具有一个包含 Windows PowerShell 进程的 ID 的环境变量 PID。 你可以对比每个会话的 ID 检查 KaTeX parse error: Expected '}', got 'EOF' at end of input: …-FilterScript {_.Id -ne $PID} | Stop-Process -PassThru

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


334 9 23348 29136 143 1.03 388 powershell

304 9 23152 29040 143 1.03 632 powershell

302 9 20916 26804 143 1.03 1116 powershell

335 9 25656 31412 143 1.09 3452 powershell

303 9 23156 29044 143 1.05 3608 powershell

287 9 21044 26928 143 1.02 3672 powershell

" 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> Get-Process -Name powershell | Where-Object -FilterScript {$_.Id -ne $PID} | Stop-Process -PassThru

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


334 9 23348 29136 143 1.03 388 powershell

304 9 23152 29040 143 1.03 632 powershell

302 9 20916 26804 143 1.03 1116 powershell

335 9 25656 31412 143 1.09 3452 powershell

303 9 23156 29044 143 1.05 3608 powershell

287 9 21044 26928 143 1.02 3672 powershell

2-3-1-4. 启动、调试和等待进程

Windows PowerShell 还附带 cmdlet,以启动(或重启)、调试进程,并在运行命令之前等待进程完成。 有关这些 cmdlet 的信息,请参阅有关每个 cmdlet 的 cmdlet 帮助主题。

2-3-1-5. 另请参阅

2-3-2. 管理服务

有八个专为各种服务任务设计的核心 Service cmdlet。 我们仅会列出和更改服务的运行状态,但你可以使用 Get-Help \*-Service 获取服务 cmdlet 列表并通过使用 Get-Help <Cmdlet-Name>(例如 Get-Help New-Service)找到每个服务 cmdlet 的相关信息。

2-3-2-1. 获取服务

可以通过使用 Get-Service cmdlet 获取本地或远程计算机上的服务。 与使用 Get-Process 相同,使用不带参数的 Get-Service 命令将返回所有服务。 你可以按名称进行筛选,甚至可以使用星号作为通配符:

Get-Service -Name se*

Status   Name			   DisplayName

------   ----			   -----------

Running  seclogon		   Secondary Logon

Running  SENS			   System Event Notification

Stopped  ServiceLayer	   ServiceLayer

" style="box-sizing: inherit; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;">PS> Get-Service -Name se*

Status   Name			   DisplayName

------   ----			   -----------

Running  seclogon		   Secondary Logon

Running  SENS			   System Event Notification

Stopped  ServiceLayer	   ServiceLayer

因为服务的真实名称并不总是可见,所以你可能会发现你需要按显示名称查找服务。可以按特定名称(使用通配符或使用显示名称的列表)执行此操作:

Get-Service -DisplayName se*

Status   Name			   DisplayName

------   ----			   -----------

Running  lanmanserver	   Server

Running  SamSs			  Security Accounts Manager

Running  seclogon		   Secondary Logon

Stopped  ServiceLayer	   ServiceLayer

Running  wscsvc			 Security Center

PS> Get-Service -DisplayName ServiceLayer,Server

Status   Name			   DisplayName

------   ----			   -----------

Running  lanmanserver	   Server

Stopped  ServiceLayer	   ServiceLayer

" style="box-sizing: inherit; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;">PS> Get-Service -DisplayName se*

Status   Name			   DisplayName

------   ----			   -----------

Running  lanmanserver	   Server

Running  SamSs			  Security Accounts Manager

Running  seclogon		   Secondary Logon

Stopped  ServiceLayer	   ServiceLayer

Running  wscsvc			 Security Center

PS> Get-Service -DisplayName ServiceLayer,Server

Status   Name			   DisplayName

------   ----			   -----------

Running  lanmanserver	   Server

Stopped  ServiceLayer	   ServiceLayer

可以使用 Get-Service cmdlet 的 ComputerName 参数获取远程计算机上的服务。ComputerName 参数接受多个值和通配符,因此你可以使用单个命令获取多台计算机上的服务。 例如,下面的命令获取 Server01 远程计算机上的服务。

Get-Service -ComputerName Server01

2-3-2-2. 获取必需和从属服务

Get-Service cmdlet 具有两个在服务管理中非常有用的参数。 DependentServices 参数获取依赖于该服务的服务。 RequiredServices 参数获取此服务所依赖的服务。

这些参数只显示 Get-Service 返回的 System.ServiceProcess.ServiceController 对象的 DependentServices 和 ServicesDependedOn (alias=RequiredServices) 属性的值,但是它们可简化命令,使获取此信息更加简单。

下面的命令获取 LanmanWorkstation 服务需要的服务。

Get-Service -Name LanmanWorkstation -RequiredServices

Status   Name			   DisplayName

------   ----			   -----------

Running  MRxSmb20		   SMB 2.0 MiniRedirector

Running  bowser			 Bowser

Running  MRxSmb10		   SMB 1.x MiniRedirector

Running  NSI				Network Store Interface Service

" style="box-sizing: inherit; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;">PS> Get-Service -Name LanmanWorkstation -RequiredServices

Status   Name			   DisplayName

------   ----			   -----------

Running  MRxSmb20		   SMB 2.0 MiniRedirector

Running  bowser			 Bowser

Running  MRxSmb10		   SMB 1.x MiniRedirector

Running  NSI				Network Store Interface Service

下面的命令获取需要 LanmanWorkstation 服务的服务。

Get-Service -Name LanmanWorkstation -DependentServices

Status   Name			   DisplayName

------   ----			   -----------

Running  SessionEnv		 Terminal Services Configuration

Running  Netlogon		   Netlogon

Stopped  Browser			Computer Browser

Running  BITS			   Background Intelligent Transfer Ser...

" style="box-sizing: inherit; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;">PS> Get-Service -Name LanmanWorkstation -DependentServices

Status   Name			   DisplayName

------   ----			   -----------

Running  SessionEnv		 Terminal Services Configuration

Running  Netlogon		   Netlogon

Stopped  Browser			Computer Browser

Running  BITS			   Background Intelligent Transfer Ser...

你甚至可以获取所有具有依赖关系的服务。 下面的命令所做的就是这些,然后使用 Format-Table cmdlet 来显示计算机上服务的 Status、Name、RequiredServices 和 DependentServices 属性。

Get-Service -Name * | Where-Object {$_.RequiredServices -or $_.DependentServices}

  Format-Table -Property Status, Name, RequiredServices, DependentServices -auto

2-3-2-3. 停止、启动、暂停和重启服务

所有 Service cmdlet 都具有相同的一般形式。 可以按公用名或显示名称指定服务,并使用列表和通配符作为值。 若要停止打印后台处理程序,请使用:

Stop-Service -Name spooler

若要在停止后启动打印后台处理程序,请使用:

Start-Service -Name spooler

若要暂停打印后台处理程序,请使用:

Suspend-Service -Name spooler

虽然 Restart-Service cmdlet 的操作方式与其他 Service cmdlet 的操作方式相同,但是我们将针对它列举一些更复杂的示例。 使用最简单的方式指定服务的名称:

Restart-Service -Name spooler

WARNING: Waiting for service 'Print Spooler (Spooler)' to finish starting...

WARNING: Waiting for service 'Print Spooler (Spooler)' to finish starting...

PS>

" style="box-sizing: inherit; font-family: SFMono-Regular, Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace; font-size: 1em; direction: ltr; position: relative; border: 0px; padding: 0px; display: block; line-height: 19px;">PS> Restart-Service -Name spooler

WARNING: Waiting for service 'Print Spooler (Spooler)' to finish starting...

WARNING: Waiting for service 'Print Spooler (Spooler)' to finish starting...

PS>

你将注意到你收到了有关打印后台处理程序启动的重复警告消息。 执行需要耗费一些时间的服务操作时,Windows PowerShell 将通知你它仍在尝试执行该任务。

如果想要重启多个服务,则可获取服务列表,并对其进行筛选,然后执行重启操作:

Get-Service | Where-Object -FilterScript {$_.CanStop} | Restart-Service

WARNING: Waiting for service 'Computer Browser (Browser)' to finish stopping...

WARNING: Waiting for service 'Computer Browser (Browser)' to finish stopping...

Restart-Service : Cannot stop service 'Logical Disk Manager (dmserver)' because

 it has dependent services. It can only be stopped if the Force flag is set.

At line:1 char:57

+ Get-Service | Where-Object -FilterScript {$_.CanStop} | Restart-Service PS> Get-Service | Where-Object -FilterScript {$_.CanStop} | Restart-Service

WARNING: Waiting for service 'Computer Browser (Browser)' to finish stopping...

WARNING: Waiting for service 'Computer Browser (Browser)' to finish stopping...

Restart-Service : Cannot stop service 'Logical Disk Manager (dmserver)' because

 it has dependent services. It can only be stopped if the Force flag is set.

At line:1 char:57

+ Get-Service | Where-Object -FilterScript {$_.CanStop} | Restart-Service <<<<

WARNING: Waiting for service 'Print Spooler (Spooler)' to finish starting...

WARNING: Waiting for service 'Print Spooler (Spooler)' to finish starting...

虽然这些 Service cmdlet 没有 ComputerName 参数,但是你可通过使用 Invoke-Command cmdlet 在远程计算机上运行它们。 例如,下面的命令在 Server01 远程计算机上重启后台打印程序服务。

Invoke-Command -ComputerName Server01 {Restart-Service Spooler}

2-3-2-4. 设置服务属性

Set-Service cmdlet 更改本地或远程计算机上服务的属性。 因为服务状态是一种属性,所以你可以使用此 cmdlet 来启动、停止和暂停服务。 Set-Service cmdlet 还有一个 StartupType 参数,可让你更改服务启动类型。

若要在 Windows Vista 和 Windows 的更高版本上使用 Set-Service,请使用“以管理员身份运行”选项打开 Windows PowerShell。

有关详细信息,请参阅 Set-Service

2-3-2-5. 另请参阅

2-3-3. 管理 Windows PowerShell 驱动器

Windows PowerShell 驱动器是一个数据存储位置,你可以像访问 Windows PowerShell 中的文件系统驱动器那样访问它。 Windows PowerShell 提供程序将为你创建一些驱动器,例如文件系统驱动器(包括 C: 和 D:)、注册表驱动器(HKCU: 和 HKLM:)和证书驱动器 (Cert:),你也可以创建自己的 Windows PowerShell 驱动器。 这些驱动器非常有用,但它们仅在 Windows PowerShell 内可用。 你无法通过使用其他 Windows 工具(如文件资源管理器或 Cmd.exe)访问它们。

Windows PowerShell 可针对适用于 Windows PowerShell 驱动器的命令使用名词 PSDrive。 有关 Windows PowerShell 会话中的 Windows PowerShell 驱动器列表,请使用 Get-PSDrive cmdlet。
PS> Get-PSDrive

Name Provider Root CurrentLocation


A FileSystem A:\

Alias Alias

C FileSystem C:\ …And Settings\me

cert Certificate \

D FileSystem D:\

Env Environment

Function Function

HKCU Registry HKEY_CURRENT_USER

HKLM Registry HKEY_LOCAL_MACHINE

Variable Variable

尽管显示内容中的驱动器与你的系统上的驱动器有所不同,但是该列表将看起来类似于 Get-PSDrive 命令的输出(如上所示)。

文件系统驱动器是 Windows PowerShell 驱动器的子集。 你可以通过 Provider 列中的 FileSystem 条目标识文件系统驱动器。 (Windows PowerShell 中的文件系统驱动器受 Windows PowerShell FileSystem 提供程序支持。)

若要查看 Get-PSDrive cmdlet 的语法,请使用 Syntax 参数键入 Get-Command 命令:
PS> Get-Command -Name Get-PSDrive -Syntax

Get-PSDrive [[-Name] <String[]>] [-Scope ] [-PSProvider <String[]>] [-Verbose] [-Debug] [-ErrorAction ] [-ErrorVariable ] [-OutVariable ] [-OutBuffer ]

PSProvider 参数允许你仅显示受特定提供程序支持的 Windows PowerShell 驱动器。 例如,若要仅显示受 Windows PowerShell FileSystem 提供程序支持的 Windows PowerShell 驱动器,请使用 PSProvider 参数和 FileSystem 值键入 Get-PSDrive 命令:
PS> Get-PSDrive -PSProvider FileSystem

Name Provider Root CurrentLocation


A FileSystem A:\

C FileSystem C:\ …nd Settings\PowerUser

D FileSystem D:\

若要查看表示注册表配置单元的 Windows PowerShell 驱动器,请使用 PSProvider 参数来仅显示受 Windows PowerShell Registry 提供程序支持的 Windows PowerShell 驱动器:
PS> Get-PSDrive -PSProvider Registry

Name Provider Root CurrentLocation


HKCU Registry HKEY_CURRENT_USER

HKLM Registry HKEY_LOCAL_MACHINE

你还可以将标准 Location cmdlet 与 Windows PowerShell 驱动器结合使用:
PS> Set-Location HKLM:\SOFTWARE
PS> Push-Location .\Microsoft
PS> Get-Location

Path


HKLM:\SOFTWARE\Microsoft

2-3-3-1. 添加新的 Windows PowerShell 驱动器 (New-PSDrive)

你可以通过使用 New-PSDrive 命令添加自己的 Windows PowerShell 驱动器。 若要获取 New-PSDrive 命令的语法,请使用 Syntax 参数输入 Get-Command 命令:
PS> Get-Command -Name New-PSDrive -Syntax

New-PSDrive [-Name] [-PSProvider] [-Root] [-Description ] [-Scope ] [-Credential ] [-Verbose] [-Debug] [-ErrorAction ] [-ErrorVariable ] [-OutVariable ] [-OutBuffer ] [-WhatIf] [-Confirm]

若要创建一个新的 Windows PowerShell 驱动器,你必须提供三个参数:

  1. 驱动器的名称(可使用任何有效的 Windows PowerShell 名称)

  2. PSProvider(将“FileSystem”用于文件系统位置,将“Registry”用于注册表位置)

  3. 根,即指向新驱动器的根目录的路径

例如,可以创建一个名为“Office”的驱动器,它将映射到包含你的计算机上的 Microsoft Office 应用程序的文件夹,例如 C:\Program Files\Microsoft Office\OFFICE11。 若要创建该驱动器,请键入以下命令:
PS> New-PSDrive -Name Office -PSProvider FileSystem -Root “C:\Program Files\Microsoft Office\OFFICE11”

Name Provider Root CurrentLocation


Office FileSystem C:\Program Files\Microsoft Offic…

备注:一般情况下,路径不区分大小写。

在执行所有 Windows PowerShell 驱动器时,请参考新的 Windows PowerShell 驱动器,格式是在名称后面跟一个冒号 ( : )。

Windows PowerShell 驱动器可以使许多任务变得更简单。 例如,Windows 注册表中的某些最重要的项的路径长度非常长,难以访问且难以记住这些路径。 关键的配置信息位于 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion。 若要查看和更改 CurrentVersion 注册表项中的项,你可以创建一个其根在该项中的 Windows PowerShell 驱动器,方法是键入:
PS> New-PSDrive -Name cvkey -PSProvider Registry -Root HKLM\Software\Microsoft\Windows\CurrentVersion

Name Provider Root CurrentLocation


cvkey Registry HKLM\Software\Microsoft\Windows…

然后,你可以像对任何其他驱动器一样,将位置更改为 cvkey: 驱动器:
PS> cd cvkey:

或者:
PS> Set-Location cvkey: -PassThru

Path


cvkey:\

New-PsDrive cmdlet 仅将新的驱动器添加到当前 Windows PowerShell 会话中。 如果关闭 Windows PowerShell 窗口,则会丢失新的驱动器。 若要保存 Windows PowerShell 驱动器,请使用 Export-Console cmdlet 导出当前 Windows PowerShell 会话,然后使用 PowerShell.exe PSConsoleFile 参数来将其导入。 或者,将新的驱动器添加到 Windows PowerShell 配置文件中。

2-3-3-2. 删除 Windows PowerShell 驱动器 (Remove-PSDrive)

你可以通过使用 Remove-PSDrive cmdlet 从 Windows PowerShell 中删除驱动器。 Remove-PSDrive cmdlet 易于使用;若要删除特定 Windows PowerShell 驱动器,只需提供 Windows PowerShell 驱动器名称。

例如,如果你添加了 Office :Windows PowerShell 驱动器(如 New-PSDrive 主题中所示),则可以通过键入以下内容将其删除 :
Remove-PSDrive -Name Office

若要删除 cvkey: Windows PowerShell 驱动器(同样,如 New-PSDrive 主题中所示),请使用以下命令:·
Remove-PSDrive -Name cvkey

可以轻松删除 Windows PowerShell 驱动器,但是如果你位于该驱动器中,则无法删除它。 例如:
PS> cd office:
PS Office:> remove-psdrive -name office

Remove-PSDrive : Cannot remove drive ‘Office’ because it is in use.

At line:1 char:15

  • remove-psdrive <<<< -name office

2-3-3-3. 添加和删除 Windows PowerShell 之外的驱动器

Windows PowerShell 检测在 Windows 中添加或删除的文件系统驱动器,包括映射的网络驱动器、附加的 USB 驱动器,以及通过使用 net use 命令或来自 Windows 脚本宿主 (WSH) 脚本的 WScript.NetworkMapNetworkDrive 和 RemoveNetworkDrive 方法删除的驱动器。

2-3-4. 在 Windows 中使用打印机

你可以通过 PowerShell 使用 WMI 和 WSH 中的 WScript.Network COM 对象来管理打印机。 我们将结合这两种工具来演示特定任务。

2-3-4-1. 列出打印机连接

列出计算机上安装的打印机的最简单方法是使用 WMI Win32_Printer 类:
Get-CimInstance -Class Win32_Printer

此外还可以通过使用通常在 WSH 脚本中使用的 WScript.Network COM 对象列出打印机:
(New-Object -ComObject WScript.Network).EnumPrinterConnections()

由于此命令返回的端口名和打印机设备名的简单字符串集合没有任何可以区分的标签,因此并不容易解释。

2-3-4-2. 添加网络打印机

若要添加新的网络打印机,请使用 WScript.Network:
(New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\Printserver01\Xerox5")

2-3-4-3. 设置默认打印机

若要使用 WMI 设置默认打印机,请在 Win32_Printer 集合中查找打印机,然后调用 SetDefaultPrinter 方法:
$printer = Get-CimInstance -Class Win32_Printer -Filter “Name=‘HP LaserJet 5Si’”
Invoke-CimMethod -InputObject $printer -MethodName SetDefaultPrinter

WScript.Network 使用起来要简单一些,因为它具有 SetDefaultPrinter 方法,该方法仅将打印机名称作为参数:
(New-Object -ComObject WScript.Network).SetDefaultPrinter(‘HP LaserJet 5Si’)

2-3-4-4. 删除打印机连接

若要删除打印机连接,请使用 WScript.Network RemovePrinterConnection 方法:
(New-Object -ComObject WScript.Network).RemovePrinterConnection("\Printserver01\Xerox5")

2-3-5. 执行网络任务

由于 TCP/IP 是最常用的网络协议,因此大多数低级别网络协议管理任务都涉及 TCP/IP。 在本部分中,我们使用 PowerShell 和 WMI 来执行这些任务。

2-3-5-1. 列出计算机的 IP 地址

若要获取本地计算机上使用的所有 IP 地址,请使用以下命令:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true
Select-Object -ExpandProperty IPAddress

此命令的输出与大多数属性列表不同,因为值括在大括号中:
Output

10.0.0.1

fe80::60ea:29a7:a233:7cb7

2601:600:a27f:a470:f532:6451:5630:ec8b

2601:600:a27f:a470:e167:477d:6c5c:342d

2601:600:a27f:a470:b021:7f0d:eab9:6299

2601:600:a27f:a470:a40e:ebce:1a8c:a2f3

2601:600:a27f:a470:613c:12a2:e0e0:bd89

2601:600:a27f:a470:444f:17ec:b463:7edd

2601:600:a27f:a470:10fd:7063:28e9:c9f3

2601:600:a27f:a470:60ea:29a7:a233:7cb7

2601:600:a27f:a470::2ec1

若要了解大括号出现的原因,请使用 Get-Member cmdlet 检查 IPAddress 属性:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
Get-Member -Name IPAddress
Output

TypeName: Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_NetworkAdapterConfiguration

Name MemberType Definition


IPAddress Property string[] IPAddress {get;}

每个网络适配器的 IPAddress 属性实际上是一个数组。 定义中的大括号指示 IPAddress 不是 System.String 值,而是由 System.String 值组成的数组。

2-3-5-2. 列出 IP 配置数据

若要显示每个网络适配器的详细 IP 配置数据,请使用以下命令:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true

网络适配器配置对象的默认显示为一组非常精简的可用信息。 对于深入检查和疑难解答,请使用 Select-Object 或格式设置 cmdlet(例如 Format-List)来指定要显示的属性。

在新式 TCP/IP 网络中,你可能对 IPX 或 WINS 属性不感兴趣。 可以使用 Select-Object 的 ExcludeProperty 参数隐藏以“WINS”或“IPX”名称开头的属性。
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
Select-Object -ExcludeProperty IPX*,WINS*

此命令返回有关 DHCP、DNS、路由以及其他次要 IP 配置属性的详细信息。

2-3-5-3. Ping 计算机

你可以使用 Win32_PingStatus 对计算机执行简单的 Ping 操作。 下面的命令执行 Ping 操作,但返回冗长的输出:
Get-CimInstance -Class Win32_PingStatus -Filter “Address=‘127.0.0.1’”

摘要信息是更为有用的形式,它显示下面的命令生成的 Address、ResponseTime 以及 StatusCode 属性。 Format-Table 的 Autosize 参数调整表列的大小,以使其正确显示在 PowerShell 中。
Get-CimInstance -Class Win32_PingStatus -Filter “Address=‘127.0.0.1’” |
Format-Table -Property Address,ResponseTime,StatusCode -Autosize

Output

Address ResponseTime StatusCode


  1. 0.0.1 0 0

如果 StatusCode 为 0,指明 ping 操作成功。

你可以使用数组借助单个命令对计算机执行 Ping 操作。 由于存在多个地址,因此请使用 ForEach-Object 单独对每个地址执行 Ping 操作:
‘127.0.0.1’,‘localhost’,‘research.microsoft.com’

ForEach-Object -Process {

Get-CimInstance -Class Win32_PingStatus -Filter (“Address=’$_’”)

Select-Object -Property Address,ResponseTime,StatusCode

}

可以使用相同的命令格式对一个子网(例如使用网络号码 (192.168.1.0) 和标准 C 类子网掩码 (255.255.255.0) 的专用网)上的所有计算机执行 Ping 操作。仅在 192.168.1.1 到 192.168.1.254 范围内的地址为合法本地地址(0 始终为网络号码保留,255 是子网广播地址)。

若要在 PowerShell 中表示从 1 到 254 范围内的数字数组,请使用语句 1…254。 可以通过生成数组,然后将值添加到 ping 语句中的部分地址上,执行完整的子网 Ping 操作:
1…254| ForEach-Object -Process {

Get-CimInstance -Class Win32_PingStatus -Filter (“Address='192.168.1.$_ '”) }

Select-Object -Property Address,ResponseTime,StatusCode

请注意,这一用于生成一系列地址的方法也可用于其他地方。 你可以使用以下方式生成完整的地址集:
$ips = 1…254 | ForEach-Object -Process {‘192.168.1.’ + $_}

2-3-5-4. 检索网络适配器属性

在前面部分中,我们提到过你可以使用 Win32_NetworkAdapterConfiguration 类来检索常规配置属性。 尽管不是严格的 TCP/IP 信息,但网络适配器信息(例如 MAC 地址和适配器类型)也可用于了解计算机的运行情况。 若要获取此信息的摘要,请使用下面的命令:
Get-CimInstance -Class Win32_NetworkAdapter -ComputerName .

2-3-5-5. 为网络适配器分配 DNS 域

若要分配 DNS 域以便进行自动名称解析,请使用 Win32_NetworkAdapterConfiguration 的 SetDNSDomain 方法。 由于你单独为每个网络适配器配置分配 DNS 域,因此需要使用 ForEach-Object 语句将域分配给每个适配器:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=$true |
ForEach-Object -Process { $_.SetDNSDomain(‘fabrikam.com’) }

筛选语句 IPEnabled=$true 是必需的,因为即使是在仅使用 TCP/IP 的网络上,计算机上的多个网络适配器配置也不是真正的 TCP/IP 适配器;它们是支持 RAS、PPTP、QoS 和其他适用于所有适配器的服务的常规软件元素,因此没有自己的地址。

可以使用 Where-Object cmdlet,而不是使用 Get-CimInstance 筛选器筛选命令。
Get-CimInstance -Class Win32_NetworkAdapterConfiguration |
Where-Object {KaTeX parse error: Expected 'EOF', got '}' at position 12: _.IPEnabled}̲ | ForEach-Obj…_.SetDNSDomain(‘fabrikam.com’)}

2-3-5-6. 执行 DHCP 配置任务

修改 DHCP 详细信息需处理一组网络适配器,与 DNS 配置的操作相同。 你可通过使用 WMI 执行多种不同的操作,我们将逐步介绍一些常见操作。

2-3-5-6-1. 确定启用 DHCP 的适配器

若要查找计算机上启用了 DHCP 的适配器,请使用下面的命令:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter “DHCPEnabled=$true”

若要排除有IP 配置问题的适配器,可以仅检索已启用 IP 的适配器:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter “IPEnabled= t r u e a n d D H C P E n a b l e d = true and DHCPEnabled= trueandDHCPEnabled=true”

2-3-5-6-2. 检索 DHCP 属性

因为适配器的 DHCP 相关属性通常以“DHCP”开头,所以你可使用 Format-Table 的 Property 参数来仅显示那些属性:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter “DHCPEnabled=$true” | Format-Table -Property DHCP*

2-3-5-6-3. 在每个适配器上启用 DHCP

若要在所有适配器上启用 DHCP,请使用下面的命令:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=KaTeX parse error: Expected '}', got 'EOF' at end of input: …ject -Process {_.EnableDHCP()}

可以使用 Filter 语句“IPEnabled=$true and DHCPEnabled=$false”来避免在已启用 DHCP 的适配器上再次启用,但忽略此步骤不会导致出现错误。

2-3-5-6-4. 释放和续订特定适配器上的 DHCP 租约

Win32_NetworkAdapterConfiguration 类具有 ReleaseDHCPLease 和 RenewDHCPLease 方法。 这两种方法的使用方式相同。 一般情况下,在仅需释放或续订特定子网上的适配器地址时使用这些方法。 在子网上筛选器适配器的最简单方法是仅选择使用该子网的网关的适配器配置。 例如,下面的命令释放本地计算机上适配器上的所有 DHCP 租约,这些适配器正在从 192.168.1.254 获得 DHCP 租约:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter “IPEnabled= t r u e a n d D H C P E n a b l e d = true and DHCPEnabled= trueandDHCPEnabled=true” |
Where-Object {KaTeX parse error: Expected 'EOF', got '}' at position 39: …'192.168.1.254'}̲ | ForEach-Obj…_.ReleaseDHCPLease()}

续订 DHCP 租约的唯一更改是使用 RenewDHCPLease 方法,而不是 ReleaseDHCPLease 方法:
Get-CimInstance -Class Win32_NetworkAdapterConfiguration -Filter “IPEnabled= t r u e a n d D H C P E n a b l e d = true and DHCPEnabled= trueandDHCPEnabled=true” |
Where-Object {KaTeX parse error: Expected 'EOF', got '}' at position 39: …'192.168.1.254'}̲ | ForEach-Obj…_.ReleaseDHCPLease()}

备注:在远程计算机上使用这些方法时,请注意,如果你通过已释放或已续订租约的适配器连接到远程系统,则可能会失去对该系统的访问权限。

2-3-5-6-5. 释放和续订所有适配器上的 DHCP 租约

可以通过使用 Win32_NetworkAdapterConfiguration 方法、ReleaseDHCPLeaseAll 和 RenewDHCPLeaseAll 对所有适配器指定全局 DHCP 地址释放或续订。 但是,该命令必须适用于 WMI 类,而不是特定的适配器,因为全局释放和续订租约是对该类执行的,而不是对特定适配器执行的。

可以通过列出所有 WMI 类,然后按名称仅选择所需类来获取对 WMI 类而不是类实例的引用。 例如,下面的命令将返回 Win32_NetworkAdapterConfiguration 类:
Get-CimInstance -List | Where-Object {$_.Name -eq ‘Win32_NetworkAdapterConfiguration’}

可以将整个命令视为类,并在其上调用ReleaseDHCPAdapterLease 方法。 在下面的命令中,Get-CimInstanceWhere-Object 管道元素两边的括号指示 PowerShell 先对其进行评估:
(Get-CimInstance -List |

Where-Object {$_.Name -eq ‘Win32_NetworkAdapterConfiguration’}).ReleaseDHCPLeaseAll()

可以使用相同的命令格式来调用 RenewDHCPLeaseAll 方法:
(Get-CimInstance -List |

Where-Object {$_.Name -eq ‘Win32_NetworkAdapterConfiguration’}).RenewDHCPLeaseAll()

2-3-5-7. 创建网络共享

若要创建网络共享,请使用 Win32_Share 的 Create 方法:
(Get-CimInstance -List |

Where-Object {$_.Name -eq ‘Win32_Share’}).Create(

‘C:\temp’,‘TempShare’,0,25,‘test share of the temp folder’
)

还可以在 Windows 上的 PowerShell 中使用 net share 来创建共享:
net share tempshare=c:\temp /users:25 /remark:“test share of the temp folder”

2-3-5-8. 删除网络共享

可以使用 Win32_Share 删除网络共享,但是该过程与创建共享略有不同,因为需要检索要删除的特定共享,而不是 Win32_Share 类。 下面的语句删除共享 TempShare :
(Get-CimInstance -Class Win32_Share -Filter “Name=‘TempShare’”).Delete()

在 Windows 中,net share 也可实现此操作:
net share tempshare /delete
Output
tempshare was deleted successfully.

2-3-5-9. 连接 Windows 可访问网络驱动器

New-PSDrive cmdlet 可创建 PowerShell 驱动器,但使用这种方法创建的驱动器仅适用于 PowerShell。 若要创建新的联网驱动器,可以使用 WScript.Network COM 对象。 下面的命令将共享 \\FPS01\users 映射到本地驱动器 B:
(New-Object -ComObject WScript.Network).MapNetworkDrive(‘B:’, ‘\FPS01\users’)

在 Windows 上,net use 命令也可实现此操作:
net use B: \FPS01\users

使用 WScript.Network 或 net use 映射的驱动器可立即用于 PowerShell。

2-3-6. 使用软件安装

可以通过 WMI 的 Win32_Product 类访问旨在使用 Windows Installer 的应用程序,但当今使用的所有应用程序并非都使用 Windows Installer。 使用替代安装例程的应用程序通常不由 Windows Installer 管理。 用于使用这些应用程序的特定技术取决于安装程序软件和应用程序开发人员做出的决策。 例如,通常不能使用此处讨论的技术来管理通过将文件复制到计算机上的文件夹安装的应用程序。 你可以使用在使用文件和文件夹中讨论的技术将这些应用程序作为文件和文件夹进行管理。

注意:Win32_Product 类不是查询优化。 使用通配符筛选器的查询导致 WMI 使用 MSI 提供程序枚举所有已安装的产品,然后按顺序解析完整列表以处理该筛选器。这还会启动已安装包的一致性检查,从而验证和修复安装。 验证是一个缓慢的过程,可能会导致事件日志中出现错误。 有关详细信息,请参阅知识库文章 974524

2-3-6-1. 列出 Windows Installer 应用程序

若要列出随 Windows Installer 一起在本地或远程系统上安装的应用程序,请使用以下简单的 WMI 查询:
Get-CimInstance -Class Win32_Product |
Where-Object Name -eq “Microsoft .NET Core Runtime - 2.1.5 (x64)”

Output

Name Caption Vendor Version IdentifyingNumber


Microsoft .NET … Microsoft .NET Core Runt… Microsoft Corporation 16.84.26919 {BEB59D04-C6DD-4926-AFE…

若要将 Win32_Product 对象的所有属性显示到显示屏中,请使用格式设置 cmdlet(例如 Format-List cmdlet)的“Property” 参数,值为 *(全部)。
Get-CimInstance -Class Win32_Product |
Where-Object Name -eq “Microsoft .NET Core Runtime - 2.1.5 (x64)” |

Format-List -Property *

Output

Name : Microsoft .NET Core Runtime - 2.1.5 (x64)

Version : 16.84.26919

InstallState : 5

Caption : Microsoft .NET Core Runtime - 2.1.5 (x64)

Description : Microsoft .NET Core Runtime - 2.1.5 (x64)

IdentifyingNumber : {BEB59D04-C6DD-4926-AFEB-410CBE2EBCE4}

SKUNumber :

Vendor : Microsoft Corporation

AssignmentType : 1

HelpLink :

HelpTelephone :

InstallDate : 20181105

InstallDate2 :

InstallLocation :

InstallSource : C:\ProgramData\Package Cache{BEB59D04-C6DD-4926-AFEB-410CBE2EBCE4}v16.84.26919\

Language : 1033

LocalPackage : C:\WINDOWS\Installer\4f97a771.msi

PackageCache : C:\WINDOWS\Installer\4f97a771.msi

PackageCode : {9A271A10-039D-49EA-8D24-043D91B9F915}

PackageName : dotnet-runtime-2.1.5-win-x64.msi

ProductID :

RegCompany :

RegOwner :

Transforms :

URLInfoAbout :

URLUpdateInfo :

WordCount : 0

PSComputerName :

CimClass : root/cimv2:Win32_Product

CimInstanceProperties : {Caption, Description, IdentifyingNumber, Name…}

CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

或者,可以使用 Get-CimInstanceFilter 参数来仅选择 Microsoft .NET 2.0 运行时。 “Filter” 参数的值使用 WMI 查询语言 (WQL) 语法,而不是 Windows PowerShell 语法。 例如:
Get-CimInstance -Class Win32_Product -Filter “Name=‘Microsoft .NET Core Runtime - 2.1.5 (x64)’” |
Format-List -Property *

若要仅列出你感兴趣的属性,请使用格式设置 cmdlet 的“Property” 参数列出所需的属性。
Get-CimInstance -Class Win32_Product -Filter “Name=‘Microsoft .NET Core Runtime - 2.1.5 (x64)’” |
Format-List -Property Name,InstallDate,InstallLocation,PackageCache,Vendor,Version,IdentifyingNumber

Output

Name : Microsoft .NET Core Runtime - 2.1.5 (x64)

InstallDate : 20180816

InstallLocation :

PackageCache : C:\WINDOWS\Installer\4f97a771.msi

Vendor : Microsoft Corporation

Version : 16.72.26629

IdentifyingNumber : {ACC73072-9AD5-416C-94BF-D82DDCEA0F1B}

2-3-6-2. 列出所有可卸载的应用程序

由于大多数标准应用程序都向 Windows 注册了卸载程序,我们通过在 Windows 注册表中查找它们便可以在本地对其进行处理。 无法保证找到系统上的每个应用程序。 但可以在下列注册表项的“添加或删除程序” 中显示的列表中查找所有程序:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall 列中的一个值匹配。

我们可以检查此项以查找应用程序。 若要更加轻松地查看 Uninstall 项,我们可以将 PowerShell 驱动器映射到此注册表位置:
New-PSDrive -Name Uninstall -PSProvider Registry -Root HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

Output

Name Provider Root CurrentLocation


Uninstall Registry HKEY_LOCAL_MACHINE\SOFTWARE\Micr…

我们现在具有一个名为“Uninstall:”的驱动器,可用于快速方便地查找应用程序安装。 我们可以查找已安装应用程序的数量,方法是计算’‘Uninstall: PowerShell’'驱动器中的注册表项数:
(Get-ChildItem -Path Uninstall:).Count

Output

459

我们可以使用各种以 Get-ChildItem 开头的技术进一步在此列表中搜索应用程序。 若要获取应用程序列表并将其保存在 $UninstallableApplications 变量中,请使用以下命令:
$UninstallableApplications = Get-ChildItem -Path Uninstall:

若要显示 Uninstall 下注册表项中的注册表条目的值,请使用注册表项的 GetValue 方法。 该方法的值是注册表条目的名称。

例如,若要查找 Uninstall 项中应用程序的显示名称,请使用以下命令:
$UninstallableApplications | ForEach-Object -Process { $_.GetValue(‘DisplayName’) }

不能保证这些值是唯一的。 在以下示例中,两个已安装的项将显示为“Windows Media 编码器 9 系列”:
$UninstallableApplications | Where-Object -FilterScript {
$_.GetValue(“DisplayName”) -eq “Microsoft Silverlight”
}

Output

Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

Name Property


{89F4137D-6C26-4A84-BDB8-2E5A4 AuthorizedCDFPrefix :

BB71E00} Comments :

			Contact			 :

			DisplayVersion	  : 5.1.50918.0

			HelpLink			: https://go.microsoft.com/fwlink/?LinkID=91955

			HelpTelephone	   :

			InstallDate		 : 20190115

			InstallLocation	 : C:\Program Files\Microsoft Silverlight\

			InstallSource	   : c:\ef64c54526db9c34cd477c103e68a254\

			ModifyPath		  : MsiExec.exe /X{89F4137D-6C26-4A84-BDB8-2E5A4BB71E00}

			NoModify			: 1

			NoRepair			: 1

			Publisher		   : Microsoft Corporation

			Readme			  :

			Size				:

			EstimatedSize	   : 236432

			UninstallString	 : MsiExec.exe /X{89F4137D-6C26-4A84-BDB8-2E5A4BB71E00}

			URLInfoAbout		:

			URLUpdateInfo	   :

			VersionMajor		: 5

			VersionMinor		: 1

			WindowsInstaller	: 1

			Version			 : 84002534

			Language			: 1033

			DisplayName		 : Microsoft Silverlight

			sEstimatedSize2	 : 79214

2-3-6-3. 安装应用程序

可以使用 Win32_Product 类远程或本地安装 Windows Installer 程序包。

备注:若要安装应用程序,必须使用“以管理员身份运行”选项启动 PowerShell。

在远程安装时,请使用通用命名约定 (UNC) 网络路径指定 .msi 包的路径,因为 WMI 子系统并不了解 PowerShell 路径。 例如,若要在远程计算机 PC01 上安装位于网络共享 \AppServ\dsp 中的 NewPackage.msi 包,请在 PowerShell 提示符下键入以下命令:
Invoke-CimMethod -ClassName Win32_Product -MethodName Install -Arguments @{PackageLocation=’\AppSrv\dsp\NewPackage.msi’}

不使用 Windows Installer 技术的应用程序可能具有用于自动部署的特定于应用程序的方法。 查看应用程序的文档或咨询应用程序供应商的支持系统。

2-3-6-4. 删除应用程序

通过使用 PowerShell 删除 Windows Installer 程序包与安装程序包的方式大致相同。 下面是一个根据其名称选择要卸载的程序包的示例;在某些情况下,使用 IdentifyingNumber 进行筛选可能会更容易:
Get-CimInstance -Class Win32_Product -Filter “Name=‘ILMerge’” | Invoke-CimMethod -MethodName Uninstall

即使是在本地执行操作,删除其他应用程序也并不那么简单。 我们可以通过提取 UninstallString 属性查找这些应用程序的命令行卸载字符串。 此方法适用于 Windows Installer 应用程序和显示在 Uninstall 项下方的旧程序:
Get-ChildItem -Path Uninstall: | ForEach-Object -Process { $_.GetValue(‘UninstallString’) }

如果愿意,你可以按显示名称筛选输出:
Get-ChildItem -Path Uninstall: |

Where-Object -FilterScript { $_.GetValue(‘DisplayName’) -like ‘Win*’} |

ForEach-Object -Process { $_.GetValue('UninstallString') }

但是,如果不进行一些修改,这些字符串可能无法直接在 PowerShell 提示符下使用。

2-3-6-5. 升级 Windows Installer 应用程序

若要升级应用程序,你需要知道应用程序的名称和应用程序升级包的路径。 借助这些信息,你可以使用单个 PowerShell 命令升级应用程序:
Get-CimInstance -Class Win32_Product -Filter “Name=‘OldAppName’” |

Invoke-CimMethod -MethodName Upgrade -Arguments @{PackageLocation=’\AppSrv\dsp\OldAppUpgrade.msi’}

2-3-7. 从正在运行的进程解码 PowerShell 命令

有时,你可能有一个正在运行的 PowerShell 进程占用了大量资源。 此进程可以在任务计划程序作业或 SQL Server 代理作业的上下文中运行。 在运行多个 PowerShell 进程的位置,很难知道哪个进程表示问题。 本文演示了如何解码 PowerShell 进程当前运行的脚本块。

2-3-7-1. 创建一个长时间运行的进程

要演示此场景,请打开一个新的 PowerShell 窗口并运行以下代码。 它执行一个 PowerShell 命令,每分钟输出一个数字,持续 10 分钟。
powershell.exe -Command {

$i = 1

while ( $i -le 10 )

{

Write-Output -InputObject $i

Start-Sleep -Seconds 60

$i++

}
}

2-3-7-2. 查看进程

PowerShell 正在执行的命令正文存储在 Win32_Process 类的 CommandLine 属性中。 如果命令为编码命令,CommandLine 属性将包含字符串“EncodedCommand”。 使用此信息,可以通过以下进程取消对编码命令的模糊处理。

以管理员身份启动 PowerShell。 以管理员身份运行 PowerShell 至关重要,否则在查询正在运行的进程时不会返回任何结果。

执行以下命令以获取所有具有编码命令的 PowerShell 进程:
$powerShellProcesses = Get-CimInstance -ClassName Win32_Process -Filter ‘CommandLine LIKE “%EncodedCommand%”’

下面的命令创建一个自定义 PowerShell 对象,其中包含进程 ID 和编码命令。
$commandDetails = $powerShellProcesses | Select-Object -Property ProcessId,
@{

name = ‘EncodedCommand’

expression = {

if ( $_.CommandLine -match 'encodedCommand (.*) -inputFormat' )

{

	return $matches[1]

}

}
}

现在可以解码编码命令。 下面的代码片段循环访问命令详细信息对象、解码编码命令,并将解码后的命令添加回该对象,以便进一步研究。
$commandDetails | ForEach-Object -Process {

3. Get the current process

$currentProcess = $_

4. Convert the Base 64 string to a Byte Array

c o m m a n d B y t e s = [ S y s t e m . C o n v e r t ] : : F r o m B a s e 64 S t r i n g ( commandBytes = [System.Convert]::FromBase64String( commandBytes=[System.Convert]::FromBase64String(currentProcess.EncodedCommand)

5. Convert the Byte Array to a string

d e c o d e d C o m m a n d = [ S y s t e m . T e x t . E n c o d i n g ] : : U n i c o d e . G e t S t r i n g ( decodedCommand = [System.Text.Encoding]::Unicode.GetString( decodedCommand=[System.Text.Encoding]::Unicode.GetString(commandBytes)

6. Add the decoded command back to the object

$commandDetails |

Where-Object -FilterScript { $_.ProcessId -eq $_.ProcessId } |

Add-Member -MemberType NoteProperty -Name DecodedCommand -Value $decodedCommand

}
$commandDetails[0]

现在可以通过选择解码后的命令属性来查看已解码的命令。
output
ProcessId : 8752
EncodedCommand : IAAKAAoACgAgAAoAIAAgACAAIAAkAGkAIAA9ACAAMQAgAAoACgAKACAACgAgACAAIAAgAHcAaABpAGwAZQAgACgAIAAkAGkAIAAtAG

wAZQAgADEAMAAgACkAIAAKAAoACgAgAAoAIAAgACAAIAB7ACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABXAHIAaQB0AGUALQBP

AHUAdABwAHUAdAAgAC0ASQBuAHAAdQB0AE8AYgBqAGUAYwB0ACAAJABpACAACgAKAAoAIAAKACAAIAAgACAAIAAgACAAIABTAHQAYQ

ByAHQALQBTAGwAZQBlAHAAIAAtAFMAZQBjAG8AbgBkAHMAIAA2ADAAIAAKAAoACgAgAAoAIAAgACAAIAAgACAAIAAgACQAaQArACsA

IAAKAAoACgAgAAoAIAAgACAAIAB9ACAACgAKAAoAIAAKAA==

DecodedCommand :

	$i = 1

	while ( $i -le 10 )

	{

		Write-Output -InputObject $i

		Start-Sleep -Seconds 60

		$i++

	}

6-1. 管理驱动器与文件

6-1-1. 管理当前位置

在文件资源管理器中导航文件夹系统时,你通常具有一个特定的工作位置(即当前打开的文件夹)。 通过单击当前文件夹中的项,可轻松对其进行操作。 对于命令行接口(例如 Cmd.exe),当你位于特定文件所在的相同文件夹中时,你可以通过指定一个相对较短的名称来访问它,而无需指定该文件的完整路径。 当前目录称为工作目录。

Windows PowerShell 使用名词 Location 来引用工作目录,并实现一系列 cmdlet 以检查你的位置并对其进行操作。

6-1-1-1. 获取你的当前位置 (Get-Location)

若要确定你的当前目录位置的路径,请输入 Get-Location 命令:
Get-Location

Path


C:\Documents and Settings\PowerUser

" 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> Get-Location

Path


C:\Documents and Settings\PowerUser

备注:Get-Location cmdlet 类似于 BASH shell 中的 pwd 命令。 Set-Location cmdlet 类似于 Cmd.exe 中的 cd 命令。

6-1-1-2. 设置你的当前位置 (Set-Location)

Get-Location 命令与 Set-Location 命令结合使用。 Set-Location 命令允许你指定当前目录位置。
Set-Location -Path C:\Windows

输入命令后,你将注意到你不会收到任何有关该命令影响的直接反馈。 执行某项操作的大多数 Windows PowerShell 命令可生成很少的输出或根本不会生成输出,因为该输出并不总是有用。 若要验证在你输入 Set-Location 命令时是否已成功更改目录,请在输入 Set-Location 命令时包括 -PassThru 参数:
Set-Location -Path C:\Windows -PassThru

Path


C:\WINDOWS

" 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> Set-Location -Path C:\Windows -PassThru

Path


C:\WINDOWS

可将 -PassThru 参数与 Windows PowerShell 中的许多 Set 命令结合使用,以在没有默认输出的情况下返回有关结果的信息。

采用在大多数 UNIX 和 Windows 命令 shell 中指定路径的相同方式,指定相对于当前位置的路径。 在相对路径的标准表示法中,句点 ( . ) 表示当前文件夹,而双句点 ( …) 表示当前位置的父目录。

例如,如果你位于 C:\Windows 文件夹中,则句点 ( . ) 表示 C:\Windows,而双句点 ( … ) 表示 C: 。 你可以从当前位置更改到 C: 驱动器的根目录,方法是键入:
Set-Location -Path … -PassThru

Path


C:\

" 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> Set-Location -Path … -PassThru

Path


C:\

相同的技术适用于非文件系统驱动器(例如 HKLM: )的 Windows PowerShell 驱动器。 可以在注册表中将你的位置设置为 HKLM\Software 项,方法是键入:
Set-Location -Path HKLM:\SOFTWARE -PassThru

Path


HKLM:\SOFTWARE

" 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> Set-Location -Path HKLM:\SOFTWARE -PassThru

Path


HKLM:\SOFTWARE

然后,可以通过使用相对路径将目录位置更改为父目录,它是 Windows PowerShell HKLM: 驱动器的根目录:
Set-Location -Path … -PassThru

Path


HKLM:\

" 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> Set-Location -Path … -PassThru

Path


HKLM:\

你可以键入 Set-Location,或使用任何用于 Set-Location(cd、chdir、sl)的内置 Windows PowerShell 别名。 例如:
cd -Path C:\Windows
chdir -Path … -PassThru
sl -Path HKLM:\SOFTWARE -PassThru

6-1-1-3. 保存和重新调用最近的位置(Push-Location 和 Pop-Location)

当更改位置时,它有助于跟踪你访问过的位置并使你能够返回到之前的位置。Windows PowerShell 中的 Push-Location cmdlet 将创建一个你访问过的目录路径的有序历史记录(“堆栈”),你可以通过使用补充的 Pop-Location cmdlet 在目录路径历史记录上返回到之前位置。

例如,Windows PowerShell 通常在用户的主目录中启动。
Get-Location

Path


C:\Documents and Settings\PowerUser

" 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> Get-Location

Path


C:\Documents and Settings\PowerUser

备注:字词 stack 在许多编程设置(包括 .NET Framework)中具有特殊含义。 例如项的物理堆栈,你放置在堆栈上的最后一项是可以从堆栈中提取的第一个项。 将项添加到堆栈俗称为将项“推送”到堆栈上。 从堆栈中提取项俗称为将项从堆栈中“弹出”。

若要将当前位置推送到堆栈上,然后将其移动到“本地设置”文件夹,请键入: Push-Location -Path “Local Settings”

然后,可以将“本地设置”位置推送到堆栈上,并将其移动到临时文件夹,方法是通过键入:
Push-Location -Path Temp

你可以验证是否通过输入 Get-Location 命令更改了目录:

Get-Location

Path


C:\Documents and Settings\PowerUser\Local Settings\Temp

" 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> Get-Location

Path


C:\Documents and Settings\PowerUser\Local Settings\Temp

然后,你可以通过输入 Pop-Location 命令弹回到最近访问的目录中,并且通过输入 Get-Location 命令验证该更改:
Pop-Location

PS> Get-Location

Path


C:\Documents and Settings\me\Local Settings

" 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> Pop-Location

PS> Get-Location

Path


C:\Documents and Settings\me\Local Settings

像 Set-Location cmdlet 一样,当你输入 Pop-Location cmdlet 来显示输入的目录时,你可以包含 -PassThru 参数:
Pop-Location -PassThru

Path


C:\Documents and Settings\PowerUser

" 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> Pop-Location -PassThru

Path


C:\Documents and Settings\PowerUser

还可以将 Location cmdlet 与网络路径结合使用。 如果你有一个名为 FS01 并且共享名为 Public 的服务器,你可以通过键入以下内容更改你的位置
Set-Location \FS01\Public


Push-Location \FS01\Public

你可以使用 Push-Location 和 Set-Location 命令将位置更改为任何可用的驱动器。例如,如果你有驱动号为 D 且包含数据 CD 的本地 CD-ROM 驱动器,你可以通过输入 Set-Location D: 命令将该位置更改为 CD 驱动器。

如果驱动器是空的,你将获得以下错误消息:

Set-Location D:

Set-Location : Cannot find path ‘D:’ because it does not exist.

" 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> Set-Location D:

Set-Location : Cannot find path ‘D:’ because it does not exist.

当你使用命令行接口时,使用文件资源管理器检查可用的物理驱动器会很不方便。此外,文件资源管理器不会向你显示所有 Windows PowerShell 驱动器。 Windows PowerShell 提供一组命令,用于对 Windows PowerShell 驱动器进行操作,我们将在下一步讨论这些命令。

6-1-2. 使用文件和文件夹

在 Windows PowerShell 驱动器中导航和操作其上面的项类似于操作 Windows 物理磁盘驱动器上的文件和文件夹。 本节讨论如何使用 PowerShell 处理特定文件和文件夹操作任务。

6-1-2-1. 列出某个文件夹内的所有文件和文件夹

可以通过使用 Get-ChildItem 直接获取某个文件夹中的所有项目。 添加可选的 Force 参数以显示隐藏项或系统项。 例如,此命令将显示 Windows PowerShell 驱动器 C(它与 Windows 物理驱动器 C 相同)的直观内容:
Get-ChildItem -Path C:\ -Force

该命令将仅列出直接包含的项,类似于使用 Cmd.exe 的 DIR 命令或 UNIX shell 中的 ls。 为了显示包含的项,你还需要指定 -Recurse 参数。 (这可能需要相当长的时间才能完成。)列出 C 驱动器上的所有内容:
Get-ChildItem -Path C:\ -Force -Recurse

Get-ChildItem 可以使用其 Path、Filter、Include 和 Exclude 参数筛选项,但那些通常只基于名称。 还可以通过使用 Where-Object 基于项的其他属性执行复杂的筛选。

下面的命令用于查找上次于 2005 年 10 月 1 日之后修改,并且不小于 1 兆字节,也不大于 10 兆字节的 Program Files 文件夹中的所有可执行文件:
Get-ChildItem -Path KaTeX parse error: Expected '}', got 'EOF' at end of input: …FilterScript {(.LastWriteTime -gt ‘2005-10-01’) -and ( . L e n g t h − g e 1 m b ) − a n d ( _.Length -ge 1mb) -and ( .Lengthge1mb)and(.Length -le 10mb)}

6-1-2-2. 复制文件和文件夹

复制通过 Copy-Item 完成。 以下命令用于将 C:\boot.ini 备份到 C:\boot.bak:
Copy-Item -Path C:\boot.ini -Destination C:\boot.bak

如果目标文件已存在,则复制尝试失败。 若要覆盖预先存在的目标,请使用 Force 参数 :
Copy-Item -Path C:\boot.ini -Destination C:\boot.bak -Force

即使当目标为只读时,该命令也有效。

复制文件夹的操作方式与此相同。 此命令用于以递归方式将文件夹 C:\temp\test1 复制到新文件夹 C:\temp\DeleteMe:
Copy-Item C:\temp\test1 -Recurse C:\temp\DeleteMe

还可以复制选定的项。 以下命令用于将 c:\data 中任意位置包含的所有 .txt 文件复制到 c:\temp\text:
Copy-Item -Filter *.txt -Path c:\data -Recurse -Destination C:\temp\text

你仍然可以使用其他工具执行文件系统复制。 XCOPY、ROBOCOPY 和 COM 对象(如 Scripting.FileSystemObject)都适用于 Windows PowerShell。 例如,可以使用 Windows Script Host Scripting.FileSystem COM 类将 C:\boot.ini 备份到 C:\boot.bak:
(New-Object -ComObject Scripting.FileSystemObject).CopyFile(‘C:\boot.ini’, ‘C:\boot.bak’)

6-1-2-3. 创建文件和文件夹

创建新项的操作方式在所有 Windows PowerShell 提供程序上都相同。 如果某个 Windows PowerShell 提供程序具有多个类型的项(例如,用于区分目录和文件的 FileSystem Windows PowerShell 提供程序),则需要指定项类型。

以下命令可创建一个新文件夹 C:\temp\New Folder:
New-Item -Path ‘C:\temp\New Folder’ -ItemType Directory

以下命令可创建新的空文件 C:\temp\New Folder\file.txt
New-Item -Path ‘C:\temp\New Folder\file.txt’ -ItemType File

6-1-2-4. 删除某个文件夹内的所有文件和文件夹

你可以使用 Remove-Item 删除包含的项,但如果项包含任何其他内容,系统将提示你确认该删除。 例如,如果尝试删除包含其他项的文件夹 C:\temp\DeleteMe,则在删除该文件夹之前 Windows PowerShell 会提示你确认:
Remove-Item -Path C:\temp\DeleteMe

Confirm

The item at C:\temp\DeleteMe has children and the -recurse parameter was not

specified. If you continue, all children will be removed with the item. Are you

sure you want to continue?

[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help

(default is “Y”):

如果不希望系统针对每个包含的项都提示你,则指定 Recurse 参数:
Remove-Item -Path C:\temp\DeleteMe -Recurse

6-1-2-5. 将本地文件夹映射为驱动器

你还可以使用 New-PSDrive 命令映射本地文件夹。 以下命令可在根路径为本地 Program Files 的目录中创建本地驱动器 P:(仅在 PowerShell 会话中可见):
New-PSDrive -Name P -Root $env:ProgramFiles -PSProvider FileSystem

正如网络驱动器一样,在 Windows PowerShell 内映射的驱动器将对 Windows PowerShell shell 立即可见。 若要创建从文件资源管理器中可见的映射驱动器,需要使用参数 -Persist 。 但是,只有远程路径才能与 Persist 一起使用。

6-1-2-6. 将文本文件数据读取到数组中

文本数据更常见的存储格式之一是采用文件形式,其中单独的行被视为不同的数据元素。 Get-Content cmdlet 可用于一步读取整个文件,如下所示:
Get-Content -Path C:\boot.ini

[boot loader]

timeout=5

default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS

[operating systems]

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional"

/noexecute=AlwaysOff /fastdetect

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=" Microsoft Windows XP Professional

with Data Execution Prevention" /noexecute=optin /fastdetect

" 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> Get-Content -Path C:\boot.ini

[boot loader]

timeout=5

default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS

[operating systems]

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=“Microsoft Windows XP Professional”

/noexecute=AlwaysOff /fastdetect

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=" Microsoft Windows XP Professional

with Data Execution Prevention" /noexecute=optin /fastdetect

Get-Content 已将从文件读取的数据视为数组,其中每行文件内容视为一个元素。可以通过检查返回的内容的长度来确认此点:
(Get-Content -Path C:\boot.ini).Length

6

" 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> (Get-Content -Path C:\boot.ini).Length

6

此命令对于直接从 Windows PowerShell 获取列表信息最为有用。 例如,你可能会在文件 C:\temp\domainMembers.txt 中存储计算机名称或 IP 地址的列表,其中文件的每一行上一个名称。 你可以使用 Get-Content 来检索文件内容并将它们放在变量 $Computers 中:
$Computers = Get-Content -Path C:\temp\DomainMembers.txt

$Computers 现在是一个数组,其中每个元素包含一个计算机名。

6-1-3. 使用文件、文件夹和注册表项

Windows PowerShell 使用名词 Item 来引用在 Windows PowerShell 驱动器上找到的项。 处理 Windows PowerShell FileSystem 提供程序时,Item 可能是文件、文件夹或 Windows PowerShell 驱动器。 列出并使用这些项是大部分管理设置中的关键基本任务,因此我们想要详细讨论这些任务。

6-1-3-1. 枚举文件、文件夹和注册表项 (Get-ChildItem)

由于从特定位置获取项的集合是很常见的任务,因此 Get-ChildItem cmdlet 专门用于返回在容器(例如某个文件夹)中找到的所有项。

如果你希望返回直接包含在文件夹 C:\Windows 内的所有文件和文件夹,请键入: PS> Get-ChildItem -Path C:\Windows

Directory: Microsoft.Windows PowerShell.Core\FileSystem::C:\Windows

Mode LastWriteTime Length Name


-a— 2006-05-16 8:10 AM 0 0.log

-a— 2005-11-29 3:16 PM 97 acc1.txt

-a— 2005-10-23 11:21 PM 3848 actsetup.log

列出操作看起来和你在 Cmd.exe 中输入 dir 命令或在 UNIX 命令 shell 中输入 ls 命令时类似。

你可以通过使用 Get-ChildItem cmdlet 的参数来执行非常复杂的列出操作。 接下来,我们将介绍一些方案。 你可以通过键入以下内容来查看 Get-ChildItem cmdlet 的语法:
Get-Command -Name Get-ChildItem -Syntax

可以混合并匹配这些参数以获取高度自定义的输出。

6-1-3-1-1. 列出所有包含的项 (-Recurse)

若要查看 Windows 文件夹内的项和子文件夹内包含的任何项,请使用 Get-ChildItem 的 Recurse 参数。 此列出操作显示 Windows 文件夹内的所有内容及其子文件夹中的项。 例如:
PS> Get-ChildItem -Path C:\WINDOWS -Recurse

Directory: Microsoft.Windows PowerShell.Core\FileSystem::C:\WINDOWS

Directory: Microsoft.Windows PowerShell.Core\FileSystem::C:\WINDOWS\AppPatch

Mode LastWriteTime Length Name


-a— 2004-08-04 8:00 AM 1852416 AcGenral.dll

6-1-3-1-2. 按名称筛选项 (-Name)

若要仅显示项的名称,请使用 Get-Childitem 的 Name 参数:
PS> Get-ChildItem -Path C:\WINDOWS -Name

addins

AppPatch

assembly

6-1-3-1-3. 强制列出隐藏的项 (-Force)

正常情况下在文件资源管理器或 Cmd.exe 中不可见的项不会在 Get-ChildItem 命令的输出中显示。 若要显示隐藏的项,请使用 Get-ChildItem 的 Force 参数。 例如:
Get-ChildItem -Path C:\Windows -Force

此参数的名称为 Force,因为你可以强制替代 Get-ChildItem 命令的正常行为。 Force 是一个广泛使用的参数,此参数可强制执行 cmdlet 通常不会执行的操作,尽管它不会执行任何危害系统安全的操作。

6-1-3-1-4. 使用通配符匹配项名称

Get-ChildItem 命令支持要列出的项路径中的通配符。

由于通配符匹配由 Windows PowerShell 引擎处理,因此接受通配符的所有 cmdlet 使用相同的表示法,并具有相同的匹配行为。 Windows PowerShell 通配符表示法包括:

星号 (*) 匹配零个或多个出现的任何字符。

问号 (?) 完全匹配一个字符。

左括号 ([) 字符和右括号 (]) 字符括起一组要匹配的字符。

下面是一些通配符规则工作原理的示例。

若要在 Windows 目录中查找带有后缀 .log 并且基名称中正好有五个字符的所有文件,请输入以下命令:
PS> Get-ChildItem -Path C:\Windows???.log

Directory: Microsoft.Windows PowerShell.Core\FileSystem::C:\Windows

Mode LastWriteTime Length Name


-a— 2006-05-11 6:31 PM 204276 ocgen.log

-a— 2006-05-11 6:31 PM 22365 ocmsn.log

-a— 2005-11-11 4:55 AM 64 setup.log

-a— 2005-12-15 2:24 PM 17719 VxSDM.log

若要在 Windows 目录中查找以字母 x 开头的所有文件,请键入: Get-ChildItem -Path C:\Windows\x*

若要查找名称以 x 或 z 开头的所有文件,请键入: Get-ChildItem -Path C:\Windows[xz]*

6-1-3-1-5. 排除项 (-Exclude)

你可以通过使用 Get-ChildItem 的 Exclude 参数来排除特定项。 这可让你在单个声明中执行复杂的筛选。

例如,假设你正尝试在 System32 文件夹中查找 Windows Time Service DLL,但是你只记得 DLL 名称以“W”开头并且其中有“32”。

类似于 w*32*.dll 的表达式将找到满足条件的所有 DLL,但它也可能返回名称中包含“95”或“16”的 Windows 95 和 16 位 Windows 兼容性 DLL。 你可以通过将 Exclude 参数与模式 *[9516]* 一起使用来忽略名称中含有任意这些数字的文件:
PS> Get-ChildItem -Path C:\WINDOWS\System32\w32.dll -Exclude [9516]

Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS\System32

Mode LastWriteTime Length Name


-a— 2004-08-04 8:00 AM 174592 w32time.dll

-a— 2004-08-04 8:00 AM 22016 w32topl.dll

-a— 2004-08-04 8:00 AM 101888 win32spl.dll

-a— 2004-08-04 8:00 AM 172032 wldap32.dll

-a— 2004-08-04 8:00 AM 264192 wow32.dll

-a— 2004-08-04 8:00 AM 82944 ws2_32.dll

-a— 2004-08-04 8:00 AM 42496 wsnmp32.dll

-a— 2004-08-04 8:00 AM 22528 wsock32.dll

-a— 2004-08-04 8:00 AM 18432 wtsapi32.dll

6-1-3-1-6. 混合使用 Get-ChildItem 参数

你可以在同一命令中使用 Get-ChildItem cmdlet 的多个参数。 在混合使用参数之前,请确保你了解通配符匹配。 例如,以下命令不会返回任何结果:
Get-ChildItem -Path C:\Windows*.dll -Recurse -Exclude [a-y]*.dll

即使 Windows 文件夹中有两个以字母“z”开头的 DLL,也没有结果。

由于我们已将通配符指定为路径的一部分,因此未返回任何结果。 即使命令是递归的,Get-ChildItem cmdlet 也会将项限制为 Windows 文件夹中名称以“.dll”结尾的项。

若要指定名称匹配特殊模式的文件的递归搜索,请使用 -Include 参数。
PS> Get-ChildItem -Path C:\Windows -Include .dll -Recurse -Exclude [a-y].dll

Directory: Microsoft.Windows PowerShell.Core\FileSystem::C:\Windows\System32\Setup

Mode LastWriteTime Length Name


-a— 2004-08-04 8:00 AM 8261 zoneoc.dll

Directory: Microsoft.Windows PowerShell.Core\FileSystem::C:\Windows\System32

Mode LastWriteTime Length Name


-a— 2004-08-04 8:00 AM 337920 zipfldr.dll

6-1-4. 使用注册表条目

因为注册表条目是项的属性而无法直接浏览,因此我们在使用它们时需要采取略有不同的方式。

6-1-4-1. 列出注册表条目

可采用许多不同的方法检查注册表条目。 最简单的方法是获取与某个项相关联的属性名称。 例如,若要查看注册表项 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion 中的条目名称,请使用 Get-Item。 注册表项具有一个通用名称为“Property”的属性,它是项中的注册表条目的列表。 以下命令选择 Property 属性并扩展这些项,以便它们可在列表中显示:
Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion |

Select-Object -ExpandProperty Property

Output

DevicePath

MediaPathUnexpanded

ProgramFilesDir

CommonFilesDir

ProductId

若要在可读性更强的窗体中查看注册表条目,请使用 Get-ItemProperty:
Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

Output

PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SO

				  FTWARE\Microsoft\Windows\CurrentVersion

PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SO

				  FTWARE\Microsoft\Windows

PSChildName : CurrentVersion

PSDrive : HKLM

PSProvider : Microsoft.PowerShell.Core\Registry

DevicePath : C:\WINDOWS\inf

MediaPathUnexpanded : C:\WINDOWS\Media

ProgramFilesDir : C:\Program Files

CommonFilesDir : C:\Program Files\Common Files

ProductId : 76487-338-1167776-22465

WallPaperDir : C:\WINDOWS\Web\Wallpaper

MediaPath : C:\WINDOWS\Media

ProgramFilesPath : C:\Program Files

PF_AccessoriesName : Accessories

(default) :

该项的 Windows PowerShell 相关的属性全都带有“PS”前缀,例如 PSPath、PSParentPath、PSChildName 和 PSProvider。

可以将 . 表示法用于引用当前位置。 可以先使用 Set-Location 以更改为 CurrentVersion 注册表容器:
Set-Location -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

另外,可以将内置 HKLM PSDrive 与 Set-Location 结合使用:
Set-Location -Path hklm:\SOFTWARE\Microsoft\Windows\CurrentVersion

然后,可以将 . 表示法用于当前位置以列出属性,而无需指定完整路径:
Get-ItemProperty -Path .

Output

DevicePath : C:\WINDOWS\inf

MediaPathUnexpanded : C:\WINDOWS\Media

ProgramFilesDir : C:\Program Files

路径扩展的工作方式与其在文件系统中的工作方式相同,因此在此位置中,你可以通过使用 Get-ItemProperty -Path …\Help 来获取 HKLM:\SOFTWARE\Microsoft\Windows\Help 的 ItemProperty 列表。

6-1-4-2. 获取单个注册表条目

如果你希望在注册表项中检索特定条目,可以使用几种可能的方法之一。 本示例查找 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion 中的 DevicePath 的值。

通过使用 Get-ItemProperty,可使用 Path 参数指定键的名称,使用 Name 参数指定 DevicePath 条目的名称。
Get-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion -Name DevicePath

Output

PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\

		   Microsoft\Windows\CurrentVersion

PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\Software\

		   Microsoft\Windows

PSChildName : CurrentVersion

PSDrive : HKLM

PSProvider : Microsoft.PowerShell.Core\Registry

DevicePath : C:\WINDOWS\inf

此命令返回标准 Windows PowerShell 属性以及 DevicePath 属性。

备注:尽管 Get-ItemProperty 具有 Filter 、Include 和 Exclude 参数,但它们无法用于按属性名称进行筛选。 这些参数引用注册表项(即项路径),而不引用注册表条目。 注册表条目是项属性。

另一种方法是使用 Reg.exe 命令行工具。 有关 reg.exe 的帮助,请在命令提示符下键入 reg.exe /?。 若要查找 DevicePath 条目,请使用 reg.exe,如以下命令中所示:
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion /v DevicePath

Output

! REG.EXE VERSION 3.0

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

DevicePath  REG_EXPAND_SZ   %SystemRoot%\inf

还可以使用 WshShell COM 对象查找某些注册表条目,尽管此方法对大型二进制数据或包含诸如“\”字符的注册表条目名称不起作用也是如此。 将属性名称附加到带有 \ 分隔符的项路径:
(New-Object -ComObject WScript.Shell).RegRead(“HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\DevicePath”)

Output

%SystemRoot%\inf

6-1-4-3. 获取单个注册表条目

如果希望在注册表项中更改特定条目,可以使用几种可能的方法之一。 此示例修改 HKEY_CURRENT_USER\Environment 下的 Path 条目。 Path 条目指定在哪里可以找到可执行文件。

使用 Get-ItemProperty 检索 Path 条目的当前值。

添加新值,将其与 ; 分离。

将 Set-ItemProperty 与指定的键、条目名称和值结合使用,以修改注册表条目。
$value = Get-ItemProperty -Path HKCU:\Environment -Name Path

$newpath = $value.Path += “;C:\src\bin”

Set-ItemProperty -Path HKCU:\Environment -Name Path -Value $newpath

备注:尽管 Set-ItemProperty 具有 Filter 、Include 和 Exclude 参数,但它们无法用于按属性名称进行筛选。 这些参数引用注册表项(即项路径),而不引用注册表条目(即项属性)。

另一种方法是使用 Reg.exe 命令行工具。 有关 reg.exe 的帮助,请键入 reg.exe /? 。

下面的示例通过删除在上面的示例添加的路径来更改 Path 条目。 Get-ItemProperty 仍可用于检索当前值,以避免必须解析从 reg query 返回的字符串。 SubString 和 LastIndexOf 方法用于检索添加到 Path 条目的最后一个路径。
$value = Get-ItemProperty -Path HKCU:\Environment -Name Path

$newpath = $value.Path.SubString(0, $value.Path.LastIndexOf(’;’))

reg add HKCU\Environment /v Path /d $newpath /f

Output

The operation completed successfully.

6-1-4-4. 创建新注册表条目

若要将名为“PowerShellPath”的新条目添加到 CurrentVersion 键,请将 New-ItemProperty 与该键的路径、条目名称和条目的值一起使用。 对于此示例,我们将采用 Windows PowerShell 变量 $PSHome 的值,该变量可存储 Windows PowerShell 的安装目录的路径。

你可以通过使用以下命令来将新条目添加到项,该命令还会返回有关新条目的信息:
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -PropertyType String -Value $PSHome

Output

PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion

PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows

PSChildName : CurrentVersion

PSDrive : HKLM

PSProvider : Microsoft.PowerShell.Core\Registry

PowerShellPath : C:\Program Files\Windows PowerShell\v1.0

PropertyType 必须是以下表格中的 Microsoft.Win32.RegistryValueKind 枚举成员的名称:

PropertyType 值 | 含义

Binary | 二进制数据

DWord | 一个数字,类型为有效的 UInt32

ExpandString | 一个字符串,可包含动态扩展的环境变量

MultiString | 一个多行字符串

字符串 | 任意字符串值

QWord | 8 字节的二进制数据

备注:你可以通过为 Path 参数指定一组值来将注册表条目添加到多个位置:
New-ItemProperty -Name PowerShellPath -PropertyType String -Value $PSHome `

-Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion, HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion

还可以替代预先存在的注册表条目值,方法是将 Force 参数添加到任何 New-ItemProperty 命令。

6-1-4-5. 重命名注册表条目

若要将 PowerShellPath 条目重命名为“PSHome”,请使用 Rename-ItemProperty:
Rename-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -NewName PSHome

若要显示重命名的值,请将 PassThru 参数添加到该命令。
Rename-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -NewName PSHome -passthru

6-1-4-6. 删除注册表条目

若要删除 PSHome 和 PowerShellPath 注册表条目,请使用 Remove-ItemProperty:
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PSHome

Remove-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath

6-1-5. 使用注册表项

由于注册表项是 PowerShell 驱动器上的项,因此使用它们的方法和使用文件及文件夹的方法非常相似。 一个关键区别在于,基于注册表的 PowerShell 驱动器上的每个项都是一个容器,就像文件系统驱动器上有一个文件夹一样。 但是,注册表条目及其关联的值只是项的属性,而不是不同的项。

6-1-5-1. 列出注册表项的所有子项

可以通过使用 Get-ChildItem 直接显示某个注册表项中的所有项目。 添加可选的 Force 参数以显示隐藏项或系统项。 例如,以下命令将直接显示 PowerShell 驱动器 HKCU:(对应于 HKEY_CURRENT_USER 注册表 Hive)中的项:
Get-ChildItem -Path HKCU:\ | Select-Object Name

Output
Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER

Name


HKEY_CURRENT_USER\AppEvents

HKEY_CURRENT_USER\Console

HKEY_CURRENT_USER\Control Panel

HKEY_CURRENT_USER\DirectShow

HKEY_CURRENT_USER\dummy

HKEY_CURRENT_USER\Environment

HKEY_CURRENT_USER\EUDC

HKEY_CURRENT_USER\Keyboard Layout

HKEY_CURRENT_USER\MediaFoundation

HKEY_CURRENT_USER\Microsoft

HKEY_CURRENT_USER\Network

HKEY_CURRENT_USER\Printers

HKEY_CURRENT_USER\Software

HKEY_CURRENT_USER\System

HKEY_CURRENT_USER\Uninstall

HKEY_CURRENT_USER\WXP

HKEY_CURRENT_USER\Volatile Environment

这些是注册表编辑器 (Regedit.exe) 中 HKEY_CURRENT_USER 下可见的顶级项。

还可以通过指定注册表提供程序的名称(后跟“::”)来指定此注册表路径。 注册表提供程序的全名是 Microsoft.PowerShell.Core\Registry,但是可以将其缩短为仅 Registry。 任一以下命令都可直接列出 HKCU: 下面的内容。
Get-ChildItem -Path Registry::HKEY_CURRENT_USER
Get-ChildItem -Path Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER
Get-ChildItem -Path Registry::HKCU
Get-ChildItem -Path Microsoft.PowerShell.Core\Registry::HKCU
Get-ChildItem HKCU:

这些命令将仅列出直接包含的项,类似于使用 Cmd.exe 中的 DIR 或 UNIX shell 中的 ls。 为了显示包含的项,需要指定 Recurse 参数。 若要列出 HKCU: 中的所有注册表项,请使用以下命令。
Get-ChildItem -Path HKCU:\ -Recurse

Get-ChildItem 可以通过其 Path 、Filter 、Include 和 Exclude 参数执行复杂的筛选功能,但这些参数通常只基于名称。 还可以通过使用 Where-Object cmdlet 基于项的其他属性执行复杂的筛选。 下面的命令用于查找 HKCU:\Software 中不止只有一个子项并且刚好具有 4 个值的所有项:
Get-ChildItem -Path HKCU:\Software -Recurse |

Where-Object {( . S u b K e y C o u n t − l e 1 ) − a n d ( _.SubKeyCount -le 1) -and ( .SubKeyCountle1)and(_.ValueCount -eq 4) }

6-1-5-2. 复制项

复制通过 Copy-Item 完成。 下面的示例将 HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion 子项及其所有属性复制到 HKCU:\
Copy-Item -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion’ -Destination HKCU:

如果你在注册表编辑器中或通过使用 Get-ChildItem 检查此新项,你会注意到在新位置中没有所包含子项的副本。 为了复制容器的所有内容,需要指定 Recurse 参数。若要使上述的复制命令递归,你将使用此命令:
Copy-Item -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion’ -Destination HKCU: -Recurse

你仍然可以使用已有的其他可用工具执行文件系统复制。 任何注册表编辑工具(包括 reg.exe 、regini.exe 和 regedit.exe )以及支持注册表编辑的 COM 对象(如 WScript.Shell 和 WMI 的 StdRegProv 类)均可用于 Windows PowerShell。

6-1-5-3. 创建项

在注册表中创建新项比在文件系统中创建新项简单。 由于所有注册表项都是容器,因此,你无需指定项类型;只需提供一个明确的路径即可,如:
New-Item -Path HKCU:\Software_DeleteMe

此外还可以使用基于提供程序的路径来指定某项:
New-Item -Path Registry::HKCU\Software_DeleteMe

6-1-5-4. 删除项

从本质而言,删除项对所有提供程序都是相同的。 以下命令将以无提示方式删除项:
Remove-Item -Path HKCU:\Software_DeleteMe
Remove-Item -Path ‘HKCU:\key with spaces in the name’

6-1-5-5. 删除特定项下的所有项

可以通过使用 Remove-Item 删除包含的项,但如果项包含任何其他内容,系统将提示你确认该删除。 例如,如果我们尝试删除我们创建的 HKCU:\CurrentVersion 子项,我们将看到:
Remove-Item -Path HKCU:\CurrentVersion

Output
Confirm

The item at HKCU:\CurrentVersion\AdminDebug has children and the -recurse

parameter was not specified. If you continue, all children will be removed with

the item. Are you sure you want to continue?

[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is “Y”):

若要在无提示下删除包含的项,请指定 Recurse 参数:
Remove-Item -Path HKCU:\CurrentVersion -Recurse

如果要删除 HKCU:\CurrentVersion 中的所有项,但不删除 HKCU:\CurrentVersion 本身,则可以改用:
Remove-Item -Path HKCU:\CurrentVersion* -Recurse`

6-2. 使用输出

6-2-1. 使用 Out-* Cmdlet 重定向数据

Windows PowerShell 提供多个 cmdlet,可让你直接控制数据输出。 这些 cmdlet 具有两个重要的共同特征。

第一,它们通常将数据转换为某种形式的文本。 这样做的原因是它们将数据输出到需要文本输入的系统组件。 这意味着它们需要将对象表示为文本。 因此,文本的格式设置为你在 Windows PowerShell 控制台窗口中看到的形式。

第二,这些 cmdlet 使用 Windows PowerShell 谓词 Out,因为它们会将信息从 Windows PowerShell 发送到别处。 Out-Host cmdlet 也不例外:主机窗口显示在 Windows PowerShell 之外。 这一点尤为重要,原因是将数据发送出 Windows PowerShell 时,实际上已删除该数据。 在你尝试创建用于将数据分页到主机窗口的管道,然后尝试将其格式化为列表时,可以看到此内容,如下所示:
Get-Process | Out-Host -Paging | Format-List

你可能希望命令显示列表格式的进程信息页。 但是,它将显示默认表格式列表:

output

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName


101	   5	 1076	   3316	32	 0.05   2888 alg

618	  18	39348	  51108   143   211.20	740 explorer

257	   8	 9752	  16828	79	 3.02   2560 explorer

next page; next line; Q quit

Out-Host cmdlet 直接将数据发送到控制台,因此 Format-List 命令绝不会收到任何要进行格式化的内容。

构建此命令的正确方法是将 Out-Host cmdlet 置于管道末尾,如下所示。 这将导致进程数据先在列表中格式化,然后再分页和显示。
PS> Get-Process | Format-List | Out-Host -Paging

Id : 2888

Handles : 101

CPU : 0.046875

Name : alg

Id : 740

Handles : 612

CPU : 211.703125

Name : explorer

Id : 2560

Handles : 257

CPU : 3.015625

Name : explorer

next page; next line; Q quit

这适用于所有 Out cmdlet。 Out cmdlet 应始终出现在管道末尾。

备注:所有 Out cmdlet 都使用对控制台窗口有效的格式(包括行长度限制)将输出呈现为文本。

6-2-1-1. 分页控制台输出 (Out-Host)

默认情况下,Windows PowerShell 将数据发送到主机窗口,这正是 Out-Host cmdlet 的用途。 Out-Host cmdlet 的主要用途是对数据进行分页,如前面所述。 例如,下面的命令使用 Out-Host 对 Get-Command cmdlet 的输出进行分页:
Get-Command | Out-Host -Paging

你还可以使用 more 函数对数据进行分页。 在 Windows PowerShell 中,more 是调用 Out-Host -Paging 的函数。 下面的命令演示了如何使用 more 函数对 Get-Command 的输出进行分页:
Get-Command | more

如果将一个或多个文件名作为参数包括到 more 函数中,则该函数将读取指定文件并将其内容分页到主机中:
PS> more c:\boot.ini

[boot loader]

timeout=5

default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS

[operating systems]

6-2-1-2. 放弃输出 (Out-Null)

Out-Null cmdlet 旨在用于立即放弃接收的任何输入。 这对放弃收到的不利于运行命令的不必要数据很有用。 键入下面的命令时,该命令不会返回任何内容:
Get-Command | Out-Null

Out-Null cmdlet 不会放弃错误输出。 例如,如果输入下面的命令,则将显示一条消息,通知你 Windows PowerShell 无法识别“Is-NotACommand”:
PS> Get-Command Is-NotACommand | Out-Null

Get-Command : ‘Is-NotACommand’ is not recognized as a cmdlet, function, operabl

e program, or script file.

At line:1 char:12

  • Get-Command <<<< Is-NotACommand | Out-Null

6-2-1-3. 打印数据 (Out-Printer)

可以通过使用 Out-Printer cmdlet 打印数据。 如果未提供打印机名称,则 Out-Printer cmdlet 将使用默认打印机。 可以通过指定其显示名称使用任何基于 Windows 的打印机。 无需使用任何类型的打印机端口映射,甚至无需使用真正的物理打印机。 例如,如果安装了 Microsoft Office 文档映像工具,则可通过键入以下内容将数据发送到映像文件:
Get-Command Get-Command | Out-Printer -Name ‘Microsoft Office Document Image Writer’

6-2-1-4. 保存数据 (Out-File)

可以使用 Out-File cmdlet 将输出发送到文件而不是控制台窗口。

下面的命令行将进程列表发送到文件 C:\temp\processlist.txt:
Get-Process | Out-File -FilePath C:\temp\processlist.txt

如果你习惯使用传统的输出重定向,则使用 Out-File cmdlet 可能与你的预期结果有所不同。 若要了解其行为,必须知道运行 Out-File cmdlet 的上下文。

默认情况下,Out-File cmdlet 创建 Unicode 文件。 从长远来看,这是最佳默认操作,但是它意味着应创建 ASCII 文件的工具将无法使用默认的输出格式正常运作。 可以使用 Encoding 参数将默认输出格式更改为 ASCII:
Get-Process | Out-File -FilePath C:\temp\processlist.txt -Encoding ASCII

Out-File 将文件内容格式化为与控制台输出类似的形式。 这会导致输出被截断,大多数情况下正如它在控制台窗口中一样。 例如,如果运行下面的命令:
Get-Command | Out-File -FilePath c:\temp\output.txt

输出将如下所示:

CommandType Name Definition


Cmdlet Add-Content Add-Content [-Path] <String[…

Cmdlet Add-History Add-History [[-InputObject] …

若要使不会强制换行的输出与屏幕宽度匹配,可以使用 Width 参数来指定行宽。 因为 Width 是一个 32 位整数参数,因此其最大值可以是 2147483647。 键入以下内容以将行宽设置为此最大值:
Get-Command | Out-File -FilePath c:\temp\output.txt -Width 2147483647

想要保存原本显示在控制台中的输出时,使用 Out-File cmdlet 最有用。 若要更好地控制输出格式,需要更高级的工具。 我们将在下一章中查看这些内容以及有关对象操作的一些详细信息。

6-2-2. 使用格式命令更改输出视图

PowerShell 具有一组 cmdlet,可让你控制特定对象的属性的显示方式。 所有 cmdlet 的名称都以谓词 Format 开头。 它们使你可以选择要显示的属性。
Get-Command -Verb Format -Module Microsoft.PowerShell.Utility

输出

CommandType Name Version Source


Cmdlet Format-Custom 6.1.0.0 Microsoft.PowerShell.Utility

Cmdlet Format-Hex 6.1.0.0 Microsoft.PowerShell.Utility

Cmdlet Format-List 6.1.0.0 Microsoft.PowerShell.Utility

Cmdlet Format-Table 6.1.0.0 Microsoft.PowerShell.Utility

Cmdlet Format-Wide 6.1.0.0 Microsoft.PowerShell.Utility

本文介绍 Format-Wide、Format-List 和 Format-Table cmdlet。

PowerShell 中的每个对象类型都具有未指定要显示的属性时使用的默认属性。 各 cmdlet 也使用相同的 Property 参数,来指定要显示的属性 。 因为 Format-Wide 只显示单个属性,其 Property 参数仅采用单个值,但 Format-List 和 Format-Table 的属性参数接受一系列属性名称 。

在此示例中,Get-Process cmdlet 的默认输出显示,我们有两个正在运行的 Internet Explorer 实例。
Get-Process -Name iexplore

Process 对象的默认格式显示如下属性 :

输出

NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName


32 25.52 10.25 13.11 12808 1 iexplore

52 11.46 26.46 3.55 21748 1 iexplore

6-2-2-1. 将 Format-Wide 用于 Single-Item 输出

默认情况下,Format-Wide cmdlet 只显示对象的默认属性。 与每个对象关联的信息将显示在单个列中:
Get-Command -Verb Format | Format-Wide

输出

Format-Custom Format-Hex

Format-List Format-Table

Format-Wide

你还可以指定非默认属性:
Get-Command -Verb Format | Format-Wide -Property Noun

输出

Custom Hex

List Table

Wide

6-2-2-1-1. 使用列控制 Format-Wide 显示

使用 Format-Wide cmdlet 时,每次只能显示一个属性。 这可用于在多个列中显示大型列表。
Get-Command -Verb Format | Format-Wide -Property Noun -Column 3

输出

Custom Hex List

Table Wide

6-2-2-2. 将 Format-List 用于列表视图

Format-List cmdlet 以列表的形式显示对象,同时标记每个属性并在单独的行上显示:
Get-Process -Name iexplore | Format-List

输出

Id : 12808

Handles : 578

CPU : 13.140625

SI : 1

Name : iexplore

Id : 21748

Handles : 641

CPU : 3.59375

SI : 1

Name : iexplore

你可以指定所需数目的属性:
Get-Process -Name iexplore | Format-List -Property ProcessName,FileVersion,StartTime,Id

输出

ProcessName : iexplore

FileVersion : 11.00.18362.1 (WinBuild.160101.0800)

StartTime : 10/22/2019 11:23:58 AM

Id : 12808

ProcessName : iexplore

FileVersion : 11.00.18362.1 (WinBuild.160101.0800)

StartTime : 10/22/2019 11:23:57 AM

Id : 21748

6-2-2-2-1. 通过将 Format-List 与通配符搭配使用获取详细信息

Format-List cmdlet 使你可以将通配符用作其 Property 参数的值 。 这样便可以显示详细信息。 通常情况下,对象包含的信息比你需要的多,这就是默认情况下 PowerShell 不显示所有属性值的原因。 若要显示对象的全部属性,则使用 Format-List -Property * 命令。 下面的命令针对单个进程生成超过 60 行的输出:
Get-Process -Name iexplore | Format-List -Property *

虽然 Format-List 命令对显示详细信息很有用,但如果你想要包括多个项目的输出的概述,更常用的是一个更简单的表格视图。

6-2-2-3. 将 Format-Table 用于表格输出

如果你在没有指定属性名称的情况下使用 Format-Table cmdlet 来格式化 Get-Process 命令的输出,你所得到的输出会和未使用 Format cmdlet 执行任何格式设置时得到的完全一样。 默认情况下,PowerShell 以表格格式显示 Process 对象 。
Get-Service -Name win* | Format-Table

输出

Status Name DisplayName


Running WinDefend Windows Defender Antivirus Service

Running WinHttpAutoProx… WinHTTP Web Proxy Auto-Discovery Se…

Running Winmgmt Windows Management Instrumentation

Running WinRM Windows Remote Management (WS-Manag…

6-2-2-3-1. 改进 Format-Table 输出(自动调整大小)

尽管表格视图对显示大量信息很有用,但如果显示区域对于数据来说太窄,则可能导致数据难以理解。 在上面的示例中,输出被截断。 当你运行 Format-Table 命令时,如果你指定 AutoSize 参数,PowerShell 会根据显示的实际数据来计算列宽。 这使得列可读。
Get-Service -Name win* | Format-Table -AutoSize

输出

Status Name DisplayName


Running WinDefend Windows Defender Antivirus Service

Running WinHttpAutoProxySvc WinHTTP Web Proxy Auto-Discovery Service

Running Winmgmt Windows Management Instrumentation

Running WinRM Windows Remote Management (WS-Management)

Format-Table cmdlet 仍可能会截断数据,但仅会在屏幕的末尾处进行截断。 除最后一个显示的属性外,会让所有属性获得各自所需的大小,以使最长的数据元素得以正确显示。
Get-Service -Name win* | Format-Table -Property Name,Status,StartType,DisplayName,DependentServices -AutoSize

输出

Name Status StartType DisplayName DependentServices


WinDefend 自动运行Windows Defender Antivirus 服务 {}

WinHttpAutoProxySvc 手工运行 WinHTTP Web代理 自动发现 服务 {NcaSvc, iphl…

Winmgmt 自动运行Windows 管理 Instrumentation {vmms, TPHKLO…

WinRM 自动运行Windows 远程管理 (WS-Management) {}

Format-Table 命令假设按重要性顺序列出属性。 因此,它会尝试完整显示离列表开头最近的那些属性。 如果 Format-Table 命令无法显示所有属性,则会从显示中删除某些列。 可以在 DependentServices 属性前一个示例中查看此行为 。

6-2-2-3-2. 让列中的 Format-Table 输出自动换行 (Wrap)

可以通过使用 Wrap 参数让较长的 Format-Table 数据在其显示列中自动换行 。 使用 Wrap 参数可能不会实现所需的操作,因为如果你不同时指定 AutoSize,它会使用默认设置 :
Get-Service -Name win* | Format-Table -Property Name,Status,StartType,DisplayName,DependentServices -Wrap

输出

Name Status StartType DisplayName DependentServices


WinDefend 自动运行 Windows Defender Antivirus 服务 {}

WinHttpAutoProxySvc 手动运行 WinHTTP Web 代理 自动发现 服务 {NcaSvc,iphlpsvc}

Winmgmt 自动运行 Windows 管理 Instrumentation {vmms,TPHKLOAD,SUService,smstsmgr…}

WinRM 自动运行 Windows 远程管理 (WS-Management) {}

使用 Wrap 参数基本不会减慢进程速度 。 但是,使用 AutoSize 格式化大型目录结构的递归文件列表可能得耗用大量时间和内存,才能显示第一批输出项 。

如果你并不关心系统负载,那么结合使用 AutoSize 和 Wrap 参数则会获得良好的效果 。 初始列仍根据需要最大限度地使用宽度来在一行上显示项,但在必要时将最后一列换行。

备注:当你首先指定最宽的列时,可能不会显示某些列。 为了获得最佳结果,请先指定最小的数据元素。

在下面的示例中,我们首先指定最宽的属性。
Get-Process -Name iexplore | Format-Table -Wrap -AutoSize -Property FileVersion,Path,Name,Id

即使进行了换行,也会省略最后 ID 列 :

输出

FileVersion Path Name


11.00.18362.1 (WinBuild.160101.0800) C:\Program Files (x86)\Internet Explorer\IEXPLORE.EXE iexplore

11.00.18362.1 (WinBuild.160101.0800) C:\Program Files\Internet Explorer\iexplore.exe iexplore

6-2-2-3-3. 组织选项卡输出 (-GroupBy)

用于表格输出控制的另一个有用参数是 GroupBy。 较长的列表可能尤其难以进行比较。 GroupBy 参数基于属性值对输出进行分组 例如,我们可以按 StartType 对服务分组以便于检查,同时从属性列表中省略 StartType 值 :
Get-Service -Name win* | Sort-Object StartType | Format-Table -GroupBy StartType

输出

StartType: Automatic

Status Name DisplayName


Running WinDefend Windows Defender Antivirus Service

Running Winmgmt Windows Management Instrumentation

Running WinRM Windows Remote Management (WS-Managem…

StartType: Manual

Status Name DisplayName


Running WinHttpAutoProxyS… WinHTTP Web Proxy Auto-Discovery Serv…

6-3. 创建 UI 元素

6-3-1. 创建自定义输入框

通过使用 Windows PowerShell 3.0 及更高版本中的 Microsoft .NET Framework 窗体构建功能为图形自定义输入框编写脚本。

6-3-1-1. 创建自定义图形输入框

复制以下内容并将其粘贴到 Windows PowerShell ISE 中,然后将其另存为 Windows PowerShell 脚本 (.ps1)。


Add-Type -AssemblyName System.Windows.Forms

Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form

$form.Text = 'Data Entry Form'

$form.Size = New-Object System.Drawing.Size(300,200)

$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button

$okButton.Location = New-Object System.Drawing.Point(75,120)

$okButton.Size = New-Object System.Drawing.Size(75,23)

$okButton.Text = 'OK'

$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

$form.AcceptButton = $okButton

$form.Controls.Add($okButton)

$cancelButton = New-Object System.Windows.Forms.Button

$cancelButton.Location = New-Object System.Drawing.Point(150,120)

$cancelButton.Size = New-Object System.Drawing.Size(75,23)

$cancelButton.Text = 'Cancel'

$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

$form.CancelButton = $cancelButton

$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label

$label.Location = New-Object System.Drawing.Point(10,20)

$label.Size = New-Object System.Drawing.Size(280,20)

$label.Text = 'Please enter the information in the space below:'

$form.Controls.Add($label)

$textBox = New-Object System.Windows.Forms.TextBox

$textBox.Location = New-Object System.Drawing.Point(10,40)

$textBox.Size = New-Object System.Drawing.Size(260,20)

$form.Controls.Add($textBox)

$form.Topmost = $true

$form.Add_Shown({$textBox.Select()})

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)

{

	$x = $textBox.Text

	$x

}

该脚本首先加载两个 .NET Framework 类:System.Drawing 和 System.Windows.Forms 。 然后,启动 .NET Framework 类 System.Windows.Forms.Form 的新实例;它提供一个可以开始添加控件的空白窗体或窗口。
$form = New-Object System.Windows.Forms.Form

在创建 Form 类的实例后,为此类的三个属性赋值。

文本。 这将成为该窗口的标题。

大小。 这是窗体的大小(以像素为单位)。 上述脚本创建的窗体大小为宽 300 像素、高 200 像素。

StartingPosition。 在上述脚本中,此可选属性将设置为 CenterScreen。 如果未添加此属性,Windows 将在窗体打开时选择一个位置。 通过将 StartingPosition 设置为 CenterScreen,可使窗体在每次加载时都自动显示在屏幕中间。

$form.Text = ‘Data Entry Form’

$form.Size = New-Object System.Drawing.Size(300,200)

$form.StartPosition = ‘CenterScreen’

接下来,为窗体创建“确定”按钮。 指定“确定”按钮的大小和行为。 在此示例中,按钮位置为距窗体上边缘 120 像素,距左边缘 75 像素。 按钮高度为 23 像素,按钮长度为 75 像素。 此脚本使用预定义的 Windows 窗体类型确定按钮行为。

$okButton = New-Object System.Windows.Forms.Button

$okButton.Location = New-Object System.Drawing.Point(75,120)

$okButton.Size = New-Object System.Drawing.Size(75,23)

$okButton.Text = ‘OK’

$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

$form.AcceptButton = $OKButton

f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(OKButton)

采用相同方式创建“取消”按钮。 “取消”按钮距窗口上边缘 120 像素,但距左边缘 150 像素。

$cancelButton = New-Object System.Windows.Forms.Button

$cancelButton.Location = New-Object System.Drawing.Point(150,120)

$cancelButton.Size = New-Object System.Drawing.Size(75,23)

$cancelButton.Text = ‘Cancel’

$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

$form.CancelButton = $cancelButton

f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(cancelButton)

接下来,在窗口上提供标签文本,用于描述你希望用户提供的信息。

$label = New-Object System.Windows.Forms.Label

$label.Location = New-Object System.Drawing.Point(10,20)

$label.Size = New-Object System.Drawing.Size(280,20)

$label.Text = ‘Please enter the information in the space below:’

f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(label)

添加控件(在本例中为文本框),从而让用户提供你在标签文本中描述的信息。 除了文本框,你还可以应用许多其他控件;有关更多控件,请参阅 MSDN 上的 System.Windows.Forms 命名空间。

$textBox = New-Object System.Windows.Forms.TextBox

$textBox.Location = New-Object System.Drawing.Point(10,40)

$textBox.Size = New-Object System.Drawing.Size(260,20)

f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(textBox)

将 Topmost 属性设置为 $True ,以强制此窗口在其他已打开的窗口和对话框之上打开。
$form.Topmost = $true

接下来,添加此代码行以激活窗体,并将焦点设置到你创建的文本框。
KaTeX parse error: Expected '}', got 'EOF' at end of input: …orm.Add_Shown({textBox.Select()})

添加以下代码行以在 Windows 中显示该窗体。
$result = $form.ShowDialog()

最后,If 块内的代码指示在用户在文本框中提供文本,然后单击“确定”按钮或按“Enter”键后,Windows 应如何处理该窗体。
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{

$x = $textBox.Text

$x
}

6-3-1-2. 另请参阅

6-3-2. 创建图形日期选取器

使用 Windows PowerShell 3.0 和更高版本创建一个带有日历式图形控件的窗体,该控件使用户可以选择本月的某一天。

6-3-2-1. 创建图形日期选取器控件

复制以下内容并将其粘贴到 Windows PowerShell ISE 中,然后将其另存为 Windows PowerShell 脚本 (.ps1)。
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object Windows.Forms.Form -Property @{

StartPosition = [Windows.Forms.FormStartPosition]::CenterScreen

Size = New-Object Drawing.Size 243, 230

Text = ‘Select a Date’

Topmost = $true
}
$calendar = New-Object Windows.Forms.MonthCalendar -Property @{

ShowTodayCircle = $false

MaxSelectionCount = 1
}
f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(calendar)
$okButton = New-Object Windows.Forms.Button -Property @{

Location = New-Object Drawing.Point 38, 165

Size = New-Object Drawing.Size 75, 23

Text = ‘OK’

DialogResult = [Windows.Forms.DialogResult]::OK
}
$form.AcceptButton = $okButton
f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(okButton)
$cancelButton = New-Object Windows.Forms.Button -Property @{

Location = New-Object Drawing.Point 113, 165

Size = New-Object Drawing.Size 75, 23

Text = ‘Cancel’

DialogResult = [Windows.Forms.DialogResult]::Cancel
}
$form.CancelButton = $cancelButton
f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(cancelButton)
$result = f o r m . S h o w D i a l o g ( ) i f ( form.ShowDialog() if ( form.ShowDialog()if(result -eq [Windows.Forms.DialogResult]::OK) {

$date = $calendar.SelectionStart

Write-Host “Date selected: ( ( (date.ToShortDateString())”
}

该脚本首先加载两个 .NET Framework 类:System.Drawing 和 System.Windows.Forms 。 然后,启动 .NET Framework 类 Windows.Forms.Form 的新实例;它提供一个可以开始添加控件的空白窗体或窗口。
$form = New-Object Windows.Forms.Form -Property @{

StartPosition = [Windows.Forms.FormStartPosition]::CenterScreen

Size = New-Object Drawing.Size 243, 230

Text = ‘Select a Date’

Topmost = $true
}

此示例使用 Property 属性和 hashtable 将值分配给此类的四个属性 。

  1. StartPosition:如果未添加此属性,Windows 将在窗体打开时选择一个位置。 通过将此属性设置为 CenterScreen ,可使窗体在每次加载时都自动显示在屏幕中间。

  2. Size:这是窗体的大小(以像素为单位)。 上述脚本创建的窗体大小为宽 243 像素、高 230 像素。

  3. Text:这将成为该窗口的标题。

  4. Topmost:通过将此属性设置为 $true,可以强制此窗口在其他已打开的窗口和对话框之上打开。

接下来,在窗体中创建并添加一个日历控件。 在此示例中,当前日期未突出显示或带圆圈。 用户一次只可以在日历上选择一天。
$calendar = New-Object Windows.Forms.MonthCalendar -Property @{

ShowTodayCircle = $false

MaxSelectionCount = 1
}
f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(calendar)

接下来,为窗体创建“确定”按钮。 指定“确定”按钮的大小和行为。 在此示例中,按钮位置为距窗体上边缘 165 像素,距左边缘 38 像素。 按钮高度为 23 像素,按钮长度为 75 像素。 此脚本使用预定义的 Windows 窗体类型确定按钮行为。
$okButton = New-Object Windows.Forms.Button -Property @{

Location = New-Object Drawing.Point 38, 165

Size = New-Object Drawing.Size 75, 23

Text = ‘OK’

DialogResult = [Windows.Forms.DialogResult]::OK
}
$form.AcceptButton = $okButton
f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(okButton)

采用相同方式创建“取消”按钮。 “取消”按钮距窗口上边缘 165 像素,但距左边缘 113 像素。
$cancelButton = New-Object Windows.Forms.Button -Property @{

Location = New-Object Drawing.Point 113, 165

Size = New-Object Drawing.Size 75, 23

Text = ‘Cancel’

DialogResult = [Windows.Forms.DialogResult]::Cancel
}
$form.CancelButton = $cancelButton
f o r m . C o n t r o l s . A d d ( form.Controls.Add( form.Controls.Add(cancelButton)

添加以下代码行以在 Windows 中显示该窗体。
$result = $form.ShowDialog()

最后,if 块内的代码指示在用户在日历上选择某一天,然后单击“确定”按钮或按“Enter”键后,Windows 应如何处理该窗体 。 Windows PowerShell 向用户显示选定的日期。
if ($result -eq [Windows.Forms.DialogResult]::OK) {

$date = $calendar.SelectionStart

Write-Host “Date selected: ( ( (date.ToShortDateString())”
}

6-3-2-2. 另请参阅

6-3-3. 多选列表框

使用 Windows PowerShell 3.0 和更高版本在自定义 Windows 窗体中创建多选列表框控件。

6-3-3-1. 创建允许进行多选的列表框控件

复制以下内容并将其粘贴到 Windows PowerShell ISE 中,然后将其另存为 Windows PowerShell 脚本 (.ps1)。

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Data Entry Form'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please make a selection from the list below:'
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.Listbox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.SelectionMode = 'MultiExtended'
[void] $listBox.Items.Add('Item 1')
[void] $listBox.Items.Add('Item 2')
[void] $listBox.Items.Add('Item 3')
[void] $listBox.Items.Add('Item 4')
[void] $listBox.Items.Add('Item 5')
$listBox.Height = 70
$form.Controls.Add($listBox)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{

$x = $listBox.SelectedItems

$x
}

该脚本首先加载两个 .NET Framework 类:System.Drawing 和 System.Windows.Forms 。 然后,启动 .NET Framework 类 System.Windows.Forms.Form 的新实例;它提供一个可以开始添加控件的空白窗体或窗口。
$form = New-Object System.Windows.Forms.Form

在创建 Form 类的实例后,为此类的三个属性赋值。

  1. 文本。 这将成为该窗口的标题。

  2. 大小。 这是窗体的大小(以像素为单位)。 上述脚本创建的窗体大小为宽 300 像素、高 200 像素。

  3. StartingPosition。 在上述脚本中,此可选属性将设置为 CenterScreen。 如果未添加此属性,Windows 将在窗体打开时选择一个位置。 通过将 StartingPosition 设置为 CenterScreen,可使窗体在每次加载时都自动显示在屏幕中间。
    $form.Text = ‘Data Entry Form’
    $form.Size = New-Object System.Drawing.Size(300,200)
    $form.StartPosition = ‘CenterScreen’

接下来,为窗体创建“确定”按钮。 指定“确定”按钮的大小和行为。 在此示例中,按钮位置为距窗体上边缘 120 像素,距左边缘 75 像素。 按钮高度为 23 像素,按钮长度为 75 像素。 此脚本使用预定义的 Windows 窗体类型确定按钮行为。

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)

采用相同方式创建“取消”按钮。 “取消”按钮距窗口上边缘 120 像素,但距左边缘 150 像素。

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)

接下来,在窗口上提供标签文本,用于描述你希望用户提供的信息。

$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please make a selection from the list below:'
$form.Controls.Add($label)

添加控件(在本例中为列表框),从而让用户提供你在标签文本中描述的信息。 除了文本框,你还可以应用许多其他控件;有关更多控件,请参阅 MSDN 上的 System.Windows.Forms 命名空间。

$listBox = New-Object System.Windows.Forms.Listbox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)

下面介绍如何指定你希望允许用户从列表中选择多个值。
$listBox.SelectionMode = ‘MultiExtended’

在下一部分中,你可以指定希望列表框向用户显示的值。

[void] $listBox.Items.Add('Item 1')
[void] $listBox.Items.Add('Item 2')
[void] $listBox.Items.Add('Item 3')
[void] $listBox.Items.Add('Item 4')
[void] $listBox.Items.Add('Item 5')

指定列表框控件的最大高度。
$listBox.Height = 70

将列表框控件添加到窗体中,并指示 Windows 在打开该窗体时,在其他窗口和对话框之上打开它。

$form.Controls.Add($listBox)
$form.Topmost = $true

添加以下代码行以在 Windows 中显示该窗体。
$result = $form.ShowDialog()

最后,If 块内的代码指示在用户从列表框中选择一个或多个选项,然后单击“确定” 按钮或按“Enter” 键后,Windows 应如何处理该窗体。
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{

$x = $listBox.SelectedItems

$x
}

6-3-3-2. 另请参阅

6-3-4. 从列表框中选择项

使用 Windows PowerShell 3.0 和更高版本创建一个对话框,从而允许用户从列表框控件中选择项。

6-3-4-1. 创建一个列表框控件,并从中选择项

复制以下内容并将其粘贴到 Windows PowerShell ISE 中,然后将其另存为 Windows PowerShell 脚本 (.ps1)。


Add-Type -AssemblyName System.Windows.Forms

Add-Type -AssemblyName System.Drawing

$form = New-Object System.Windows.Forms.Form

$form.Text = 'Select a Computer'

$form.Size = New-Object System.Drawing.Size(300,200)

$form.StartPosition = 'CenterScreen'

$okButton = New-Object System.Windows.Forms.Button

$okButton.Location = New-Object System.Drawing.Point(75,120)

$okButton.Size = New-Object System.Drawing.Size(75,23)

$okButton.Text = 'OK'

$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

$form.AcceptButton = $okButton

$form.Controls.Add($okButton)

$cancelButton = New-Object System.Windows.Forms.Button

$cancelButton.Location = New-Object System.Drawing.Point(150,120)

$cancelButton.Size = New-Object System.Drawing.Size(75,23)

$cancelButton.Text = 'Cancel'

$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

$form.CancelButton = $cancelButton

$form.Controls.Add($cancelButton)

$label = New-Object System.Windows.Forms.Label

$label.Location = New-Object System.Drawing.Point(10,20)

$label.Size = New-Object System.Drawing.Size(280,20)

$label.Text = 'Please select a computer:'

$form.Controls.Add($label)

$listBox = New-Object System.Windows.Forms.ListBox

$listBox.Location = New-Object System.Drawing.Point(10,40)

$listBox.Size = New-Object System.Drawing.Size(260,20)

$listBox.Height = 80

[void] $listBox.Items.Add('atl-dc-001')

[void] $listBox.Items.Add('atl-dc-002')

[void] $listBox.Items.Add('atl-dc-003')

[void] $listBox.Items.Add('atl-dc-004')

[void] $listBox.Items.Add('atl-dc-005')

[void] $listBox.Items.Add('atl-dc-006')

[void] $listBox.Items.Add('atl-dc-007')

$form.Controls.Add($listBox)

$form.Topmost = $true

$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK)

{

$x = $listBox.SelectedItem

$x

}

该脚本首先加载两个 .NET Framework 类:System.Drawing 和 System.Windows.Forms 。 然后,启动 .NET Framework 类 System.Windows.Forms.Form 的新实例;它提供一个可以开始添加控件的空白窗体或窗口。
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

在创建 Form 类的实例后,为此类的三个属性赋值。

  1. 文本。 这将成为该窗口的标题。

  2. 大小。 这是窗体的大小(以像素为单位)。 上述脚本创建的窗体大小为宽 300 像素、高 200 像素。

  3. StartingPosition。 在上述脚本中,此可选属性将设置为 CenterScreen。 如果未添加此属性,Windows 将在窗体打开时选择一个位置。 通过将 StartingPosition 设置为 CenterScreen,可使窗体在每次加载时都自动显示在屏幕中间。


$form.Text = 'Select a Computer'

$form.Size = New-Object System.Drawing.Size(300,200)

$form.StartPosition = 'CenterScreen'

接下来,为窗体创建“确定”按钮。 指定“确定”按钮的大小和行为。 在此示例中,按钮位置为距窗体上边缘 120 像素,距左边缘 75 像素。 按钮高度为 23 像素,按钮长度为 75 像素。 此脚本使用预定义的 Windows 窗体类型确定按钮行为。


$okButton = New-Object System.Windows.Forms.Button

$okButton.Location = New-Object System.Drawing.Point(75,120)

$okButton.Size = New-Object System.Drawing.Size(75,23)

$okButton.Text = 'OK'

$okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK

$form.AcceptButton = $okButton

$form.Controls.Add($okButton)

采用相同方式创建“取消”按钮。 “取消”按钮距窗口上边缘 120 像素,但距左边缘 150 像素。


$cancelButton = New-Object System.Windows.Forms.Button

$cancelButton.Location = New-Object System.Drawing.Point(150,120)

$cancelButton.Size = New-Object System.Drawing.Size(75,23)

$cancelButton.Text = 'Cancel'

$cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel

$form.CancelButton = $cancelButton

$form.Controls.Add($cancelButton)

接下来,在窗口上提供标签文本,用于描述你希望用户提供的信息。 在本例中,你希望用户选择一台计算机。


$label = New-Object System.Windows.Forms.Label

$label.Location = New-Object System.Drawing.Point(10,20)

$label.Size = New-Object System.Drawing.Size(280,20)

$label.Text = 'Please select a computer:'

$form.Controls.Add($label)

添加控件(在本例中为列表框),从而让用户提供你在标签文本中描述的信息。 除了文本框,你还可以应用许多其他控件;有关更多控件,请参阅 MSDN 上的 System.Windows.Forms 命名空间


$listBox = New-Object System.Windows.Forms.ListBox

$listBox.Location = New-Object System.Drawing.Point(10,40)

$listBox.Size = New-Object System.Drawing.Size(260,20)

$listBox.Height = 80

在下一部分中,你可以指定希望列表框向用户显示的值。

备注:此脚本创建的列表框只允许进行单选。 若要创建允许进行多选的列表框控件,请指定 SelectionMode 属性的值,类似于以下内容:$listBox.SelectionMode = 'MultiExtended'。 有关详细信息,请参阅多选列表框


[void] $listBox.Items.Add('atl-dc-001')

[void] $listBox.Items.Add('atl-dc-002')

[void] $listBox.Items.Add('atl-dc-003')

[void] $listBox.Items.Add('atl-dc-004')

[void] $listBox.Items.Add('atl-dc-005')

[void] $listBox.Items.Add('atl-dc-006')

[void] $listBox.Items.Add('atl-dc-007')

将列表框控件添加到窗体中,并指示 Windows 在打开该窗体时,在其他窗口和对话框之上打开它。


$form.Controls.Add($listBox)

$form.Topmost = $true

添加以下代码行以在 Windows 中显示该窗体。
$result = $form.ShowDialog()

最后,If 块内的代码指示在用户从列表框中选择某个选项,然后单击“确定” 按钮或按“Enter” 键后,Windows 应如何处理该窗体。


if ($result -eq [System.Windows.Forms.DialogResult]::OK)

{

    $x = $listBox.SelectedItem

    $x

}

6-3-4-2. 另请参阅

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页