64、PowerShell 高级使用指南

PowerShell高级技巧详解

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 的各种功能,提高工作效率和脚本编写能力。不断实践和探索,你将能够根据具体需求灵活运用这些知识,实现更复杂的自动化任务。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值