PowerShell 技能连载 - 管理蓝牙设备(第 2 部分)

如果您只是在 Windows 中寻找一种快速的方法来配对和接触配对蓝牙设备,请尝试以下命令:

1
PS> explorer.exe ms-settings-connectabledevices:devicediscovery

这将立即弹出一个对话框,显示所有蓝牙设备。只需在 PowerShell 中添加一个函数,因此您不必记住命令,只需要将其放入个人资料脚本中:

1
2
3
PS> function Show-Bluetooth { explorer.exe ms-settings-connectabledevices:devicediscovery }

PS> Show-Bluetooth

如果您想在桌面放一个蓝牙图标的快捷方式,请尝试以下操作:

1
2
3
4
5
6
7
8
$desktop = [Environment]::GetFolderPath('Desktop')
$path = Join-Path -Path $desktop -ChildPath 'bluetooth.lnk'
$shell = New-Object -ComObject WScript.Shell
$scut = $shell.CreateShortcut($path)
$scut.TargetPath = 'explorer.exe'
$scut.Arguments = 'ms-settings-connectabledevices:devicediscovery'
$scut.IconLocation = 'fsquirt.exe,0'
$scut.Save()

PowerShell 技能连载 - 管理蓝牙设备(第 1 部分)

列出计算机已连接的蓝牙设备只需要一行代码:

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
PS> Get-PnpDevice -Class Bluetooth

Status Class FriendlyName InstanceId
------ ----- ------------ ----------
OK Bluetooth Bose QC35 II Avrcp Transport BTHENUM\{0000110C-00...
OK Bluetooth Generic Attribute Profile BTHLEDEVICE\{0000180...
OK Bluetooth Generic Access Profile BTHLEDEVICE\{0000180...
OK Bluetooth Generic Attribute Profile BTHLEDEVICE\{0000180...
OK Bluetooth Bamboo Ink Plus BTHLE\DEV_006FF2E608...
OK Bluetooth Bose QC35 II Avrcp Transport BTHENUM\{0000110E-00...
OK Bluetooth Generic Attribute Profile BTHLEDEVICE\{0000180...
OK Bluetooth SMA001d SN: 2110109033 SN2110109033 BTHENUM\DEV_0080251B...
OK Bluetooth MX Master 3 BTHLE\DEV_D304DEE615...
OK Bluetooth Bluetooth LE Generic Attribute Service BTHLEDEVICE\{0000FE5...
OK Bluetooth Microsoft Bluetooth LE Enumerator BTH\MS_BTHLE\6&1B2C8...
OK Bluetooth Device Information Service BTHLEDEVICE\{0000180...
OK Bluetooth Bluetooth LE Generic Attribute Service BTHLEDEVICE\{0000180...
OK Bluetooth Device Information Service BTHLEDEVICE\{0000180...
OK Bluetooth Generic Access Profile BTHLEDEVICE\{0000180...
OK Bluetooth Bluetooth LE Generic Attribute Service BTHLEDEVICE\{0001000...
OK Bluetooth Bluetooth LE Generic Attribute Service BTHLEDEVICE\{0000180...
OK Bluetooth MX Keys BTHLE\DEV_D9FDB81EAB...
OK Bluetooth Device Information Service BTHLEDEVICE\{0000180...
OK Bluetooth Microsoft Bluetooth Enumerator BTH\MS_BTHBRB\6&1B2C...
OK Bluetooth Generic Access Profile BTHLEDEVICE\{0000180...
OK Bluetooth Bluetooth LE Generic Attribute Service BTHLEDEVICE\{0001000...
OK Bluetooth Intel(R) Wireless Bluetooth(R) USB\VID_8087&PID_002...
OK Bluetooth Bluetooth Device (RFCOMM Protocol TDI) BTH\MS_RFCOMM\6&1B2C...
OK Bluetooth Bluetooth LE Generic Attribute Service BTHLEDEVICE\{0000180...
OK Bluetooth Bose QC35 II BTHENUM\DEV_2811A579...

要根据名称搜索特定的蓝牙设备,请尝试下面一行代码。它会查找名称中带有 “Bose” 的所有设备:

1
2
3
4
5
6
7
PS> Get-PnpDevice -Class Bluetooth -FriendlyName *Bose*

Status Class FriendlyName
------ ----- ------------
OK Bluetooth Bose QC35 II Avrcp Transport
OK Bluetooth Bose QC35 II Avrcp Transport
OK Bluetooth Bose QC35 II

通过添加 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
PS> Get-PnpDevice -Class Bluetooth  |
Select-Object -Property Caption, Manufacturer, Service

Caption Manufacturer Service
------- ------------ -------
Bose QC35 II Avrcp Transport Microsoft Microsoft_Bluetooth_AvrcpTransport
Generic Attribute Profile Microsoft UmPass
Generic Access Profile Microsoft UmPass
Generic Attribute Profile Microsoft UmPass
Bamboo Ink Plus Microsoft BthLEEnum
Bose QC35 II Avrcp Transport Microsoft Microsoft_Bluetooth_AvrcpTransport
Generic Attribute Profile Microsoft UmPass
SMA001d SN: 2110109033 SN2110109033 Microsoft
MX Master 3 Microsoft BthLEEnum
Bluetooth LE Generic Attribute Service Microsoft UmPass
Microsoft Bluetooth LE Enumerator Microsoft BthLEEnum
Device Information Service Microsoft UmPass
Bluetooth LE Generic Attribute Service Microsoft UmPass
Device Information Service Microsoft UmPass
Generic Access Profile Microsoft UmPass
Bluetooth LE Generic Attribute Service Microsoft UmPass
Bluetooth LE Generic Attribute Service Microsoft UmPass
MX Keys Microsoft BthLEEnum
Device Information Service Microsoft UmPass
Microsoft Bluetooth Enumerator Microsoft BthEnum
Generic Access Profile Microsoft UmPass
Bluetooth LE Generic Attribute Service Microsoft UmPass
Intel(R) Wireless Bluetooth(R) Intel Corporation BTHUSB
Bluetooth Device (RFCOMM Protocol TDI) Microsoft RFCOMM
Bluetooth LE Generic Attribute Service Microsoft UmPass
Bose QC35 II Microsoft

当您使用名词 “PnPDevice” 搜索其他 cmdlet 时,还可以发现启用或禁用的命令:

1
2
3
4
5
6
7
PS> Get-Command -Noun PnPDevice

CommandType Name Version Source
----------- ---- ------- ------
Function Disable-PnpDevice 1.0.0.0 PnpDevice
Function Enable-PnpDevice 1.0.0.0 PnpDevice
Function Get-PnpDevice 1.0.0.0 PnpDevice

要了解如何确定当前连接状态并完全删除蓝牙设备,请参阅我们的下一个提示。

PowerShell 技能连载 - 2022 年的 PowerShell 计划

Microsoft PowerShell 团队刚刚发布了 2022 年的计划和投资:https://devblogs.microsoft.com/powershell/powershell-and-openssh-team-investments-for-2022/

简而言之,这些投资围绕着更高的安全性。此外,自定义远程连接可能会成为一个有趣的补充:您为访问远程系统而编写的代码随后可以被其他 cmdlet 使用,实质上形成了一个远程基础架构。

此外,该团队希望让现有的 Windows PowerShell 用户更容易获得 PowerShell 7。我们可能会在 2022 年看到 Windows PowerShell 多年来的第一次更新:团队讨论向 Windows PowerShell 添加一个新的 cmdlet,以在其上安装 PowerShell 7。

为了让 IntelliSense 更加智能,该团队已经引入了 “CompleterPredictors”,它可以“猜测”你将要输入的内容。虽然这些最初仅限于 Azure cmdlet,但该技术现在将向任何开发人员广泛开放。

通过添加为每个模块单独加载 .NET 程序集的方法,模块将变得更加健壮。目前,当一个模块加载具有给定版本的 .NET 程序集,而另一个模块需要不同版本的相同 .NET 程序集时,任何时候都只能加载一个版本,从而导致失败。

PowerShell 的内部包管理系统 PowerShellGet 将升级到 3.0 版,该版本之前仅作为预览版提供。它解决了从 powershellgallery.com 等存储库上传和安装模块的常见功能请求。

团队在 2022 年将关注更多感兴趣的领域,即适用于 Windows 的 OpenSSH。在此处阅读完整的声明:https://devblogs.microsoft.com/powershell/powershell-and-openssh-team-investments-for-2022/

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

WMI 类被组织在所谓的命名空间中,这些命名空间从“根”开始并像目录结构一样工作。默认命名空间是 root\cimv2,当不指定命名空间时,你只能看到位于默认命名空间中的 WMI 类。这是我们在本系列的过去部分中一直使用的。

还有更多带有许多附加 WMI 类的命名空间,其中一些非常有用。在我们探索 WMI 的这一部分之前,请注意,您将进入 Windows 的文档稀少的区域,这些区域不一定适用于一般受众。您可能需要 google,此处找到的类可能仅适用于特定的 Windows 操作系统和/或许可证类型。

要获取计算机上可用的 WMI 命名空间列表,请运行以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# create a new queue
$namespaces = [System.Collections.Queue]::new()

# add an initial namespace to the queue
# any namespace in the queue will later be processed
$namespaces.Enqueue('root')

# process all elements on the queue until all are taken
While ($namespaces.Count -gt 0 -and ($current = $namespaces.Dequeue()))
{
# find child namespaces
Get-CimInstance -Namespace $current -ClassName __Namespace -ErrorAction Ignore |
# ignore localization namespaces
Where-Object Name -NotMatch '^ms_\d{2}' |
ForEach-Object {
# construct the full namespace name
$childnamespace = '{0}\{1}' -f $current, $_.Name
# add namespace to queue
$namespaces.Enqueue($childnamespace)
}

# output current namespace
$current
}

代码可能会运行一段时间,所以请喝杯咖啡。结果是您机器上可用的命名空间列表,可能类似于以下内容:

root
root\subscription
root\DEFAULT
root\CIMV2
root\msdtc
root\Cli
root\Intel_ME
root\SECURITY
root\HyperVCluster
root\SecurityCenter2
root\RSOP
root\PEH
root\StandardCimv2
root\WMI
root\MSPS
root\directory
root\Policy
root\virtualization
root\Interop
root\Hardware
root\ServiceModel
root\SecurityCenter
root\Microsoft
root\Appv
root\dcim
root\CIMV2\mdm
root\CIMV2\Security
root\CIMV2\power
root\CIMV2\TerminalServices
root\HyperVCluster\v2
root\RSOP\User
root\RSOP\Computer
root\StandardCimv2\embedded
root\directory\LDAP
root\virtualization\v2
root\Microsoft\HomeNet
root\Microsoft\protectionManagement
root\Microsoft\Windows
root\Microsoft\SecurityClient
root\Microsoft\Uev
root\dcim\sysman
root\CIMV2\mdm\dmmap
root\CIMV2\Security\MicrosoftTpm
root\CIMV2\Security\MicrosoftVolumeEncryption
root\Microsoft\Windows\RemoteAccess
root\Microsoft\Windows\Dns
root\Microsoft\Windows\Powershellv3
root\Microsoft\Windows\Hgs
root\Microsoft\Windows\WindowsUpdate
root\Microsoft\Windows\DeviceGuard
root\Microsoft\Windows\TaskScheduler
root\Microsoft\Windows\DesiredStateConfigurationProxy
root\Microsoft\Windows\SmbWitness
root\Microsoft\Windows\Wdac
root\Microsoft\Windows\StorageReplica
root\Microsoft\Windows\winrm
root\Microsoft\Windows\AppBackgroundTask
root\Microsoft\Windows\DHCP
root\Microsoft\Windows\PS_MMAgent
root\Microsoft\Windows\Storage
root\Microsoft\Windows\HardwareManagement
root\Microsoft\Windows\SMB
root\Microsoft\Windows\EventTracingManagement
root\Microsoft\Windows\DesiredStateConfiguration
root\Microsoft\Windows\Attestation
root\Microsoft\Windows\CI
root\Microsoft\Windows\dfsn
root\Microsoft\Windows\DeliveryOptimization
root\Microsoft\Windows\Defender
root\dcim\sysman\biosattributes
root\dcim\sysman\wmisecurity
root\Microsoft\Windows\RemoteAccess\Client
root\Microsoft\Windows\Storage\PT
root\Microsoft\Windows\Storage\Providers_v2
root\Microsoft\Windows\Storage\PT\Alt

一旦您知道了命名空间的名称,就可以使用这个迷你系列的前面部分来查询位于给定命名空间中的 WMI 类名。例如,下面的代码列出了命名空间 “root\Microsoft\Windows\WindowsUpdate” 中的所有 WMI 类:

1
2
3
4
$ns = 'root\Microsoft\Windows\WindowsUpdate'
Get-CimClass -Namespace $ns |
Select-Object -ExpandProperty CimClassName |
Sort-Object

以双下划线开头的类名用于内部用途:

__AbsoluteTimerInstruction
__ACE
__AggregateEvent
__ClassCreationEvent
__ClassDeletionEvent
__ClassModificationEvent
__ClassOperationEvent
__ClassProviderRegistration
__ConsumerFailureEvent
__Event
__EventConsumer
__EventConsumerProviderRegistration
__EventDroppedEvent
__EventFilter
__EventGenerator
__EventProviderRegistration
__EventQueueOverflowEvent
__ExtendedStatus
__ExtrinsicEvent
__FilterToConsumerBinding
__IndicationRelated
__InstanceCreationEvent
__InstanceDeletionEvent
__InstanceModificationEvent
__InstanceOperationEvent
__InstanceProviderRegistration
__IntervalTimerInstruction
__MethodInvocationEvent
__MethodProviderRegistration
__NAMESPACE
__NamespaceCreationEvent
__NamespaceDeletionEvent
__NamespaceModificationEvent
__NamespaceOperationEvent
__NotifyStatus
__NTLMUser9X
__ObjectProviderRegistration
__PARAMETERS
__PropertyProviderRegistration
__Provider
__ProviderRegistration
__QOSFailureEvent
__SecurityDescriptor
__SecurityRelatedClass
__SystemClass
__SystemEvent
__SystemSecurity
__thisNAMESPACE
__TimerEvent
__TimerInstruction
__TimerNextFiring
__Trustee
__Win32Provider
CIM_ClassCreation
CIM_ClassDeletion
CIM_ClassIndication
CIM_ClassModification
CIM_Error
CIM_Indication
CIM_InstCreation
CIM_InstDeletion
CIM_InstIndication
CIM_InstModification
MSFT_ExtendedStatus
MSFT_WmiError
MSFT_WUOperations
MSFT_WUSettings
MSFT_WUUpdate

要查询此命名空间中的 MSFT_WUSettings 类(如果存在于您的机器上),请运行以下命令:

1
2
$ns = 'root\Microsoft\Windows\WindowsUpdate'
Get-CimInstance -ClassName MSFT_WUSettings -Namespace $ns

结果是一个异常,表明您在探索新的且文档稀少的内部 WMI 类时可能会感到意外。根据您的操作系统和许可证类型,可能支持也可能不支持操作。如果它们不受支持,您最终可能会遇到 “provider failure” 异常。

此外,某些 WMI 类(如此命名空间中的类)并非旨在包含属性和返回信息。相反,它们包含方法(命令),这个例子用于管理 Windows 更新:

1
2
3
$ns = 'root\Microsoft\Windows\WindowsUpdate'
Get-CimClass -Namespace $ns -ClassName 'MSFT_WUOperations' |
Select-Object -ExpandProperty CimClassMethods

结果显示了它的方法:

Name           ReturnType Parameters                              Qualifiers
----           ---------- ----------                              ----------
ScanForUpdates     UInt32 {SearchCriteria, Updates}               {implemented, static}
InstallUpdates     UInt32 {DownloadOnly, Updates, RebootRequired} {implemented, static}

这是 Windows Server 2019 机器的实际示例。该脚本远程访问服务器(并行)并使用本地 WMI 检查安全更新,然后安装它们:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# list of names of Windows Server 2019 machines to update:
$servers="Server2019-IIS","Server2019-AD"

$ns = "root/Microsoft/Windows/WindowsUpdate"
$class = "MSFT_WUOperations"

Invoke-Command -ComputerName $servers -ScriptBlock {
# find missing updates:
$arg = @{SearchCriteria="IsInstalled=0 AND AutoSelectOnWebSites=1"}
$r = Invoke-CimMethod -Namespace $ns -ClassName $class -MethodName ScanForUpdates -Arguments $arg

# install missing updates:
if ($r.Updates)
{
$arg = @{Updates=$r.Updates}
Invoke-CimMethod -Namespace $ns -ClassName $class -MethodName InstallUpdates -Arguments $arg
}
}

请注意,上面的代码在 Windows Server 2019 上有效,但在 Windows Server 2016 上失败(因为 WMI 类名略有变化)。如果你还想深入挖掘,我们强烈推荐 https://github.com/microsoft/MSLab/blob/master/Scenarios/Windows%20Update/readme.md 这是一组关于如何使用 WMI 管理 Windows 服务器上的 Windows 更新的丰富示例。

如果您对 WMI 感兴趣,请前往 https://powershell.one/wmi/commands 了解更多信息。

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

成功利用 WMI 的秘诀是知道代表您需求的类名。在上一个技能中,我们解释了如何使用 IntelliSense 向 Get-CimInstance 询问可用的类名。不过,您也可以以编程方式执行相同的操作。下面是转储默认命名空间 root\cimv2 的所有有效 WMI 类名称的代码:

1
Get-CimClass | Select-Object -ExpandProperty CimClassName | Sort-Object

要检查给定的类名是否真的代表您要查找的内容,请执行一下测试查询。例如,要获取 Win32_OperatingSystem 的所有实例,请运行以下命令:

1
2
3
4
5
PS> Get-CimInstance -ClassName Win32_OperatingSystem

SystemDirectory Organization BuildNumber RegisteredUser SerialNumber Version
--------------- ------------ ----------- -------------- ------------ -------
C:\WINDOWS\system32 psconf.eu 19042 Zumsel 12345-12345-12345-AAOEM 10.0.19042

一些 WMI 类名是显而易见的,但其他则不是。要查看在任何给定类名中找到的属性,请尝试以下操作:

1
2
3
4
5
6
Get-CimClass |
Select-Object -Property CimClassName, @{
N='Properties'
E={$_.CimClassProperties -join ','}
} |
Out-GridView -PassThru

结果是一个显示 WMI 类名称及其属性名称的网格视图窗口。现在您可以使用网格视图窗口顶部的文本框过滤器来过滤任何关键字。仅列出在 WMI 类名称或其属性之一中包含您的关键字的行。

选择您感兴趣的类,然后单击左下角的“确定”将信息输出到控制台。接下来,您可以使用 Get-CimInstance 来测试查询您找到的 WMI 类名称。

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

新的 Get-CimInstance cmdlet 允许您在本地查询 WMI,并且(有限)支持远程查询:您可以指定 -ComputerName 参数,但不能使用替代凭据。

这是因为 Get-CimInstance 使用单独的网络会话进行远程访问,这为您提供了更多选择。例如,一旦您建立了一个网络会话,您就可以将它用于多个查询。以下是远程查询 WMI 信息的方法——从建立网络会话开始:

1
2
3
4
5
6
7
8
9
10
11
# establish network session
$credential = Get-Credential -Message 'Your logon details'
$computername = '127.0.0.1' # one or more comma-separated IP addresses or computer names
# note that IP addresses only work with NTFS authentication.
# using computer names in AD is more secure (Kerberos)

$options = New-CimSessionOption -Protocol Wsman -UICulture en-us # optional
$session = New-CimSession -SessionOption $option -Credential $credential -ComputerName $computername

# output live session
$session

结果是一个或多个会话,每台指定计算机一个:

Id           : 1
Name         : CimSession1
InstanceId   : e7790bc5-6b0d-4920-a6b9-d7b9676aae74
ComputerName : 127.0.0.1
Protocol     : WSMAN

当您在 Active Directory 之外使用 IP 地址或计算机时,请确保您已在客户端计算机(而不是服务器)上启用了 NTFS 身份验证。以下代码激活 NTFS 身份验证并需要本地管理员权限:

1
PS> Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value * -Force

设置网络会话后,可以将其用于多个 WMI 查询:

1
2
Get-CimInstance -ClassName Win32_BIOS -CimSession $session
Get-CimInstance -ClassName Win32_StartupCommand -CimSession $session

完成后,永远不要忘记关闭网络会话,这样它就不会在服务器上驻留很长时间:

1
Remove-CimSession -CimSession $session

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方式的人都应该深入研究这些代码。