在 Windows 上使用 PowerShell 7 的全面指南
1. 理解 PowerShell 7 和 Windows PowerShell
PowerShell 7 是跨平台的开源工具,而 Windows PowerShell 则是基于 Windows 系统的特定版本。PowerShell 7 构建在开源的 .NET Core 平台上,而 Windows PowerShell 基于完整的专有 .NET Framework。这导致了两者在兼容性上存在差异。
Windows PowerShell 与 Windows 操作系统及其上运行的许多应用程序具有更高的原生兼容性,因为它可以利用 .NET Framework 中 PowerShell 7 无法访问的元素。微软将运行在 .NET Framework 上的 PowerShell 称为桌面版,将运行在开源 .NET 上的称为核心版。
大多数 PowerShell 功能来自于可扩展的库,即模块。要运行模块中的命令,PowerShell 必须先加载该模块。虽然微软已经重写了许多核心和常用的 PowerShell 模块,但并非所有模块都与 PowerShell 7 兼容。有些模块可能由于作者尚未更新,或者模块的关键功能依赖于 .NET Framework 中不存在于开源 .NET Core 的特性,导致不兼容。如果尝试加载这些不兼容的模块,通常会导致错误或无法正常工作。
2. 探索兼容性
要确定哪些模块与 PowerShell 7 兼容,可以在 Windows PowerShell 中运行以下命令:
Get-Module | Format-Table -Auto -Wrap Name, CompatiblePSEditions, Version
运行该命令后,可能会得到类似以下的输出:
| Name | CompatiblePSEditions | Version |
|------------------------------|----------------------|---------|
| Microsoft.PowerShell.Management | Desktop, Core | 版本号 |
| Microsoft.Powershell.Utility | Desktop | 版本号 |
| Microsoft.PowerShell.Security | Desktop | 版本号 |
| Microsoft.WSMan.Management | Desktop | 版本号 |
| 其他模块 | 无信息 | 版本号 |
从输出中可以看出,部分模块有兼容性信息,有些模块则没有。没有兼容性信息的模块可能是在 PowerShell Core 发布之前编写的,因此仅与桌面版兼容,或者是不适合包含兼容性信息的模块类型。模块有四种类型:脚本模块、清单模块、二进制模块和动态模块。清单模块包含扩展名为 .Psd1 的清单文件,可以通过运行
Get-Module <modulename>
来检查模块的类型。
当需要某个模块的功能,但该模块未被列为与 PowerShell 7 兼容时,有以下三种选择:
-
寻找兼容版本
:PowerShell 7 提供了一些核心模块的不同版本,安装在
C:\program files\powershell\7\Modules
中。一些第三方模块也可能有与 PowerShell 7 兼容的特定版本,可以在 PowerShell 画廊中使用搜索词
Tags:"core"
来查找。
-
强制加载
:可以使用
Import-Module
的
-SkipEditionCheck
参数来尝试强制加载不兼容的模块,但这种方法可能会导致模块加载后无法正常工作。例如:
Import-Module RemoteDesktop -SkipEditionCheck
- 使用兼容模式 :在 PowerShell 7 的最新版本中,使用兼容模式很简单。只需导入所需的模块,PowerShell 会自动检查是否有兼容的模块,如果没有则会在后台创建一个远程会话来运行 Windows PowerShell。例如:
Import-Module RemoteDesktop
使用兼容模式时,需要注意以下两点:
-
运行的 PowerShell 版本
:创建的
WinPSCompatSession
会话运行的是 Windows PowerShell 5.1,而不是 PowerShell 7。可以通过以下命令验证:
$session = Get-PSSession -Name WinPSCompatSession
Invoke-Command -Session $session -ScriptBlock { $PSVersionTable.PSVersion }
-
反序列化对象
:由于这是一个远程会话,输出的对象会被反序列化,其方法和属性会有所不同。为了避免意外加载模块进入兼容模式,可以编辑
powershell.config.json文件,添加"DisableImplicitWinCompat": "true"来防止隐式导入。也可以通过添加Import-Module命令的-UseWindowsPowerShell参数来显式使用兼容模式。同时,可以编辑powershell.config.json文件中的拒绝列表,防止特定模块在兼容模式下加载。
3. 哪些功能在 PowerShell 7 中无法使用
-
-ComputerName 参数
:该参数已从 Windows PowerShell 移植到 PowerShell 7,但由于 Windows 中该参数使用的一些协议和模型与 PowerShell 7 不兼容,在最新版本的 PowerShell 7 中,该参数已从无法正常工作的 cmdlet 中移除。可以使用
Invoke-Command作为替代。 -
某些管理模块
:如用于管理 Windows Server Update Services (WSUS) 的
UpdateServices模块,由于依赖于通过其方法返回的对象进行操作,而这些对象在反序列化过程中无法保留其功能,因此在兼容模式下无法正常工作。 -
Windows Management Instrumentation (WMI) 命令
:自 PowerShell 3.0 起,微软就试图弃用 WMI 命令,推荐使用更轻量级的 CIM 命令。虽然 WMI 命令仍然很受欢迎,但 PowerShell 7 中不包含这些命令。不过,可以通过一些变通方法,如使用
Invoke-Command在兼容模式下使用 WMI 命令。
4. 使用 CIM 和 WMI 管理机器
CIM(Common Information Model)和 WMI(Windows Management Instrumentation)是用于管理本地和远程机器的相关技术。
4.1 CIM 和 WMI 简介
CIM 和 WMI 基于 1996 年分布式管理任务组 (DMTF) 引入的基于 Web 的企业管理 (WBEM) 标准。WMI 是微软在 1998 年基于 WBEM 实现的一组工具,而 CIM 是 DMTF 在 1999 年发布的开放标准,定义了环境中实体的表示和关联方式。
在 Windows 环境中,CIM 使用 WMI 的元素,但使用不同的协议进行访问。WMI 使用分布式公共对象模型 (DCOM) 协议,而 CIM 使用基于 HTTP 的 Web 服务管理 (WS-MAN) 协议。两者都连接到一个公共的存储库,即 WMI 存储库,该存储库包含了我们可能想要管理的对象类型和实例的信息。
4.2 为什么 CIM 比 WMI 更好
CIM 相对较新,并且使用开放的连接协议 WS-MAN,这需要机器和网络中的任何设备上有一对静态网络端口可用。而 DCOM 使用远程过程调用 (RPC) 协议,严重依赖临时的 TCP/IP 端口。由于这个差异,在网络上运行 WS-MAN 比运行 DCOM 更容易。
自 2012 年 PowerShell 3.0 起,微软就试图弃用 WMI cmdlet,鼓励人们使用 CIM cmdlet,因为 CIM 使用更轻量级的协议,网络占用更小。尽管如此,仍有很多人使用 WMI cmdlet,并且互联网上有许多使用它们的流行脚本。
4.3 使用 CIM 和 WMI 的命令
WMI 存储库非常庞大且复杂,因此在可能的情况下,最好使用专门的 cmdlet 而不是 CIM 或 WMI cmdlet。例如,要查询机器上的打印机,可以使用
Get-CimInstance Win32_Printer
命令,但使用
Get-Printer
命令更快、更直观:
Get-CimInstance Win32_Printer | Where-Object { $_.Name -like "*HP*" }
Get-Printer | Where-Object { $_.Name -like "*HP*" }
Get-Printer
支持
-ComputerName
参数用于远程机器,甚至支持使用 CIM 会话。在花费大量时间研究如何使用 CIM cmdlet 完成某项任务之前,最好先检查是否已经有现成的 cmdlet 可以满足需求。
4.4 WMI 存储库
WMI 存储库是一个分层数据库,呈树状结构。顶层是命名空间,命名空间包含类,类表示对象类型,如打印机,并包含该类型对象的实例。每个类的实例具有相同的属性和方法集,但可能并非所有属性都被填充或启用。有一个名为
__NAMESPACE
的类,它包含命名空间,因此一个命名空间可能包含其他命名空间。
根命名空间称为
root
,可以使用以下命令查看其内容:
Get-CimClass -Namespace 'Root' | Select-Object -First 10
可以使用以下命令查看
__NAMESPACE
类的实例:
Get-CimInstance -Namespace 'Root' -ClassName __NAMESPACE
命名空间和类的内容可能因每台机器而异,因为硬件和软件在安装时会创建自己的命名空间和类。对于大多数人来说,重要的命名空间是
root/CIMV2
,它包含了 Microsoft Windows 类。PowerShell 默认将 CIMV2 命名空间设置为默认命名空间,因此在使用 CIM 命令时通常不需要指定命名空间。
以下是使用 CIM 和 WMI 管理机器的流程 mermaid 图:
graph LR
A[开始] --> B[选择管理方式]
B --> C{CIM 还是 WMI}
C -->|CIM| D[使用 CIM 命令连接]
C -->|WMI| E[使用 WMI 命令连接]
D --> F[查询或操作对象]
E --> F
F --> G[结束]
综上所述,在 Windows 上使用 PowerShell 7 时,需要了解其与 Windows PowerShell 的差异,以及如何处理模块兼容性问题。同时,掌握 CIM 和 WMI 的使用方法可以帮助我们更好地管理本地和远程机器。
在 Windows 上使用 PowerShell 7 的全面指南
5. 兼容性模式的深入探讨
兼容性模式为在 PowerShell 7 中使用 Windows PowerShell 模块提供了便利,但也带来了一些需要注意的细节。
5.1 兼容性模式的性能影响
由于兼容性模式会在后台创建一个远程会话来运行 Windows PowerShell,这会带来一定的性能开销。每次在兼容性模式下调用模块中的命令时,都需要通过远程会话进行交互,这可能会导致命令执行速度变慢。特别是在处理大量数据或频繁调用命令时,性能影响会更加明显。
例如,当使用
Get-WmiObject
命令在兼容性模式下查询大量系统信息时,由于数据需要在远程会话和本地会话之间传输和反序列化,会消耗更多的时间和系统资源。
5.2 兼容性模式下的错误处理
在兼容性模式下,错误处理可能会变得更加复杂。由于命令是在远程会话中执行的,错误信息可能会以不同的格式返回,并且可能需要额外的步骤来解析和处理这些错误。
例如,如果在兼容性模式下加载一个不兼容的模块,可能会收到一个来自远程会话的错误信息,这个信息可能包含一些与本地会话不同的上下文信息。在处理这种错误时,需要仔细分析错误信息,确定是模块本身的问题还是兼容性模式的问题。
5.3 兼容性模式的安全考虑
兼容性模式涉及到在本地机器上创建一个远程会话来运行 Windows PowerShell,这可能会带来一些安全风险。如果没有正确配置远程会话的安全设置,可能会导致敏感信息泄露或被恶意利用。
例如,如果在兼容性模式下使用的模块需要访问敏感的系统资源或执行特权操作,需要确保远程会话具有足够的权限,并且采取适当的安全措施来保护这些操作。
6. CIM 和 WMI 的高级应用
除了基本的查询和管理功能,CIM 和 WMI 还可以用于一些高级应用场景。
6.1 批量管理多台机器
可以使用 CIM 和 WMI 对多台机器进行批量管理。通过创建 CIM 会话或使用
-ComputerName
参数(在支持的情况下),可以同时对多台远程机器执行相同的操作。
例如,要批量查询多台机器上的打印机信息,可以使用以下脚本:
$computers = "Computer1", "Computer2", "Computer3"
foreach ($computer in $computers) {
Get-CimInstance -ComputerName $computer -ClassName Win32_Printer
}
6.2 自动化任务调度
CIM 和 WMI 可以与 Windows 的任务调度器结合使用,实现自动化任务调度。可以使用 CIM 命令创建、修改和删除任务调度器中的任务。
例如,要创建一个每天定时执行的任务,可以使用以下脚本:
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-Command 'Get-Process | Out-File C:\Temp\Processes.txt'"
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask -TaskName "DailyProcessReport" -InputObject $task
6.3 事件监控
CIM 和 WMI 可以用于监控系统事件。通过订阅 WMI 事件,可以在特定事件发生时触发相应的操作。
例如,要监控系统中进程的创建事件,可以使用以下脚本:
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'"
Register-WmiEvent -Query $query -Action {
$event = $Event.SourceEventArgs.NewEvent
Write-Host "New process created: $($event.TargetInstance.Name)"
}
7. 总结与最佳实践
在 Windows 上使用 PowerShell 7 时,为了更好地发挥其功能并避免潜在的问题,以下是一些总结和最佳实践:
7.1 模块兼容性处理
-
在使用新模块之前,先检查其兼容性。可以使用
Get-Module | Format-Table -Auto -Wrap Name, CompatiblePSEditions, Version命令查看模块的兼容性信息。 - 优先使用与 PowerShell 7 兼容的模块版本。如果找不到兼容版本,可以尝试寻找替代模块或使用兼容性模式。
- 对于不兼容的模块,尽量避免强制加载,而是优先考虑使用兼容性模式。在使用兼容性模式时,要注意其性能影响和对象反序列化的问题。
7.2 CIM 和 WMI 的使用
-
尽量使用专门的 cmdlet 而不是直接使用 CIM 或 WMI cmdlet。例如,使用
Get-Printer而不是Get-CimInstance Win32_Printer。 - 了解 CIM 和 WMI 的区别,优先使用 CIM 命令,因为其使用更轻量级的协议,网络占用更小。
- 在使用 CIM 和 WMI 进行批量管理或自动化任务时,要注意性能和安全问题,合理配置参数和权限。
7.3 兼容性模式的使用
- 在使用兼容性模式时,要明确其运行的是 Windows PowerShell 5.1,并且返回的对象是反序列化的。
-
可以通过编辑
powershell.config.json文件来控制兼容性模式的行为,如防止隐式导入和禁止特定模块加载。 - 定期检查 PowerShell 7 的更新,随着版本的更新,兼容性问题可能会得到改善。
以下是一个总结的表格,展示了在不同情况下的最佳选择:
| 情况 | 最佳选择 |
| ---- | ---- |
| 模块兼容 | 使用兼容版本的模块 |
| 模块不兼容 | 寻找替代模块或使用兼容性模式 |
| 管理机器 | 优先使用 CIM 命令,必要时使用 WMI 命令 |
| 性能要求高 | 避免使用兼容性模式,优化 CIM 或 WMI 查询 |
| 安全要求高 | 正确配置远程会话和权限,避免敏感信息泄露 |
通过遵循这些最佳实践,可以在 Windows 上更高效、安全地使用 PowerShell 7,充分发挥其强大的管理和自动化功能。
graph LR
A[使用 PowerShell 7] --> B{模块是否兼容}
B -->|是| C[使用兼容模块]
B -->|否| D{寻找替代模块}
D -->|有| E[使用替代模块]
D -->|无| F[使用兼容性模式]
G[管理机器] --> H{使用 CIM 还是 WMI}
H -->|CIM| I[使用 CIM 命令]
H -->|WMI| J[使用 WMI 命令]
K[性能要求高] --> L[优化查询或避免兼容性模式]
M[安全要求高] --> N[配置安全设置]
总之,在 Windows 环境中使用 PowerShell 7 时,需要综合考虑各种因素,灵活运用不同的技术和方法,以实现高效、稳定和安全的系统管理。
超级会员免费看
744

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



