PowerShell 技能连载 - 利用 WMI(第 2 部分)

查询 WMI 类时,一开始可能无法取回所有信息:

1
2
3
4
5
6
PS> Get-CimInstance -ClassName Win32_LogicalDisk

DeviceID DriveType ProviderName VolumeName Size FreeSpace
-------- --------- ------------ ---------- ---- ---------
C: 3 OS 1007210721280 227106992128
Z: 4 \\127.0.0.1\c$ OS 1007210721280 227106988032

确保加上 Select-Object 以获得完整的信息集:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
PS> Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object -Property *


Status :
Availability :
DeviceID : C:
StatusInfo :
Caption : C:
Description : Local Fixed Disk
InstallDate :
Name : C:
ConfigManagerErrorCode :
ConfigManagerUserConfig :
CreationClassName : Win32_LogicalDisk
ErrorCleared :
ErrorDescription :
LastErrorCode :
PNPDeviceID :
PowerManagementCapabilities :
PowerManagementSupported :
SystemCreationClassName : Win32_ComputerSystem
SystemName : DELL7390
Access : 0
BlockSize :
ErrorMethodology :
NumberOfBlocks :
Purpose :
FreeSpace : 227111596032
Size : 1007210721280
Compressed : False
DriveType : 3
FileSystem : NTFS
MaximumComponentLength : 255
MediaType : 12
ProviderName :
QuotasDisabled :
QuotasIncomplete :
QuotasRebuilding :
SupportsDiskQuotas : False
SupportsFileBasedCompression : True
VolumeDirty :
VolumeName : OS
VolumeSerialNumber : DAD43A43
PSComputerName :
CimClass : root/cimv2:Win32_LogicalDisk
CimInstanceProperties : {Caption, Description, InstallDate, Name...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

Status :
Availability :
DeviceID : Z:
StatusInfo :
Caption : Z:
Description : Network Connection
InstallDate :
Name : Z:
ConfigManagerErrorCode :
ConfigManagerUserConfig :
CreationClassName : Win32_LogicalDisk
ErrorCleared :
ErrorDescription :
LastErrorCode :
PNPDeviceID :
PowerManagementCapabilities :
PowerManagementSupported :
SystemCreationClassName : Win32_ComputerSystem
SystemName : DELL7390
Access : 0
BlockSize :
ErrorMethodology :
NumberOfBlocks :
Purpose :
FreeSpace : 227111596032
Size : 1007210721280
Compressed : False
DriveType : 4
FileSystem : NTFS
MaximumComponentLength : 255
MediaType : 0
ProviderName : \\127.0.0.1\c$
QuotasDisabled :
QuotasIncomplete :
QuotasRebuilding :
SupportsDiskQuotas : False
SupportsFileBasedCompression : True
VolumeDirty :
VolumeName : OS
VolumeSerialNumber : DAD43A43
PSComputerName :
CimClass : root/cimv2:Win32_LogicalDisk
CimInstanceProperties : {Caption, Description, InstallDate, Name...}
CimSystemProperties : Microsoft.Management.Infrastructure.CimSystemProperties

现在您看到了所有属性,并且可以选择真正需要的项目:

1
2
3
4
5
6
PS> Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object -Property DeviceId, Description, FreeSpace, FileSystem

DeviceId Description FreeSpace FileSystem
-------- ----------- --------- ----------
C: Local Fixed Disk 227110989824 NTFS
Z: Network Connection 227110989824 NTFS

PowerShell 技能连载 - 利用 WMI(第 1 部分)

WMI 是一种用于查询计算机详细信息的 Windows 技术。如果您仍在使用已弃用的 Get-WmiObject cmdlet,则应重新考虑:

1
2
3
4
5
6
7
PS> Get-WmiObject -Class Win32_BIOS

SMBIOSBIOSVersion : 1.9.1
Manufacturer : Dell Inc.
Name : 1.9.1
SerialNumber : 4ZKM0Z2
Version : DELL - 20170001

切换到新的 Get-CimInstance cmdlet,它的工作原理非常相似:

1
2
3
4
5
6
7
PS> Get-CimInstance -ClassName Win32_BIOS

SMBIOSBIOSVersion : 1.9.1
Manufacturer : Dell Inc.
Name : 1.9.1
SerialNumber : 4ZKM0Z2
Version : DELL - 20170001

Get-CimInstance 的众多优点之一是它的 IntelliSense 支持:要找出可用的类名,只需按 TAB 或(在 ISE 或 VSCode 等图形编辑器中)按 CTRL+空格:

1
PS> Get-CimInstance -ClassName Win32_\# <-press CTRL+SPACE with the cursor after "_"

最开始可能需要重复按几次按键,因为生成 IntelliSense 列表可能需要几秒钟,因此在您第一次按键时,IntelliSense 可能会超时。

Get-CimInstance 相对于 Get-WmiObject 的另一个优势是 Get-CimInstance 在 PowerShell 7 中也可用。 WMI 是一种基于 Windows 的技术。不要期望在 Linux 机器上找到 WMI 类。

PowerShell 技能连载 - More Control with Strict Mode

有时,PowerShell 可能会出现意外行为。例如,当您输入一个不带引号的 IPv4 地址时,PowerShell 能够正常地接受它,但什么也不做。为什么?

1
PS> 1.2.3.4

在这种情况下,激活“严格模式”可能会有好处,当出现问题时会发出更严格的异常:

1
2
3
4
5
PS> Set-StrictMode -Version Latest

PS> 1.2.3.4
The property '3.4' cannot be found on this object. Verify that the property exists.
At line:1 char:1

启用严格模式后,PowerShell 会这样解释输入“1.2.3.4”:获取到浮点数 1.2,然后查询其中的 “3” 属性和其中的 “4” 属性。当然,这些属性是不存在的。禁用严格模式后,PowerShell 不会抱怨不存在的属性,只会返回“什么也没有”。这就是所发生的事情。

启用严格模式还有助于识别代码中的拼写错误。只需确保您在脚本开发机器上专门启用严格模式即可。永远不要将它添加到生产代码中。严格模式只是脚本开发人员的帮手。一旦脚本完成并移交给其他用户,请不要将开发工具留在其中。

Set-StrictMode 永远不应该放在您的代码中(并且始终以交互方式输入或作为配置文件脚本的一部分)的原因很简单:其他 PowerShell 脚本开发人员可能故意选择依赖松散的异常,并且当您的脚本强制严格模式,它也适用于从那里使用的所有代码(和模块)。在生产中启用严格模式可能会使运行良好的代码突然产生过多的红色异常。

PowerShell 技能连载 - 管理 Wi-Fi 配置文件

在Windows上,你可以使用旧的控制台命令来发现Wi-Fi配置文件:

1
PS> netsh wlan show profiles

从这里开始,您甚至可以查看个人配置文件的详细信息,并获得高速缓存的明文密码。然而,所有这些都是基于控制台的,所以它不是面向对象的,需要大量的字符串操作,当概要文件使用特殊字符或您的计算机使用不同的区域设置时,可能会返回意外的信息。

一个更好的方法是使用本地Windows API。在PowerShell图库上有一个可以使用的公共模块。这样安装:

1
PS> Install-Module -Name WifiProfileManagement -Scope CurrentUser

其余的都是微不足道的。要转储所有保存的Wi-Fi配置文件(包括名称中有特殊字符的文件),请使用Get-WiFiProfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS C:\> Get-WiFiProfile

ProfileName ConnectionMode Authentication Encryption Password
----------- -------------- -------------- ---------- --------
HOTSPLOTS_WR_Muehlenberg manual open none
Zudar06_Gast auto WPA2PSK AES
management auto WPA3SAE AES
MagentaWLAN-X5HZ auto WPA3SAE AES
Alando-Whg.17 auto WPA2PSK AES
internet-cafe auto WPA2PSK AES
Training manual WPA2PSK AES
QSC-Guest auto open none
ibisbudget manual open none
Leonardo auto open none
ROOMZ-GUEST auto open none
Freewave auto open none
PS Saturday auto WPA2PSK AES
WIFIonICE manual open none
Airport Hotel auto WPA2PSK AES

并且,要查看缓存的Wi-Fi密码,只需添加-ClearKey参数。高速缓存的密码现在将以明文形式出现在“密码”列中。

如果您有兴趣直接在您自己的代码中使用此功能,只需查看模块中的源代码即可。它是高度复杂的,但本地的电源外壳。任何正在寻找直接与Wi-Fi子系统对话的原生API方式的人都应该深入研究这些代码。

PowerShell 技能连载 - Automating User Confirmation

Some commands seem to require user input no matter what. While you can try parameters such as -Confirm:$false to get rid of default confirmations, some commands either do not support that parameter, or show their very own user requests. Here is an example:

PS> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

When you run this command (elevated) on Windows 10 or 11, at the end of the process the cmdlet wants to know whether a restart is OK:

Do you want to restart the computer to complete this operation now?
[Y] Yes  [N] No  [?] Help (default is "Y"):

The cmdlet halts until the user either enters “Y” or “N”.

To fully automate cmdlets like this, either take a closer look at its remaining parameters. Often, there are ways to articulate your choice and leave no room for ambiguities that need manual resolution. In the example above, by adding “-NoRestart”, you could deny automatic restarts and then explicitly restart the machine using Restart-Computer.

Or, you can pipe user input to a new PowerShell instance. PowerShell takes the input and places it into the keyboard input buffer. Whenever a command requests user input, it is taken from this buffer. Use comma-separated values to submit multiple items of user input to PowerShell.

Here is an example illustrating how you can submit a “N” to the command above:

PS> "N" | powershell.exe -noprofile -command Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

PowerShell 技能连载 - Using Predictive IntelliSense

Predictive IntelliSense is a new feature in PSReadLine 2.1 and was improved in version 2.2. As such, it is available in all PowerShell consoles starting in PowerShell version 5.1. If you are uncertain whether your PowerShell console is using the latest version of PSReadLine, try this:

PS> Update-Module -Name PSReadLine

If you can’t update the module because it shipped with Windows, or you are missing privileges, try and freshly install it like so:

PS> Install-Module -Name PSReadLine -Scope CurrentUser -Force

Next, restart you PowerShell console.

The reason why you may not have heard anything about “predictive IntelliSense” is that it is turned off by default. To turn it on, run this:

PS> Set-PSReadLineOption -PredictionSource HistoryAndPlugin

In Windows PowerShell, you are limited to the option “History” only:

PS> Set-PSReadLineOption -PredictionSource History

Immediately thereafter, when you type commands in your console, you start seeing shadowed (darker) IntelliSense suggestions while you type. These suggestions are taken primarily from your command history so PowerShell starts suggesting command parameters that you commonly use. The auto-suggestion is an individualized experience, and the actual suggestions depend on your previous PowerShell commands:

PS> Get-Service | import-database -Database $db

If you don’t like this “real-time” IntelliSense, turn it off again like so:

PS> Set-PSReadLineOption -PredictionSource None

PowerShell 技能连载 - Update PowerShell’s PSReadLine

Do you know the PSReadLine module? It’s included in PowerShell 5 and 7 by default, and this module is responsible for the convenient color coding in PowerShell consoles, among a number of additional benefits that makes handling code easier. PowerShell loads this module by default in console-based environments (it’s not being used in the PowerShell ISE).

To check the current version, run this:

PS> try { (Get-Module -Name PSReadLine).Version.ToString() } catch { Write-Warning 'PSReadLine not used in this host' }
2.1.0

The line either returns the current PSReadLine version used by your PowerShell host, or emits a warning that PSReadline isn’t used by your host (i.e. inside the PowerShell ISE host which takes care of color coding internally).

You should make sure you are using the latest version of PSReadline. This line would try and update it to the latest version:

PS> Update-Module -Name PSReadLine

Just in case you can’t update the module because it shipped with Windows, try and freshly install it like so:

PS> Install-Module -Name PSReadLine -Scope CurrentUser -Force

Make sure you relaunch PowerShell after you have updated PSReadLine to load the latest version.

PSReadLine comes with powerful new features such as “predictive IntelliSense” and dynamic help that are explained here: https://devblogs.microsoft.com/powershell/psreadline-2-2-ga/

ReTweet this Tip!

PowerShell 博客文章汇总 (2021-04 ~ 2022-03)

2021 年 04 月

2021 年 05 月

2021 年 06 月

2021 年 07 月

2021 年 08 月

2021 年 09 月

2021 年 10 月

2021 年 11 月

2021 年 12 月

2022 年

2022 年 01 月

2022 年 02 月

2022 年 03 月

PowerShell 技术互动社区发展状况(2022 年 3 月)

至 2022 年 3 月,“PowerShell 技术互动”社区人数已达到 1998 人,十分接近社区最大容量(2000 人),保持 PowerShell 最大中文社区的位置。根据腾讯社交平台的策略,社区人数的上限为 2000 人,我们会尽可能保留机会给活跃用户。

QQ Group

如您遇到 PowerShell 方面的技术问题,或有好的资源希望分享,请加入我们。QQ 群号:271143343

或者用手机 QQ 扫描二维码:

QR