Windows PowerShell 5.1 与 PowerShell 7.x 之间的差异

Windows PowerShell 5.1 是在 .NET Framework v4.5 基础上构建的。 随着 PowerShell 6.0 的发布,PowerShell 成为基于 .NET Core 2.0 构建的开源项目。 从 .NET Framework 转换到 .Net Core 使 PowerShell 成为可跨平台的解决方案。 PowerShell 在 Windows、macOS 和 Linux 上运行。

Windows PowerShell 和 PowerShell 的 PowerShell 语言有一些不同。 最明显的差异在于 Windows 和非 Windows 平台上 PowerShell cmdlet 的可用性和行为以及因 .NET Framework 和 .NET Core 之间的差异所引起的变化。

本文总结了 Windows PowerShell 和当前版本的 PowerShell 之间的显著差异和重大更改。 本总结不涵盖添加的新功能或 cmdlet。 本文也不讨论版本之间的不同之处。 本文的目的是介绍 PowerShell 的当前状态以及与 Windows PowerShell 的不同之处。 有关各版本之间的差异和新增功能的详细讨论,请参阅每个版本的“新增功能”一文。

.NET Framework 和 .NET Core

Linux 和 macOS 上的 PowerShell 使用 .NET Core,即 Microsoft Windows 上的完整 .NET Framework 的子集。 这非常重要,因为 PowerShell 提供对基础框架类型和方法的直接访问。 因此,在 Windows 上运行的脚本可能无法在非 Windows 平台上运行,因为框架之间存在差异。 有关 .NET Core 中的更改的详细信息,请参阅有关从 .NET Framework 迁移到 .NET Core 的重大更改

PowerShell 的每个新版本都是在较新版本的 .NET 基础上构建的。 .NET 中可能存在影响 PowerShell 的中断性变更。

  • PowerShell 7.5 - 基于 .NET 9.0 构建
  • PowerShell 7.4 - 基于 .NET 8.0 构建
  • PowerShell 7.3 - 基于 .NET 7.0 构建
  • PowerShell 7.2 (LTS-current) - 基于 .NET 6.0 (LTS-current) 构建
  • PowerShell 7.1 - 基于 .NET 5.0 构建
  • PowerShell 7.0 (LTS) - 基于 .NET Core 3.1 (LTS) 构建
  • PowerShell 6.2 - 基于 .NET Core 2.1 构建
  • PowerShell 6.1 - 基于 .NET Core 2.1 构建
  • PowerShell 6.0 - 基于 .NET Core 2.0 构建

随着 .NET Standard 2.0 的出现,PowerShell 能够加载许多传统 Windows PowerShell 模块,而无需修改。 此外,PowerShell 7 还包含 Windows PowerShell 兼容性功能,通过这些功能可使用仍需要完善框架的 Windows PowerShell 模块。

有关详细信息,请参阅:

请注意 .NET 方法更改

虽然 .NET 方法更改并不特定于 PowerShell,但它们可能会影响脚本,尤其是在直接调用 .NET 方法时。 此外,构造函数可能会有新的重载。 这可能会影响如何使用 New-Object[type]::new() 方法创建对象。

例如,.NET 向 .NET Framework 4.5 中不可用的 [System.String]::Split() 方法添加了重载。 以下列表显示了 Windows PowerShell 5.1 中可用的 Split() 方法的重载:

PS> "".Split

OverloadDefinitions
-------------------
string[] Split(Params char[] separator)
string[] Split(char[] separator, int count)
string[] Split(char[] separator, System.StringSplitOptions options)
string[] Split(char[] separator, int count, System.StringSplitOptions options)
string[] Split(string[] separator, System.StringSplitOptions options)
string[] Split(string[] separator, int count, System.StringSplitOptions options)

以下列表显示了 PowerShell 7 中可用的 Split() 方法的重载:

"".Split

OverloadDefinitions
-------------------
string[] Split(char separator, System.StringSplitOptions options)
string[] Split(char separator, int count, System.StringSplitOptions options)
string[] Split(Params char[] separator)
string[] Split(char[] separator, int count)
string[] Split(char[] separator, System.StringSplitOptions options)
string[] Split(char[] separator, int count, System.StringSplitOptions options)
string[] Split(string separator, System.StringSplitOptions options)
string[] Split(string separator, int count, System.StringSplitOptions options)
string[] Split(string[] separator, System.StringSplitOptions options)
string[] Split(string[] separator, int count, System.StringSplitOptions options)

在 Windows PowerShell 5.1 中,可以将字符数组 (char[]) 作为 string 传递给 Split() 方法。 该方法会在数组中出现任何字符时拆分目标字符串。 以下命令会拆分 Windows PowerShell 5.1 中的目标字符串,但在 PowerShell 7 中则不会:

# PowerShell 7 example
"1111p2222q3333".Split('pq')
1111p2222q3333

若要绑定到正确的重载,则必须将字符串类型转换为字符数组:

# PowerShell 7 example
"1111p2222q3333".Split([char[]]'pq')
1111
2222
3333

PowerShell 不再附带模块

由于各种兼容性原因,PowerShell 中不再包括以下模块。

  • ISE
  • Microsoft.PowerShell.LocalAccounts
  • Microsoft.PowerShell.ODataUtils
  • Microsoft.PowerShell.Operation.Validation
  • PSScheduledJob
  • PSWorkflow
  • PSWorkflowUtility

PowerShell 工作流

PowerShell 工作流是基于可为长时间运行或并行化任务创建可靠 runbook 的 Windows Workflow Foundation (WF) 生成的 Windows PowerShell 中的一项功能。

由于缺少对 .NET Core 中的 Windows Workflow Foundation 的支持,我们已从 PowerShell 中删除 PowerShell 工作流。

将来,我们希望使用 PowerShell 语言启用本机并行/并发,而无需使用 PowerShell 工作流。

如果在操作系统重启后需要使用检查点来恢复脚本,建议在操作系统启动时使用任务计划程序运行脚本,但此脚本将需要维持自身的状态(例如将它保存到文件)。

从 PowerShell 中删除的 cmdlet

对于 PowerShell 中包含的模块,出于各种兼容性原因或为了避免使用不支持的 API,从 PowerShell 中删除了以下 cmdlet。

CimCmdlet

  • Export-BinaryMiLog

Microsoft.PowerShell.Core

  • Add-PSSnapin
  • Export-Console
  • Get-PSSnapin
  • Remove-PSSnapin
  • Resume-Job
  • Suspend-Job

Microsoft.PowerShell.Diagnostics

  • Export-Counter
  • Import-Counter

Microsoft.PowerShell.Management

  • Add-Computer
  • Checkpoint-Computer
  • Clear-EventLog
  • Complete-Transaction
  • Disable-ComputerRestore
  • Enable-ComputerRestore
  • Get-ComputerRestorePoint
  • Get-ControlPanelItem
  • Get-EventLog
  • Get-Transaction
  • Get-WmiObject
  • Invoke-WmiMethod
  • Limit-EventLog
  • New-EventLog
  • New-WebServiceProxy
  • Register-WmiEvent
  • Remove-Computer
  • Remove-EventLog
  • Remove-WmiObject
  • Reset-ComputerMachinePassword
  • Restore-Computer
  • Set-WmiInstance
  • Show-ControlPanelItem
  • Show-EventLog
  • Start-Transaction
  • Test-ComputerSecureChannel
  • Undo-Transaction
  • Use-Transaction
  • Write-EventLog

Microsoft.PowerShell.Utility

  • Convert-String
  • ConvertFrom-String

PSDesiredStateConfiguration

  • Disable-DscDebug
  • Enable-DscDebug
  • Get-DscConfiguration
  • Get-DscConfigurationStatus
  • Get-DscLocalConfigurationManager
  • Publish-DscConfiguration
  • Remove-DscConfigurationDocument
  • Restore-DscConfiguration
  • Set-DscLocalConfigurationManager
  • Start-DscConfiguration
  • Stop-DscConfiguration
  • Test-DscConfiguration
  • Update-DscConfiguration

WMI v1 cmdlet

以下 WMI v1 cmdlet 已从 PowerShell 中删除:

  • Register-WmiEvent
  • Set-WmiInstance
  • Invoke-WmiMethod
  • Get-WmiObject
  • Remove-WmiObject

CimCmdlet 模块(也称为 WMI v2)cmdlet 可执行相同的功能,同时提供新的功能和重新设计的语法。

删除了 New-WebServiceProxy cmdlet

.NET Core 不支持为使用 SOAP 协议提供服务的 Windows Communication Framework。 由于此 cmdlet 需要 SOAP 协议,因此已将其删除。

*-Transaction cmdlet 已遭删除

这些 cmdlet 的使用非常有限。 已决定停止提供对它们的支持。

  • Complete-Transaction
  • Get-Transaction
  • Start-Transaction
  • Undo-Transaction
  • Use-Transaction

*-EventLog cmdlet

由于使用了不受支持的 API 而从 PowerShell 中了删除 *-EventLog cmdlet。 Get-WinEventNew-WinEvent 可用于在 Windows 上获取和创建事件。

使用 Windows Presentation Framework (WPF) 的 cmdlet

.NET Core 3.1 添加了对 WPF 的支持,因此 PowerShell 7.0 恢复了以下 Windows 特定功能:

  • Show-Command cmdlet
  • Out-GridView cmdlet
  • Get-Help 的 ShowWindow 参数

PowerShell Desired State Configuration (DSC) 更改

Invoke-DscResource 恢复为 PowerShell 7.0 中的实验性功能。

从 PowerShell 7.2 开始,已从 PowerShell 中删除 PSDesiredStateConfiguration 模块,并已将其发布到 PowerShell 库。 有关详细信息,请参阅 PowerShell 团队博客中的公告

PowerShell 可执行文件更改

已将 powershell.exe 重命名为 pwsh.exe

PowerShell 的二进制名称已从 powershell(.exe) 更改为 pwsh(.exe)。 此更改为用户提供一个决定性方法,从而可在计算机上运行 PowerShell 并支持并行 Windows PowerShell 和 PowerShell 安装。

powershell.exe 重命名为 pwsh(.exe) 后的其他更改:

  • 已将第一个位置参数从 -Command 更改为 -File。 此更改修复了 #!(亦称为 shebang)在非 Windows 平台上非 PowerShell shell 内执行的 PowerShell 脚本 中的使用问题。 这还意味着无需指定 -File 即可运行 pwsh foo.ps1pwsh fooScript 等命令。 但是,尝试运行 pwsh.exe -Command Get-Command 等命令时,此更改会要求显示指定 -c-Command
  • pwsh 接受 -i(或 -Interactive)切换表示交互式 shell。 这使 PowerShell 可用作 Unix 平台上的默认 shell。
  • 已将参数 -ImportSystemModules-PSConsoleFilepwsh.exe 中删除。
  • 已更改 pwsh -versionpwsh.exe 内置帮助,以与其他本机工具保持统一。
  • -File-Command 的无效参数错误消息以及退出代码与 Unix 标准一致
  • 已在 Windows 上添加 -WindowStyle 参数。 同样,非 Windows 平台上基于包的安装更新现为就地更新。

缩短的名称也与非 Windows 平台上 shell 的命名一致。

支持使用 bool 参数运行 PowerShell 脚本

以前,使用 pwsh.exe 执行 PowerShell 脚本,使用 -File 无法将 $true/$false 作为参数值进行传递。 添加了支持将 $true/$false 作为参数的解析值。 还支持 Switch 值。

改进了 Windows PowerShell 的向后兼容性

对于 Windows,新开关参数 UseWindowsPowerShell 将添加到 Import-Module。 此开关会在 PowerShell 7 中创建一个代理模块,该模块使用本地 Windows PowerShell 进程隐式运行该模块中包含的任何 cmdlet。 有关详细信息,请参阅 Import-Module

有关哪些 Microsoft 模块适用于 PowerShell 7.0 的详细信息,请参阅模块兼容性表

针对 Windows 的 Microsoft 更新支持

PowerShell 7.2 添加了对 Microsoft 更新的支持。 启用此功能时,你将在传统 Windows 更新 (WU) 管理流中获得最新的 PowerShell 7 更新,无论是包含适用于企业的 Windows 更新、WSUS、SCCM,还是包含设置中的交互式 WU 对话框。

PowerShell 7.2 MSI 包包含以下命令行选项:

  • USE_MU - 该属性有两个可能值:
    • 1(默认)- 选择通过 Microsoft 更新或 WSUS 进行更新
    • 0 - 不选择通过 Microsoft 更新或 WSUS 进行更新
  • ENABLE_MU
    • 1(默认)- 选择使用 Microsoft 更新、自动更新或 Windows 更新
    • 0 - 不选择使用 Microsoft 更新、自动更新或 Windows 更新

引擎更改

支持将 PowerShell 作为默认 Unix shell

在 Unix 上,对于交互式 shell 而言,shell 通常会接受 -i,许多工具都期待这一行为(例如,script,以及在将 PowerShell 设置为默认 shell 时),并使用 -i 开关来调用 shell。 此更改具有突破性,因为 -i 以前可用作速记以匹配 -inputformat,它现在需要使用 -in

自定义管理单元

PowerShell 管理单元是 PowerShell 社区中未广泛采用的 PowerShell 模块的前身。

鉴于支持管理单元的复杂性及其缺乏在社区中的使用,我们不再支持 PowerShell 中的自定义管理单元。

实验性功能标志

PowerShell 6.2 启用了对实验性功能的支持。 这允许 PowerShell 开发人员提供新功能,并在设计完成之前获得反馈。 通过这种方式,我们可以避免随着设计的改进而进行重大更改。

使用 Get-ExperimentalFeature 获取可用的实验性功能列表。 可以使用 Enable-ExperimentalFeatureDisable-ExperimentalFeature 启用或禁用这些功能。

在尝试从 GAC 加载程序集之前,先从模块基路径加载程序集

以前,当二进制模块在 GAC 中具有模块程序集时,我们会在从模块基路径中加载程序集之前从 GAC 中加载该程序集。

对具有值类型元素类型的集合,跳过 null 元素检查

对于 Mandatory 参数及 ValidateNotNullValidateNotNullOrEmpty 属性,如果集合的元素类型是值类型,则跳过 null 元素检查。

为 ParenExpression、SubExpression 和 ArrayExpression 保留 $?

此 PR 更改了子管道 (...)、子表达式 $(...) 和数组表达式 @() 的编译方式,以便 $? 不会自动为 true。 $? 的值应取决于所执行的管道或语句的结果。

当本机命令写入 stderr 时,将 $? 修复为非 $false

当本机命令写入 stderr 时,$? 不会设置时为 $false。 通常情况下,本机命令会写入 stderr 且不会指示失败。 仅当本机命令包含非零的退出代码时,$? 才会设置为 $false

使 $ErrorActionPreference 不会影响本机命令的 stderr 输出

通常情况下,本机命令会写入 stderr 且不会指示失败。 进行此更改后,仍会在 ErrorRecord 对象中捕获 stderr 输出,但如果 ErrorRecord 来自本机命令,则运行时将不再适用 $ErrorActionPreference

更改 $OutputEncoding 以使用 UTF-8 NoBOM 编码,而不使用 ASCII

以前的编码 ASCII(7 位)在某些情况下会导致输出的错误更改。 将 UTF-8 NoBOM 变为默认值,从而保留具有大多数工具和操作系统支持的编码的 Unicode 输出。

将带有参数 -Encoding 的 cmdlet 统一为 System.Text.Encoding 类型

-EncodingByte 已从文件系统提供程序 cmdlet 中删除。 新参数 -AsByteStream 现可用于指定需要一个字节流作为输入,或用于指定输出是一个字节流。

在非 Windows 平台上将 New-ModuleManifest 编码更改为 UTF8NoBOM

以前,New-ModuleManifest 创建带有 BOM 的 UTF-16 格式的 psd1 清单,这为 Linux 工具带来了一个问题。 这一重大更改将 New-ModuleManifest 的编码更改为非 Windows 平台中的 UTF(无 BOM)。

从大多数默认别名中删除 AllScope

为了加快作用域创建,从大多数默认别名中删除了 AllScope。 保留 AllScope 供查找速度更快的几个常用别名使用。

-Verbose-Debug 不再替代 $ErrorActionPreference

以前,如果已指定 -Verbose-Debug,则它会替代 $ErrorActionPreference 的行为。 进行此更改后,-Verbose-Debug 不再影响 $ErrorActionPreference 的行为。

此外,-Debug 参数将 $DebugPreference 设置为“继续”而不是“查询” 。

使 $PSCulture 一致地反映会话中区域性更改

在 Windows PowerShell 中,将缓存当前区域性值,这样可避免值在会话启动后区域性发生变化时与之同步。 此缓存行为在 PowerShell Core 中是固定的。

允许显式指定的命名参数取代展开的哈希表中的同一个参数

进行此更改后,展开中的命名参数将移到参数列表的末尾,这样在所有显式指定的命名参数被绑定后,它们就会被绑定。 当找不到指定的命名参数时,简单函数的参数绑定不会引发错误。 未知的命名参数绑定到简单函数的 $args 参数。 将展开移动到自变量列表的末尾将更改参数在 $args中的显示顺序。

例如:

function SimpleTest {
    param(
        $Name,
        $Path
    )
    "Name: $Name; Path: $Path; Args: $args"
}

在以前的行为中,MyPath 未绑定到 -Path,因为它是自变量列表中的第三个自变量。 ## 因此它最终和 Blah = "World" 一起填充到“$args”中

PS> $hash = @{ Name = "Hello"; Blah = "World" }
PS> SimpleTest @hash "MyPath"
Name: Hello; Path: ; Args: -Blah: World MyPath

进行此更改后,@hash 中的自变量将移到自变量列表的末尾。 MyPath 成为列表中的第一个自变量,因此它将绑定到 -Path

PS> SimpleTest @hash "MyPath"
Name: Hello; Path: MyPath; Args: -Blah: World

语言更改

Null 合并操作符 ??

如果 null 合并运算符 ?? 不为 null,则它返回其左操作数的值。 否则,它将计算右操作数并返回其结果。 如果左操作数的计算结果为非 null,则 ?? 运算符不会计算其右操作数。

$x = $null
$x ?? 100
100

在下面的示例中,不会计算右操作数。

[string] $todaysDate = '1/10/2020'
$todaysDate ?? (Get-Date).ToShortDateString()
1/10/2020

Null 合并赋值运算符 ??=

仅当左操作数的计算结果为 NULL 时,Null 合并赋值运算符 ??= 才会将其右操作数的值赋值给其左操作数。 如果左操作数的计算结果为非 null,则 ??= 运算符不会计算其右操作数。

$x = $null
$x ??= 100
$x
100

在下面的示例中,不会计算右操作数。

[string] $todaysDate = '1/10/2020'
$todaysDate ??= (Get-Date).ToShortDateString()
1/10/2020

Null 条件运算符

备注

在 PowerShell 7.1 中,此功能已从实验性功能转变为主要功能。

仅当操作数的计算结果为非 NULL 时,NULL 条件运算符才对其操作数应用成员访问 ?. 或元素访问 ?[] 操作;否则,它会返回 NULL。

由于 PowerShell 允许 ? 作为变量名称的一部分,因此使用这些运算符需要变量名称的形式规范。 因此,使用 {} 将变量名称括起来(如 ${a})或 ? 是变量名称 ${a?} 的一部分时需要形式规范。

在以下示例中,返回 PropName 的值。

$a = @{ PropName = 100 }
${a}?.PropName
100

以下示例将返回 NULL,而不尝试访问成员名称 PropName。

$a = $null
${a}?.PropName

同样,将返回元素的值。

$a = 1..10
${a}?[0]
1

如果操作数为 NULL,则不会访问元素并返回 NULL。

$a = $null
${a}?[0]

备注

不应将变量名称语法 ${<name>}$() 子表达式运算符混淆。 有关详细信息,请参阅 about_Variables 的“变量名称”部分。

添加 & 运算符用于作业控制

& 置于管道末尾会导致管道作为 PowerShell 作业运行。 管道在后台运行时会返回作业对象。 管道作为作业运行后,所有标准 *-Job cmdlet 均可以用来管理该作业。 此管道中使用的变量(特定于进程的变量除外)自动复制到该作业,从而使 Copy-Item $foo $bar & 正常运行。 该作业还会在当前目录而不是用户主目录中运行。

PSCustomObject 上的新方法/属性

我们为 PSCustomObject 添加了新的方法和属性。 PSCustomObject 现在包括类似于其他对象的 Count/Length 属性。

$PSCustomObject = [pscustomobject]@{foo = 1}

$PSCustomObject.Length
1
$PSCustomObject.Count
1

此工作还包括 ForEachWhere 方法,这些方法允许对 PSCustomObject 项进行操作和筛选:

$PSCustomObject.ForEach({$_.foo + 1})
2
$PSCustomObject.Where({$_.foo -gt 0})
foo
---
  1

从 PSMethod 到委托的转换

可以将 PSMethod 转换为委托。 这样,可以执行将 PSMethod[M]::DoubleStrLen 作为委托值传递到 [M]::AggregateString 等操作:

class M {
    static [int] DoubleStrLen([string] $value) { return 2 * $value.Length }

    static [long] AggregateString([string[]] $values, [func[string, int]] $selector) {
        [long] $res = 0
        foreach($s in $values){
            $res += $selector.Invoke($s)
        }
        return $res
    }
}

[M]::AggregateString((gci).Name, [M]::DoubleStrLen)

PowerShell 7.1 中的字符串比较行为已更改

PowerShell 7.1 是在 .NET 5.0 基础上构建的,它引入了以下中断性变更:

从 .NET 5.0 开始,区域性固定的字符串比较将忽略非打印控制字符。

例如,以下两个字符串被视为是相同的:

# Escape sequence "`a" is Ctrl-G or [char]7
'Food' -eq "Foo`ad"
True

新 cmdlet

新 Get-Uptime cmdlet

Get-Uptime cmdlet 返回自操作系统上次启动以来经过的时间。 此 cmdlet 是在 PowerShell 6.0 中引入的。

新 Remove-Alias cmdlet

Remove-Alias cmdlet 从当前 PowerShell 会话中删除别名。 此 cmdlet 是在 PowerShell 6.0 中引入的。

新 cmdlet Remove-Service

Remove-Service cmdlet 删除注册表和服务数据库中的 Windows 服务。 Remove-Service cmdlet 是在 PowerShell 6.0 中引入的。

新 Markdown cmdlet

Markdown 是创建可读明文文档的标准,其基本格式可以呈现为 HTML。

以下 cmdlet 已添加到 PowerShell 6.1 中:

  • ConvertFrom-Markdown - 将字符串或文件的内容转换为 MarkdownInfo 对象。
  • Get-MarkdownOption - 返回用于在控制台中呈现 Markdown 内容的当前颜色和样式。
  • Set-MarkdownOption - 设置用于在控制台中呈现 Markdown 内容的颜色和样式。
  • Show-Markdown - 在控制台中显示 Markdown 内容或以 HTML 形式显示

新 Test-Json cmdlet

Test-Json cmdlet 测试字符串是否为有效的 JavaScript 对象表示法 (JSON) 文档,并且可以选择性地根据提供的架构验证该 JSON 文档。

此 cmdlet 是在 PowerShell 6.1 中引入的

支持实验性功能的新 cmdlet

PowerShell 6.2 中添加了以下 cmdlet 以支持实验性功能。

新 Join-String cmdlet

Join-String cmdlet 将管道中的对象合并为单个字符串。 此 cmdlet 是在 PowerShell 6.2 中添加的。

新视图 ConciseView 和 cmdlet Get-Error

PowerShell 7.0 具有新的默认视图 ConciseView,它增强了错误消息的显示,进而提高了交互式错误和脚本错误的可读性。 视图通过首选项变量 $ErrorView 可供用户选择。

使用 ConciseView,如果错误不是源自脚本或分析器错误,则它是单行错误消息:

Get-Childitem -Path c:\NotReal
Get-ChildItem: Cannot find path 'C:\NotReal' because it does not exist

如果在脚本执行期间发生错误或者错误是分析错误,则 PowerShell 将返回一条多行错误消息,其中包含错误、指针以及显示错误在该行中的位置的错误消息。 如果终端不支持 ANSI 颜色转义序列 (VT100),则不会显示颜色。

PowerShell 7 中的默认视图是 ConciseView。 之前的默认视图是 NormalView,你可通过设置首选项变量 $ErrorView 来选择它。

$ErrorView = 'NormalView' # Sets the error view to NormalView
$ErrorView = 'ConciseView' # Sets the error view to ConciseView

备注

$Host.PrivateData 添加新属性 ErrorAccentColor,以支持更改错误消息的主题色。

新的 cmdlet Get-Error 在需要时可提供完全符合条件的错误的完整详细视图。 默认情况下,该 cmdlet 将显示所发生的最后一个错误的完整详细信息(包括内部异常)。

Get-Error cmdlet 使用内置变量 $Error 支持来自管道的输入。 Get-Error 显示所有管道错误。

$Error | Get-Error

Get-Error cmdlet 支持最新参数,允许你指定当前会话中要显示的错误数。

Get-Error -Newest 3 # Displays the lst three errors that occurred in the session

有关详细信息,请参阅 Get-Error

Cmdlet 更改

添加到 ForEach-Object 的并行执行

从 PowerShell 7.0 开始,循环访问集合中的项的 ForEach-Object cmdlet 现在使用新的 Parallel 参数实现内置并行。

默认情况下,并行脚本块使用启动并行任务的调用方的当前工作目录。

此示例从本地 Windows 计算机上的 5 个系统日志中检索 50,000 个日志条目:

$logNames = 'Security','Application','System','Windows PowerShell','Microsoft-Windows-Store/Operational'

$logEntries = $logNames | ForEach-Object -Parallel {
    Get-WinEvent -LogName $_ -MaxEvents 10000
} -ThrottleLimit 5

$logEntries.Count

50000

Parallel 参数指定为每个输入日志名称并行运行的脚本块。

新的 ThrottleLimit 参数限制在给定时间内并行运行的脚本块数量。 默认值为 5。

使用 $_ 变量来表示脚本块中的当前输入对象。 使用 $using: 范围将变量引用传递给正在运行的脚本块。

有关详细信息,请参阅 ForEach-Object

在 Windows 上检查 system32 以获取兼容的内置模块

在 Windows 10 1809 更新和 Windows Server 2019 中,我们更新了许多内置 PowerShell 模块,将其标记为与 PowerShell 兼容。

当 PowerShell 启动时,它自动将 $windir\System32 包含为 PSModulePath 环境变量的一部分。 但是,如果模块 CompatiblePSEdition 被标记为与 Core 兼容,则它仅将模块公开给 Get-ModuleImport-Module

可以替代此行为,使用 -SkipEditionCheck 开关参数显示所有模块。 我们还在表输出中添加了 PSEdition 属性。

所有 -LiteralPath 参数的 -lp 别名

我们为所有具有 -LiteralPath 参数的内置 PowerShell cmdlet 创建了标准参数别名 -lp

如果 a*b 实际上不存在,则修复 Get-Item -LiteralPath a*b 以返回错误

以前,给定通配符的 -LiteralPath 将其视为与 -Path 相同,如果该通配符未找到任何文件,则会以无提示方式退出。 正确的行为应该是 -LiteralPath 是文本,因此,如果文件不存在,它应显示错误。 更改就是将与 -Literal 一起使用的通配符视作文本。

Start-Job 中将工作目录设置为当前目录

Start-Job cmdlet 现在使用当前目录作为新作业的工作目录。

*-Computer cmdlet 中删除 -Protocol

由于 CoreFX 中的 RPC 远程处理出现问题(特别是在非 Windows 平台上)以及为确保在 PowerShell 中获得一致的远程处理体验,已将 -Protocol 参数从 \*-Computer cmdlet 中删除。 远程处理功能不再支持 DCOM。 以下 cmdlet 仅支持 WSMAN 远程处理:

  • Rename-Computer
  • Restart-Computer
  • Stop-Computer

*-Service cmdlet 中删除 -ComputerName

为了鼓励一致地使用 PSRP,已将 -ComputerName 参数从 *-Service cmdlet 中删除。

修复 Get-Content -Delimiter 以便不在返回的行中包含分隔符

以前,使用 Get-Content -Delimiter 时的输出不一致且不方便,因为它需要进一步处理数据才能删除分隔符。 此更改删除返回行中的分隔符。

Format-Hex 的更改

-Raw 参数现在是一个“no-op”(因为它不执行任何操作)。 今后所有输出都显示为实际数字表示形式,其中包括其类型的所有字节。 这就是在此更改之前 -Raw 参数的作用。

Get-ComputerInfo 属性名中的拼写错误修复

BiosSerialNumber 被错误地拼写为 BiosSeralNumber,并被更改为正确的拼写。

添加 Get-StringHashGet-FileHash cmdlet

此更改是 CoreFX 不支持的一些哈希算法,因此它们将不再可用:

  • MACTripleDES
  • RIPEMD160

在传递 $null 返回所有对象而不是错误时在 Get-* cmdlet 上添加验证

$null 传递给以下任何项,现在会引发错误:

  • Get-Credential -UserName
  • Get-Event -SourceIdentifier
  • Get-EventSubscriber -SourceIdentifier
  • Get-Help -Name
  • Get-PSBreakpoint -Script
  • Get-PSProvider -PSProvider
  • Get-PSSessionConfiguration -Name
  • Get-Runspace -Name
  • Get-RunspaceDebug -RunspaceName
  • Get-Service -Name
  • Get-TraceSource -Name
  • Get-Variable -Name

Import-Csv 中添加对 W3C 扩展日志文件格式的支持

以前,Import-Csv cmdlet 不能用于直接导入采用 W3C 扩展日志格式的日志文件,并且需要执行其他操作。 进行此更改后,支持 W3C 扩展日志格式。

当类型信息以 CSV 显示时,Import-Csv 在导入时应用 PSTypeNames

以前,使用 Export-CSV 导出的对象(带有使用 ConvertFrom-Csv 导入的 TypeInformation)已不保留类型信息。 此更改会将类型信息添加到 PSTypeNames 成员(若可从 CSV 文件中获得)。

-NoTypeInformationExport-Csv 上的默认值

以前,Export-CSV cmdlet 将输出一条注释作为包含对象的类型名称的第一行。 默认情况下,更改会排除类型信息,因为大多数 CSV 工具无法理解该信息。 此更改的目的是为了解决客户反馈。

使用 -IncludeTypeInformation 以保留以前的行为。

允许为 Remove-Item 在注册表路径中使用 *

以前,给定通配符的 -LiteralPath 将其视为与 -Path 相同,如果该通配符未找到任何文件,则会以无提示方式退出。 正确的行为应该是 -LiteralPath 是文本,因此,如果文件不存在,它应显示错误。 更改就是将与 -Literal 一起使用的通配符视作文本。

组对象现在对组进行排序

作为性能改进的一部分,Group-Object 现在返回组的已排序列表。 虽然不应依赖于顺序,但如果想要第一组,则可能会被此更改所破坏。 我们认为这种性能改进是值得更改的,因为依赖于以前行为的影响很小。

Measure-Object 中的标准偏差

Measure-Object 中的输出现在包括 StandardDeviation 属性。

Get-Process | Measure-Object -Property CPU -AllStats
Count             : 308
Average           : 31.3720576298701
Sum               : 9662.59375
Maximum           : 4416.046875
Minimum           :
StandardDeviation : 264.389544720926
Property          : CPU

Get-PfxCertificate -Password

Get-PfxCertificate 现在已具备采用 SecureStringPassword 参数。 这允许以非交互方式使用它:

$certFile = '\\server\share\pwd-protected.pfx'
$certPass = Read-Host -AsSecureString -Prompt 'Enter the password for certificate: '

$certThumbPrint = (Get-PfxCertificate -FilePath $certFile -Password $certPass ).ThumbPrint

删除 more 函数

在过去,PowerShell 在 Windows 上发布了一个名为 more 的函数,它包含 more.com。 该函数现在已删除。

此外,help 函数已改为在 Windows 上使用 more.com,或在非 Windows 平台上使用 $env:PAGER 指定的系统默认页导航。

cd DriveName: 现在将用户返回到该驱动器中的当前工作目录

以前使用 Set-Locationcd 返回到 PSDrive 会将用户发送到该驱动器的默认位置。 现在会将用户发送到该会话最后一个已知的当前工作目录。

cd - 返回到上一目录

C:\Windows\System32> cd C:\
C:\> cd -
C:\Windows\System32>

或者,在 Linux 上:

PS /etc> cd /usr/bin
PS /usr/bin> cd -
PS /etc>

cdcd -- 也更改为 $HOME

Update-Help 更改为非管理员命令

根据大众需求,Update-Help 不再需要以管理员身份运行。 Update-Help 现在默认将帮助保存到用户范围的文件夹。

Where-Object -Not

-Not 参数添加到 Where-Object 后,可在管道中筛选对象,查看是否有不存在的属性或 null/空属性值。

例如,此命令返回未定义任何依赖服务的所有服务:

Get-Service | Where-Object -Not DependentServices

对 Web Cmdlet 的更改

Web Cmdlet 的基础 .NET API 已更改为 System.Net.Http.HttpClient。 此更改提供了许多好处。 但是,此更改以及缺乏与 Internet Explorer 的互操作性导致了 Invoke-WebRequestInvoke-RestMethod 中的几次重大更改。

  • Invoke-WebRequest 现在仅支持基本 HTML 分析。 Invoke-WebRequest 始终返回一个 BasicHtmlWebResponseObject 对象。 已删除 ParsedHtmlForms 属性。
  • BasicHtmlWebResponseObject.Headers 值现在是 String[] 而不是 String
  • BasicHtmlWebResponseObject.BaseResponse 现在是一个 System.Net.Http.HttpResponseMessage 对象。
  • Web Cmdlet 异常上的 Response 属性现在是一个 System.Net.Http.HttpResponseMessage 对象。
  • 对于 -Headers-UserAgent 参数,严格的 RFC 标头分析是默认设置。 这可以使用 -SkipHeaderValidation 绕过。
  • 不再支持 file://ftp:// URI 方案。
  • 不再采用 System.Net.ServicePointManager 设置。
  • 目前在 macOS 上尚无基于证书的身份验证。
  • 通过 http:// URI 使用 -Credential 将导致错误。 使用 https:// URI 或提供 -AllowUnencryptedAuthentication 参数来阻止此错误。
  • 现在当重定向尝试超过提供的限制时,-MaximumRedirection 会生成终止错误时,而不是返回最后一次重定向的结果。
  • 在 PowerShell 6.2 中,JSON 响应默认更改为 UTF-8 编码。 如果未为 JSON 响应提供字符集,则依照 RFC 8259,默认编码应为 UTF-8。
  • 对于 application-json 响应,默认编码设置为 UTF-8
  • 添加了 -SkipHeaderValidation 参数以允许不符合标准的 Content-Type 标头
  • 添加了 -Form 参数以支持简化的 multipart/form-data 支持
  • 合规且不区分大小写的关系键处理
  • 添加了 Web cmdlet 的 -Resume 参数

在没有返回任何数据时,Invoke-RestMethod 返回有用的信息

当 API 仅返回 null 时,Invoke-RestMethod 将其序列化为字符串 "null",而不是 $null。 此项更改修复了 Invoke-RestMethod 中的逻辑,以便将有效的单个值 JSON null 文本正确序列化为 $null

通过未加密的连接发送 -Credential 时,Web Cmdlet 发出警告

使用 HTTP 时,包括密码在内的内容将以明文形式发送。 此更改默认不允许此操作,并且如果以不安全的方式传递凭据,则返回错误。 用户可以使用 -AllowUnencryptedAuthentication 开关来绕过此操作。

在 Web cmdlet 中指定 -OutFile 参数,使其具有与 -LiteralPath 相同的作用

从 PowerShell 7.1 开始,Web cmdlet 的 OutFile 参数具有与 LiteralPath 相同的作用,并且不处理通配符 。

API 更改

删除 AddTypeCommandBase

Add-Type 删除 AddTypeCommandBase 类以提高性能。 此类仅供 Add-Type cmdlet 使用,不应影响用户。

已在 Add-Type 中删除作为受支持语言的 VisualBasic

在过去,可以使用 Add-Type cmdlet 编译 Visual Basic 代码。 Visual Basic 很少与 Add-Type 一起使用。 我们已删除此功能以减小 PowerShell 的大小。

已删除 RunspaceConfiguration 支持

以前,在使用 API 以编程方式创建 PowerShell 运行空间时,可以使用旧版 RunspaceConfiguration 或较新的 InitialSessionState 类。 此更改不再支持 RunspaceConfiguration 并仅支持 InitialSessionState

CommandInvocationIntrinsics.InvokeScript 将参数绑定到 $input 而不是 $args

形参的位置不正确会导致将实参作为输入而不是实参进行传递。

$PSVersionTable 中删除 ClrVersionBuildVersion

$PSVersionTableClrVersion 属性对 CoreCLR 没有用。 最终用户不应使用该值来确定兼容性。

BuildVersion 属性已绑定到 Windows 内部版本,该版本在非 Windows 平台上不可用。 使用 GitCommitId 属性检索 PowerShell 的确切内部版本。

实现 Unicode 转义分析

`u#### `u{####} 转换为相应的 Unicode 字符。 若要输出文本 `u,转义反引号: ``u

PS 函数中 ValueFromRemainingArguments 的参数绑定问题

ValueFromRemainingArguments 现在返回一些值作为数组,而不是本身是数组的单个值。

已清理 CommandTypes.WorkflowWorkflowInfoCleaned 的使用

清理与 System.Management.Automation 中的 CommandTypes.WorkflowWorkflowInfo 的使用相关的代码。

这些次要的中断性变更主要影响帮助提供程序代码。

  • WorkflowInfo 的公共构造函数更改为内部构造函数。 我们不再支持工作流,因此不允许用户创建 Workflow 实例是合理的。
  • 删除类型 System.Management.Automation.DebugSource,因为它仅用于工作流调试。
  • 从仅用于工作流调试的抽象类 Debugger 中删除 SetParent 的重载。
  • 从派生类 RemotingJobDebugger 中删除 SetParent 的相同重载。

ScriptBlock 转换为委托时,不要将返回结果包装为 PSObject

ScriptBlock 转换为要在 C# 上下文中使用的委托类型时,将结果包装为 PSObject 会导致不必要的麻烦:

  • 当值转换为委托返回类型时,PSObject 实质上是已解包。 因此不需要 PSObject
  • 如果委托返回类型为 object,则将其包装为 PSObject 会使其难以在 C# 代码中运行。

进行此更改后,返回的对象是基础对象。

远程处理支持

在 Unix 平台上使用 WinRM 的 PowerShell 远程处理 (PSRP) 时需要通过 HTTPS 进行 NTLM/协商或基本身份验证。 macOS 上的 PSRP 仅支持通过 HTTPS 进行基本身份验证。 非 Windows 平台不支持基于 Kerberos 的身份验证。

PowerShell 还支持所有平台(Windows、macOS 和 Linux)上通过 SSH 的 PowerShell 远程处理 (PSRP)。 有关详细信息,请参阅 PowerShell 中的 SSH 远程处理

适用于容器的 PowerShell Direct 尝试先使用 pwsh

PowerShell Direct 是 PowerShell 和 Hyper-V 的一项功能,允许在没有网络连接或其他远程管理服务的情况下连接到 Hyper-V VM 或容器。

在过去,PowerShell Direct 使用容器上的内置 Windows PowerShell 实例进行连接。 现在,PowerShell Direct 先尝试使用 PATH 环境变量上任何可用的 pwsh.exe 进行连接。 如果 pwsh.exe 不可用,PowerShell Direct 则会回退为使用 powershell.exe

Enable-PSRemoting 现在为预览版本创建单独的远程处理终结点

Enable-PSRemoting 现在创建两个远程会话配置:

  • 一个用于 PowerShell 的主要版本。 例如,PowerShell.6 。 根据“系统范围”的 PowerShell 6 会话配置,次要版本更新可依赖于此终结点
  • 一个版本特定的会话配置,例如:PowerShell.6.1.0

如果要在同一台计算机上安装并访问多个 PowerShell 6 版本,则此行为会很有帮助。

此外,预览版本的 PowerShell 现在可以在运行 Enable-PSRemoting cmdlet 后获取自己的远程会话配置:

C:\WINDOWS\system32> Enable-PSRemoting

如果之前未设置 WinRM,则输出可能会有所不同。

WinRM is already set up to receive requests on this computer.
WinRM is already set up for remote management on this computer.

然后可以查看 PowerShell 6 的预览版和稳定版本以及每个特定版本单独的 PowerShell 会话配置。

Get-PSSessionConfiguration
Name          : PowerShell.6.2-preview.1
PSVersion     : 6.2
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name          : PowerShell.6-preview
PSVersion     : 6.2
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name          : powershell.6
PSVersion     : 6.1
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

Name          : powershell.6.1.0
PSVersion     : 6.1
StartupScript :
RunAsUser     :
Permission    : NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed

SSH 支持的 user@host:port 语法

SSH 客户端通常支持格式为 user@host:port 的连接字符串。 我们通过将 SSH 添加为 PowerShell 远程处理的协议,增加了对这种连接字符串格式的支持:

Enter-PSSession -HostName fooUser@ssh.contoso.com:2222

只能使用环境变量禁用遥测

PowerShell 在启动时会向 Microsoft 发送基本的遥测数据。 该数据包括 OS 名称、OS 版本和 PowerShell 版本。 此数据帮助我们更好地了解使用 PowerShell 的环境,并能确定新功能和修复的优先级。

要选择退出此遥测,请将环境变量 POWERSHELL_TELEMETRY_OPTOUT 设置为 trueyes1。 我们不再支持删除文件 DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY 以禁用遥测。