PowerShell 高级使用指南
1. Exit 语句
Exit 语句用于从当前的 PowerShell 命令或实例返回一个错误代码。如果在脚本的任何位置(内联、函数内或脚本块中)调用该语句,它将退出脚本;如果在脚本外部(例如函数外部)调用,则会退出 PowerShell。Exit 语句会将
$LastExitCode
自动变量设置为指定的错误级别(errorLevel)。如果 errorLevel 不为零,则会将
$?
自动变量设置为
$false
。
示例代码:
exit errorlevel
若要了解更多关于自动变量的信息,可以使用以下命令:
Get-Help about_automatic_variables
2. 帮助文档
PowerShell 会根据命令中带有特殊标记的注释自动生成帮助内容。以下是一个示例:
<#
.SYNOPSIS
Runs a ...
.EXAMPLE
PS > ...
#>
param(
## Help content for the Param1 parameter
$Param1
)
帮助特定的注释必须是注释块中唯一的注释。如果 PowerShell 发现非帮助注释,它将停止在该注释块中查找注释。如果需要在注释块中包含非帮助注释,应将它们放在单独的注释块中。以下是注释块中最常用的帮助注释:
-
.SYNOPSIS
:命令的简短摘要,理想情况下为一句话。
-
.DESCRIPTION
:命令的详细描述。
-
.PARAMETER name
:参数的描述,每个要描述的参数都应有一个。也可以直接在参数上方编写注释,这样更便于阅读和维护。
-
.EXAMPLE
:命令的使用示例,每个示例都应有一个。PowerShell 将
.EXAMPLE
标签下方的行视为示例命令,如果该行没有类似提示符的文本,PowerShell 会在其前面添加提示符。后续行将被视为额外的输出和示例注释。
-
.INPUTS
:命令支持的管道输入的简短摘要。对于每种输入类型,PowerShell 的内置帮助遵循特定的约定。
-
.OUTPUTS
:命令生成的项目的简短摘要。对于每种输出类型,PowerShell 的内置帮助也遵循特定的约定。
-
.NOTES
:关于该命令的任何额外注释或备注。
-
.LINK
:相关帮助主题或命令的链接,每个链接使用一个
.LINK
标签。如果相关帮助主题是一个 URL,当用户为命令的
Get-Help
提供
-Online
参数时,PowerShell 将打开该 URL。
3. 错误管理
PowerShell 支持两种类型的错误:非终止错误和终止错误。这两种类型的错误都会作为列表收集在
$error
自动变量中。
3.1 非终止错误
大多数错误是非终止错误,它们不会停止当前 cmdlet、脚本、函数或管道的执行。当命令通过 PowerShell 的错误输出功能输出错误时,PowerShell 会将该错误写入一个名为错误输出流的流中。可以使用
Write-Error
cmdlet(或在编写 cmdlet 时使用
WriteError()
API)输出非终止错误。
$ErrorActionPreference
自动变量可用于控制 PowerShell 处理非终止错误的方式,它支持以下值:
| 值 | 含义 |
| — | — |
| Ignore | 不显示错误,也不将其添加到
$error
集合中。仅在作为命令的
ErrorAction
参数值时支持。 |
| SilentlyContinue | 不显示错误,但将其添加到
$error
集合中。 |
| Stop | 将非终止错误视为终止错误。 |
| Continue | 显示错误,但继续执行当前 cmdlet、脚本、函数或管道。这是默认值。 |
| Inquire | 显示一个提示,询问 PowerShell 应如何处理此错误。 |
大多数 cmdlet 允许通过将这些值之一传递给
ErrorAction
参数来明确配置此行为。
3.2 终止错误
终止错误会停止当前 cmdlet、脚本、函数或管道的执行。如果命令(如 cmdlet 或 .NET 方法调用)生成结构化异常(例如,为方法提供超出其有效范围的参数),PowerShell 会将其作为终止错误处理。如果 PowerShell 无法解析脚本、函数或管道中的某个元素,也会生成终止错误。
可以在脚本中使用
throw
关键字生成终止错误:
throw message
在自己的脚本和 cmdlet 中,仅当操作的基本意图无法实现时才应生成终止错误。例如,在远程服务器上执行命令失败应视为非终止错误,而完全无法连接到远程服务器则应视为终止错误。
可以使用
try
、
catch
和
finally
语句来捕获终止错误,这与许多其他编程语言类似:
try
{
statement block
}
catch [exception type]
{
error handling block
}
catch [alternate exception type]
{
alternate error handling block
}
finally
{
cleanup block
}
在
try
语句之后,必须提供
catch
语句、
finally
语句或两者都提供。如果指定异常类型(可选),可以指定多个
catch
语句来处理不同类型的异常。如果指定了异常类型,
catch
块仅适用于该类型的终止错误。
PowerShell 还允许在遇到错误之前定义
trap
语句来捕获终止错误:
trap [exception type]
{
statement block
[continue or break]
}
如果指定了异常类型,
trap
语句仅适用于该类型的终止错误。在
catch
块或
trap
语句中,
$_
(或
$PSItem
)变量表示当前正在处理的异常或错误。
如果指定了
continue
关键字,PowerShell 将在遇到终止错误的位置之后继续处理脚本、函数或管道。如果指定了
break
关键字,PowerShell 将停止处理脚本、函数或管道的其余部分。默认模式是
break
,如果既不指定
break
也不指定
continue
,则使用该模式。
4. 输出格式化
当对象到达输出管道的末尾时,PowerShell 会将它们转换为文本,以便人类阅读。PowerShell 支持多种选项来控制此格式化过程,如下表所示:
| 格式化命令 | 结果 |
| — | — |
|
Format-Table Properties
| 将输入对象的属性格式化为表格,仅包含指定的对象属性。如果未指定属性列表,PowerShell 会选择一组默认属性。除了提供对象属性,还可以提供高级格式化语句。例如:
powershell<br>PS > Get-Process | `<br> Format-Table -Auto Name,`<br> @{Label="HexId";`<br> Expression={ "{0:x}" -f $_.Id}`<br> Width=4`<br> Align="Right"`<br> }<br>
高级格式化语句是一个哈希表,包含
Label
和
Expression
(或它们的缩写形式)键。
Expression
键的值应该是一个脚本块,它为当前对象(由
$_
变量表示)返回一个结果。若要了解更多关于
Format-Table
cmdlet 的信息,可以使用
Get-Help Format-Table
命令。 |
|
Format-List Properties
| 将输入对象的属性格式化为列表,仅包含指定的对象属性。如果未指定属性列表,PowerShell 会选择一组默认属性。
Format-List
cmdlet 支持与
Format-Table
cmdlet 相同的高级格式化语句。该 cmdlet 常用于获取对象属性的详细摘要。
Format-List *
命令返回所有属性,但不包括 PowerShell 默认隐藏的属性。
Format-List * -Force
命令返回所有属性。若要了解更多关于
Format-List
cmdlet 的信息,可以使用
Get-Help Format-List
命令。 |
|
Format-Wide Property
| 将输入对象的属性格式化为极其简洁的摘要视图。如果未指定属性,PowerShell 会选择一个默认属性。除了提供对象属性,还可以提供高级格式化语句。例如:
powershell<br>PS > Get-Process | `<br> Format-Wide -Auto `<br> @{ Expression={ "{0:x}" -f $_.Id} }<br>
高级格式化语句是一个哈希表,包含
Expression
(或其缩写形式)键。
Expression
键的值应该是一个脚本块,它为当前对象(由
$_
变量表示)返回一个结果。若要了解更多关于
Format-Wide
cmdlet 的信息,可以使用
Get-Help Format-Wide
命令。 |
4.1 自定义格式化文件
PowerShell 中的所有格式化默认值(例如,未指定格式化命令或未指定格式化属性时)由安装目录中的
*.Format.Ps1Xml
文件驱动,这与在某些操作中提到的类型扩展文件类似。
若要创建自己的格式化自定义项,可以使用这些文件作为示例,但不要直接修改它们。而是创建一个新文件,并使用
Update-FormatData
cmdlet 加载自定义项。
Update-FormatData
cmdlet 会将更改应用到当前的 PowerShell 实例。如果希望每次启动 PowerShell 时都加载这些更改,可以在配置文件脚本中调用
Update-FormatData
。以下命令从与配置文件相同的目录加载
Format.custom.ps1xml
:
$formatFile = Join-Path (Split-Path $profile) "Format.Custom.Ps1Xml"
Update-FormatData -PrependPath $typesFile
若要在不使用格式文件的情况下添加格式化信息,可以参考相关操作说明。
5. 捕获输出
在 PowerShell 中,有多种方法可以捕获命令的输出,如下表所示:
| 命令 | 结果 |
| — | — |
|
$variable = Command
| 将 PowerShell 命令生成的对象存储到
$variable
中。 |
|
$variable = Command | Out-String
| 将 PowerShell 命令的可视化表示存储到
$variable
中,即命令转换为人类可读输出后的结果。 |
|
$variable = NativeCommand
| 将原生命令的(字符串)输出存储到
$variable
中。PowerShell 将其存储为字符串列表,每行输出对应一个字符串。 |
|
Command -OutVariable variable
| 对于大多数命令,将 PowerShell 命令生成的对象存储到
$variable
中。
-OutVariable
参数也可以写成
-Ov
。 |
|
Command > File
| 将 PowerShell 的可视化表示(或原生命令的标准输出)重定向到文件中,如果文件存在则覆盖该文件。此重定向不会捕获错误。 |
|
Command >> File
| 将 PowerShell 的可视化表示(或原生命令的标准输出)追加到文件中,如果文件存在则在文件末尾添加内容。此重定向不会捕获错误。 |
|
Command 2> File
| 将 PowerShell 或原生命令的错误重定向到文件中,如果文件存在则覆盖该文件。 |
|
Command n> File
| 将流编号为 n 的内容重定向到文件中,如果文件存在则覆盖该文件。支持的流编号包括 2(错误)、3(警告)、4(详细信息)、5(调试信息)和
*
(所有流)。 |
|
Command 2>> File
| 将 PowerShell 或原生命令的错误追加到文件中,如果文件存在则在文件末尾添加内容。 |
|
Command n>> File
| 将流编号为 n 的内容追加到文件中,如果文件存在则在文件末尾添加内容。支持的流编号包括 2(错误)、3(警告)、4(详细信息)、5(调试信息)和
*
(所有流)。 |
|
Command > File 2>&1
| 将 PowerShell 或原生命令的错误和标准输出流都重定向到文件中,如果文件存在则覆盖该文件。 |
|
Command >> File 2>&1
| 将 PowerShell 或原生命令的错误和标准输出流都追加到文件中,如果文件存在则在文件末尾添加内容。 |
6. 常见自定义点
尽管 PowerShell 开箱即用就很有用,但它还提供了多种自定义和个性化的途径。
6.1 控制台设置
Windows PowerShell 用户界面提供了一些功能,可让你的 shell 体验更加高效。
-
调整窗口大小
:在系统菜单(右键单击控制台窗口左上角的标题栏)中,选择“属性”→“布局”。“窗口大小”选项可控制实际窗口的大小(即窗口在屏幕上的显示大小),“屏幕缓冲区大小”选项可控制虚拟窗口的大小(即窗口可以容纳的内容量)。如果屏幕缓冲区大小大于实际窗口大小,控制台窗口将显示滚动条。增加虚拟窗口的高度可以让 PowerShell 存储更多会话早期的输出。如果从开始菜单启动 PowerShell,它会以一些默认的窗口大小设置启动。
-
更轻松地选择文本
:在系统菜单中,单击“选项”→“快速编辑模式”。快速编辑模式允许你使用鼠标高效地在 PowerShell 控制台中复制和粘贴文本。默认情况下,PowerShell 以快速编辑模式启动。
-
使用热键更高效地操作 shell
:Windows PowerShell 控制台支持许多热键,可提高操作效率,如下表所示:
| 热键 | 含义 |
| — | — |
| Windows 键 - r,然后输入 powershell | 启动 Windows PowerShell。 |
| 向上箭头 | 向后浏览命令历史记录。 |
| 向下箭头 | 向前浏览命令历史记录。 |
| Page Up | 显示命令历史记录中的第一条命令。 |
| Page Down | 显示命令历史记录中的最后一条命令。 |
| 向左箭头 | 在命令行上将光标向左移动一个字符。 |
| 向右箭头 | 在命令行上将光标向右移动一个字符。如果光标位于行尾,则插入上一条命令文本中的一个字符。 |
| Home | 将光标移动到命令行的开头。 |
| End | 将光标移动到命令行的末尾。 |
| Ctrl - 向左箭头 | 在命令行上将光标向左移动一个单词。 |
| Ctrl - 向右箭头 | 在命令行上将光标向右移动一个单词。 |
| Alt - 空格,e,l | 滚动屏幕缓冲区。 |
| Alt - 空格,e,f | 在屏幕缓冲区中搜索文本。 |
| Alt - 空格,e,k | 选择要从屏幕缓冲区复制的文本。 |
| Alt - 空格,e,p | 将剪贴板内容粘贴到 Windows PowerShell 控制台中。 |
| Alt - 空格,c | 关闭 Windows PowerShell 控制台。 |
| Ctrl - c | 取消当前操作。 |
| Ctrl - break | 强制关闭 Windows PowerShell 窗口。 |
| Ctrl - Home | 删除当前命令行开头到(但不包括)当前光标位置的字符。 |
| Ctrl - End | 删除从当前光标位置(包括)到命令行末尾的字符。 |
| F1 | 在命令行上将光标向右移动一个字符。如果光标位于行尾,则插入上一条命令文本中的一个字符。 |
| F2 | 通过复制上一条命令行直到输入的字符来创建新的命令行。 |
| F3 | 从当前光标位置到命令行末尾,用上次命令行的内容完成当前命令行。 |
| F4 | 删除从光标位置到(但不包括)输入的字符之间的字符。 |
| F5 | 向后浏览命令历史记录。 |
| F7 | 交互式地从命令历史记录中选择命令。使用箭头键在出现的窗口中滚动。按 Enter 键执行命令,或使用向右箭头键将文本放置在命令行上。 |
| F8 | 向后浏览命令历史记录,仅显示与当前命令行中已输入文本匹配的命令。 |
| F9 | 调用命令历史记录中指定编号的命令。这些命令的编号与命令历史记录选择窗口(F7)中显示的编号相对应。 |
| Alt - F7 | 清除命令历史记录列表。 |
虽然这些热键本身就很有用,但使用像免费的 AutoHotkey 这样的热键程序将它们映射到更短或更直观的按键上会更加方便。
6.2 配置文件
Windows PowerShell 在启动时会自动运行以下四个脚本(如果存在),每个脚本都可以让你自定义执行环境。PowerShell 会像你在命令行手动输入一样运行这些文件中的任何内容。
| 配置文件用途 | 配置文件位置 |
| — | — |
| 所有 PowerShell 会话的自定义,包括系统上所有用户的 PowerShell 宿主应用程序 |
InstallationDirectory\profile.ps1
|
| 系统上所有用户的 PowerShell.exe 会话的自定义 |
InstallationDirectory\Microsoft.PowerShell_profile.ps1
|
| 所有 PowerShell 会话的自定义,包括 PowerShell 宿主应用程序 |
<My Documents>\WindowsPowerShell\profile.ps1
|
| PowerShell.exe 会话的典型自定义 |
<My Documents>\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
|
PowerShell 通过定义自动变量
$profile
来简化配置文件脚本的编辑。单独使用
$profile
时,它指向“当前用户,PowerShell.exe”配置文件。此外,
$profile
变量还定义了其他属性,指向其他配置文件位置。例如:
PS > $profile | Format-List -Force
AllUsersAllHosts : C:\Windows\System32\WindowsPowerShell\v1.0\
profile.ps1
AllUsersCurrentHost : C:\Windows\System32\WindowsPowerShell\v1.0\
Microsoft.PowerShell_profile.ps1
CurrentUserAllHosts : E:\Lee\WindowsPowerShell\profile.ps1
CurrentUserCurrentHost : E:\Lee\WindowsPowerShell\Microsoft.PowerShell_
profile.ps1
若要创建新的配置文件,可以使用以下命令:
New-Item -Type file -Force $profile
若要编辑该配置文件,可以使用以下命令:
notepad $profile
6.3 提示符自定义
要自定义提示符,可以在配置文件中添加一个
prompt
函数。该函数应返回一个字符串。例如:
function Prompt
{
"PS [$env:COMPUTERNAME] >"
}
若要了解更多关于自定义提示符的信息,可以参考相关操作说明。
6.4 制表符补全自定义
可以定义一个
TabExpansion2
函数来自定义 Windows PowerShell 在按下 Tab 键时完成属性、变量、参数和文件的方式。自定义的
TabExpansion
函数会覆盖 PowerShell 默认定义的函数,因此可以将其定义作为起点:
Get-Content function:\TabExpansion2
若要了解更多关于自定义制表符补全的信息,可以参考相关操作说明。
6.5 用户输入自定义
可以定义一个
PSConsoleHostReadLine
函数来自定义 Windows PowerShell 控制台主机(非 ISE)读取用户输入的方式。该函数负责处理用户的所有按键操作,并最终返回 PowerShell 应执行的命令。若要了解更多关于覆盖用户输入的信息,可以参考相关操作说明。
6.6 命令解析自定义
可以通过将脚本块分配给
$executionContext.SessionState.InvokeCommand
的
PreCommandLookupAction
、
PostCommandLookupAction
或
CommandNotFoundAction
属性之一或全部,在三个位置拦截 PowerShell 的命令解析行为。
PowerShell 在用户输入命令名称后但尝试解析命令之前调用
PreCommandLookupAction
。在解析命令后但执行命令之前调用
PostCommandLookupAction
。在未找到命令但生成错误消息之前调用
CommandNotFoundAction
。每个脚本块都会接收两个参数:
CommandName
和
CommandLookupEventArgs
。
示例代码:
$executionContext.SessionState.InvokeCommand.CommandNotFoundAction = {
param($CommandName, $CommandLookupEventArgs)
(...)
}
如果脚本块将脚本块分配给
CommandLookupEventArgs
的
CommandScriptBlock
属性,或者将
CommandInfo
分配给
CommandLookupEventArgs
的
Command
属性,PowerShell 将分别使用该脚本块或命令。如果脚本块将
StopSearch
属性设置为
true
,PowerShell 将不再进行进一步的命令解析。若要了解更多关于覆盖用户输入的信息,可以参考相关操作说明。
7. 总结与流程图示例
为了更清晰地展示 PowerShell 中错误处理和输出操作的流程,下面给出 mermaid 格式的流程图。
7.1 错误处理流程
graph TD;
A[命令执行] --> B{是否产生错误};
B -- 是 --> C{错误类型};
C -- 非终止错误 --> D[写入错误输出流];
D --> E{ErrorActionPreference 值};
E -- Ignore --> F[不显示且不添加到 $error 集合];
E -- SilentlyContinue --> G[不显示但添加到 $error 集合];
E -- Stop --> H[视为终止错误];
E -- Continue --> I[显示错误并继续执行];
E -- Inquire --> J[显示提示询问处理方式];
C -- 终止错误 --> K[停止当前操作];
K --> L{是否有 try-catch 或 trap 语句};
L -- 是 --> M[执行相应处理块];
L -- 否 --> N[抛出错误];
B -- 否 --> O[正常执行];
7.2 输出捕获流程
graph TD;
A[执行命令] --> B{输出捕获方式};
B -- $variable = Command --> C[存储对象到 $variable];
B -- $variable = Command | Out-String --> D[存储可视化表示到 $variable];
B -- $variable = NativeCommand --> E[存储原生命令字符串输出到 $variable];
B -- Command -OutVariable variable --> F[存储对象到 variable];
B -- Command > File --> G[重定向到文件(覆盖)];
B -- Command >> File --> H[重定向到文件(追加)];
B -- Command 2> File --> I[重定向错误到文件(覆盖)];
B -- Command n> File --> J[重定向指定流到文件(覆盖)];
B -- Command 2>> File --> K[重定向错误到文件(追加)];
B -- Command n>> File --> L[重定向指定流到文件(追加)];
B -- Command > File 2>&1 --> M[重定向错误和标准输出到文件(覆盖)];
B -- Command >> File 2>&1 --> N[重定向错误和标准输出到文件(追加)];
8. 综合应用示例
以下是一个综合运用上述知识的示例脚本,该脚本将展示如何在 PowerShell 中进行错误处理、输出格式化和捕获输出。
# 定义一个函数,可能会产生错误
function Test-Function {
param (
[int]$Number
)
if ($Number -lt 0) {
throw "输入的数字不能为负数。"
}
return $Number * 2
}
try {
# 调用函数并捕获输出
$result = Test-Function -Number 5
# 格式化输出
$result | Format-Table | Out-String | Write-Host
# 尝试产生错误
$errorResult = Test-Function -Number -1
}
catch {
# 处理终止错误
Write-Error "发生错误: $_"
# 将错误信息存储到变量
$errorVariable = $_
}
finally {
# 清理操作
Write-Host "脚本执行结束。"
}
# 捕获命令输出到变量
$processes = Get-Process | Format-List Name, Id
# 将输出保存到文件
$processes | Out-File -FilePath "processes.txt"
9. 注意事项
在使用 PowerShell 进行高级操作时,需要注意以下几点:
-
错误处理
:合理区分非终止错误和终止错误,根据实际情况选择合适的处理方式。在自定义脚本中,谨慎使用
throw
关键字,确保只有在必要时才抛出终止错误。
-
输出格式化
:根据不同的需求选择合适的格式化命令,如
Format-Table
、
Format-List
和
Format-Wide
。在使用高级格式化语句时,确保脚本块的正确性。
-
捕获输出
:注意不同的输出捕获方式适用于不同的场景,如存储对象、可视化表示或原生命令输出。在重定向输出到文件时,要考虑文件的覆盖和追加情况。
-
自定义设置
:在进行控制台设置、配置文件修改、提示符自定义等操作时,要备份相关文件,避免因误操作导致 PowerShell 无法正常使用。
通过以上对 PowerShell 高级使用的介绍,你可以更深入地掌握 PowerShell 的各种功能,提高工作效率和脚本编写能力。不断实践和探索,你将能够根据具体需求灵活运用这些知识,实现更复杂的自动化任务。
PowerShell高级技巧详解
超级会员免费看

被折叠的 条评论
为什么被折叠?



