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 的不同之处。 有关各版本之间的差异和新增功能的详细讨论,请参阅每个版本的“新增功能”一文。
- PowerShell 7.5 中的新增功能
- PowerShell 7.4 中的新增功能
- PowerShell 7.3 中的新增功能
- PowerShell 7.2 中的新增功能
- PowerShell 7.1 中的新增功能
- PowerShell 7.0 中的新增功能
- PowerShell 6.x 中的新增功能
.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-WinEvent
和 New-WinEvent
可用于在 Windows 上获取和创建事件。
使用 Windows Presentation Framework (WPF) 的 cmdlet
.NET Core 3.1 添加了对 WPF 的支持,因此 PowerShell 7.0 恢复了以下 Windows 特定功能:
Show-Command
cmdletOut-GridView
cmdletGet-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.ps1
或pwsh fooScript
等命令。 但是,尝试运行pwsh.exe -Command Get-Command
等命令时,此更改会要求显示指定-c
或-Command
。 pwsh
接受-i
(或-Interactive
)切换表示交互式 shell。 这使 PowerShell 可用作 Unix 平台上的默认 shell。- 已将参数
-ImportSystemModules
和-PSConsoleFile
从pwsh.exe
中删除。 - 已更改
pwsh -version
和pwsh.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-ExperimentalFeature
和 Disable-ExperimentalFeature
启用或禁用这些功能。
在尝试从 GAC 加载程序集之前,先从模块基路径加载程序集
以前,当二进制模块在 GAC 中具有模块程序集时,我们会在从模块基路径中加载程序集之前从 GAC 中加载该程序集。
对具有值类型元素类型的集合,跳过 null 元素检查
对于 Mandatory
参数及 ValidateNotNull
和 ValidateNotNullOrEmpty
属性,如果集合的元素类型是值类型,则跳过 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
类型
-Encoding
值 Byte
已从文件系统提供程序 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
此工作还包括 ForEach
和 Where
方法,这些方法允许对 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-Module
和 Import-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-StringHash
和 Get-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 文件中获得)。
-NoTypeInformation
是 Export-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
现在已具备采用 SecureString
的 Password
参数。 这允许以非交互方式使用它:
$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-Location
或 cd
返回到 PSDrive 会将用户发送到该驱动器的默认位置。 现在会将用户发送到该会话最后一个已知的当前工作目录。
cd -
返回到上一目录
C:\Windows\System32> cd C:\
C:\> cd -
C:\Windows\System32>
或者,在 Linux 上:
PS /etc> cd /usr/bin
PS /usr/bin> cd -
PS /etc>
cd
和 cd --
也更改为 $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-WebRequest
和 Invoke-RestMethod
中的几次重大更改。
Invoke-WebRequest
现在仅支持基本 HTML 分析。Invoke-WebRequest
始终返回一个BasicHtmlWebResponseObject
对象。 已删除ParsedHtml
和Forms
属性。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
中删除 ClrVersion
和 BuildVersion
$PSVersionTable
的 ClrVersion
属性对 CoreCLR 没有用。 最终用户不应使用该值来确定兼容性。
BuildVersion
属性已绑定到 Windows 内部版本,该版本在非 Windows 平台上不可用。 使用 GitCommitId
属性检索 PowerShell 的确切内部版本。
实现 Unicode 转义分析
将 `u####
或 `u{####}
转换为相应的 Unicode 字符。 若要输出文本 `u
,转义反引号: ``u
。
PS 函数中 ValueFromRemainingArguments
的参数绑定问题
ValueFromRemainingArguments
现在返回一些值作为数组,而不是本身是数组的单个值。
已清理 CommandTypes.Workflow
和 WorkflowInfoCleaned
的使用
清理与 System.Management.Automation 中的 CommandTypes.Workflow
和 WorkflowInfo
的使用相关的代码。
这些次要的中断性变更主要影响帮助提供程序代码。
- 将
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
设置为 true
、yes
或 1
。 我们不再支持删除文件 DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY
以禁用遥测。