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 上运行。
在 PowerShell 语言方面,Windows 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 工作流 是 Windows PowerShell 中的一项功能,它基于 Windows Workflow Foundation (WF) 构建,可为长时间运行或并行化的任务创建可靠的 Runbook。
由于在 .NET Core 中缺少对 Windows Workflow Foundation 的支持,我们从 PowerShell 中删除了 PowerShell 工作流。
将来,我们希望在 PowerShell 语言中启用本机并行/并发,而无需 PowerShell 工作流。
如果需要在 OS 重启后使用检查点恢复脚本,我们建议使用任务计划程序在 OS 启动时运行脚本,但脚本需要维护自己的状态(如将其保存到文件)。
从 PowerShell 中删除的 cmdlet
对于 PowerShell 中包含的模块,出于各种兼容性原因或使用不受支持的 API,从 PowerShell 中删除了以下 cmdlet。
CimCmdlets
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 模块 (aka WMI v2) cmdlet 执行相同的功能,并提供新功能和重新设计的语法。
删除了 New-WebServiceProxy
cmdlet
.NET Core 不支持提供使用 SOAP 协议的服务的 Windows 通信框架。 此 cmdlet 已删除,因为它需要 SOAP。
*-Transaction
cmdlet 已删除
这些 cmdlet 的使用非常有限。 决定停止支持他们。
Complete-Transaction
Get-Transaction
Start-Transaction
Undo-Transaction
Use-Transaction
*-EventLog
cmdlet
由于使用了不支持的 API,*-EventLog
cmdlet 已从 PowerShell 中删除。
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 开始,PSDesiredStateConfiguration 模块已从 PowerShell 中删除,并已发布到 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。 这允许在 Unix 平台上将 PowerShell 用作默认 shell。 - 从
pwsh.exe
中删除了参数-ImportSystemModules
和-PSConsoleFile
。 - 更改了
pwsh -Version
,并调整了pwsh.exe
的内置帮助,使其与其他原生工具保持一致。 -File
和-Command
的无效参数错误消息和与 Unix 标准一致的退出代码- 在 Windows 上添加了
-WindowStyle
参数。 同样,非 Windows 平台上基于包的安装更新是就地更新。
缩短的名称也与非 Windows 平台上 shell 的命名一致。
支持使用布尔参数运行 PowerShell 脚本
以前,使用 pwsh.exe
通过 -File
执行 PowerShell 脚本时,没有办法将 $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 Update 的支持。 启用此功能时,你将在传统的 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
,但并非是故意表示失败。 通过此更改,stderr
输出仍捕获到 ErrorRecord 对象中,但如果 ErrorRecord 来自本机命令,运行时将不再应用 $ErrorActionPreference
。
更改 $OutputEncoding
以使用 UTF-8 NoBOM
编码,而不是 ASCII
在某些情况下,以前的编码 ASCII(7 位)将导致输出错误更改。 将 UTF-8 NoBOM
设置为默认值以保留 Unicode 输出,并且大多数工具和操作系统都支持该编码。
将带有参数 -Encoding
的 cmdlet 统一为 System.Text.Encoding
类型
-Encoding
值 Byte
已从文件系统提供程序 cmdlet 中删除。 新的参数 -AsByteStream
现在用于指定输入是否需要字节流或输出是否为字节流。
将 New-ModuleManifest
编码更改为非 Windows 平台上的 UTF8NoBOM
以前,New-ModuleManifest
使用 BOM 在 UTF-16 中创建 psd1
清单,从而为 Linux 工具创建问题。 此重大变更将非 Windows 平台中 New-ModuleManifest
的编码更改为 UTF 编码格式(无 BOM)。
从大多数默认别名中删除 AllScope
为了加快范围创建速度,AllScope
已从大多数默认别名中删除。 为一些常用别名保留了AllScope
,以便更快地查找。
-Verbose
和 -Debug
不再替代 $ErrorActionPreference
以前,如果指定了 -Verbose
或 -Debug
,它会覆盖 $ErrorActionPreference
的行为。 通过此更改,-Verbose
和 -Debug
不再影响 $ErrorActionPreference
的行为。
此外,-Debug
参数将 $DebugPreference
设置为 Continue,而不是 Inquire。
使 $PSCulture
一致地反映会话中区域性更改
在 Windows PowerShell 中,将缓存当前区域性值,这样可避免值在会话启动后区域性发生变化时与之同步。 PowerShell 核心中修复了此缓存行为。
允许显式指定的命名参数取代展开的哈希表中的同一个参数
进行此更改后,展开中的命名参数将移到参数列表的末尾,这样在所有显式指定的命名参数被绑定后,它们就会被绑定。 找不到指定的命名参数时,简单函数的参数绑定不会引发错误。 未知的命名参数被绑定到简单函数的 $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+ 上比较字符串时的行为变化
从 .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 中引入。
新的命令行工具 Remove-Service
Remove-Service cmdlet 删除注册表和服务数据库中的 Windows 服务。 PowerShell 6.0 中引入了 Remove-Service
cmdlet。
新 Markdown cmdlet
Markdown 是创建具有基本格式的可读纯文本文档(可呈现为 HTML)的标准。
PowerShell 6.1 中添加了以下 cmdlet:
- ConvertFrom-Markdown - 将字符串或文件的内容转换为 MarkdownInfo 对象。
- Get-MarkdownOption - 返回用于在控制台中呈现 Markdown 内容的当前颜色和样式。
- Set-MarkdownOption - 设置用于在控制台中呈现 Markdown 内容的颜色和样式。
- Show-Markdown - 在控制台中或以 HTML 格式显示 Markdown 内容
新 Test-Json cmdlet
Test-Json cmdlet 测试字符串是否为有效的 JavaScript 对象表示法(JSON)文档,并且可以选择性地根据提供的架构验证 JSON 文档。
PowerShell 6.1 中引入了此 cmdlet
支持实验性功能的新 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 中的默认视图 简明视图。 之前的默认视图是 NormalView,您可以通过设置首选项变量 $ErrorView
来选择此视图。
$ErrorView = 'NormalView' # Sets the error view to NormalView
$ErrorView = 'ConciseView' # Sets the error view to ConciseView
注释
向 $Host.PrivateData
添加新属性 ErrorAccentColor,以支持更改错误消息的主题色。
如果需要,新的 Get-Error
cmdlet 提供了完全限定错误的完整详细视图。 默认情况下,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
属性。
-lp
是所有 -LiteralPath
参数的别名
我们为具有 -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 中保持一致的远程处理体验,已从 \*-Computer
cmdlet 中移除了 -Protocol
参数。 远程处理功能不再支持 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
在 Get-*
cmdlet 上添加一个验证,以便在传递 $null 时返回所有对象,而不是产生错误。
将 $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
)已不保留类型信息。 如果 CSV 文件中有可用的类型信息,此更改会将其添加到 pstypenames
字段。
-NoTypeInformation
是 Export-Csv
的默认值
以前,Export-Csv
cmdlet 将输出注释作为包含对象类型名称的第一行。 默认情况下,更改会排除类型信息,因为大多数 CSV 工具无法理解该信息。 此更改旨在解决客户反馈问题。
使用 -IncludeTypeInformation
保留以前的行为。
允许为 Remove-Item
在注册表路径中使用 *
以前,-LiteralPath
给定的通配符将将其视为与 -Path
相同,如果通配符未找到任何文件,它将以无提示方式退出。 正确的行为应该是,-LiteralPath
为文本,因此,如果文件不存在,则它应出错。 更改就是将与 -Literal
一起使用的通配符视作文本。
Group-Object 现在对组进行排序
作为性能改进的一部分,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
现在具有 Password
参数,这个参数需要 SecureString
。 这样就可以以非交互方式使用它:
$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
后,可以在管道中过滤掉不存在属性或具有空/无效属性值的对象。
例如,此命令返回未定义任何依赖服务的所有服务:
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 目前没有可用的基于证书的身份验证。
- 使用
-Credential
而不是http://
URI 会导致错误。 使用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
类
AddTypeCommandBase
类已从 Add-Type
中删除,以提高性能。 此类仅供 Add-Type
cmdlet 使用,不应影响用户。
在 Add-Type 中删除了对 VisualBasic
这门语言的支持
过去,可以使用 Add-Type
cmdlet 编译 Visual Basic 代码。 Visual Basic 很少与 Add-Type
一起使用。 我们删除了此功能以减少 PowerShell 的大小。
已删除 RunspaceConfiguration
支持
以前,使用 API 以编程方式创建 PowerShell Runspace 时,可以使用旧版 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,因为它仅用于工作流调试。
- 从仅用于工作流调试的抽象类 调试器 中删除
SetParent
的重载。 - 从派生类 RemotingJobDebugger 中删除
SetParent
的相同重载。
将 ScriptBlock
转换为委托时,不要将返回结果包装为 PSObject
当 ScriptBlock
转换为用于 C# 上下文的委托类型时,将结果包装在 PSObject
中会带来不必要的麻烦:
- 当值转换为委托返回类型时,
PSObject
实质上是已解包。 因此,PSObject
是不需要的。 - 当委托返回类型
object
时,它将包装在PSObject
中,使其难以在 C# 代码中使用。
此更改后,返回的对象是基础对象。
远程通信支持
在 Unix 平台上使用 WinRM 的 PowerShell 远程处理(PSRP)需要通过 HTTPS 进行 NTLM/Negotiate 或基本身份验证。 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 版本,则此行为非常有用。
此外,运行 Enable-PSRemoting
cmdlet 后,PowerShell 预览版现在可以获得自己的远程会话配置:
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
以禁用遥测。