Powershell Item-属性 在使用 Get-ChildItem 存储到数组时未扩展
Powershell Item-Property not expanded when stored to an array with Get-ChildItem
编写符合 Posh 2.0 的脚本(要求),我需要使用注册表库获取服务的详细信息。
然而,当我使用确切的名称(并因此使用 -eq 或 -like)搜索特定服务时,结果不正确,而 -like 使用通配符,这按预期工作。我们该如何解释?
PS > [array]$services=Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "*OpenVpnService*" }
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
PS > [array]$services=Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -eq "OpenVpnService" }
PS > $services[0]
SKC VC Name Property
--- -- ---- --------
0 8
PS > "'$($services[0].PsChildName)'"
''
PS > [array]$services=Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "OpenVpnService" }
PS > $services[0]
SKC VC Name Property
--- -- ---- --------
0 8
PS > "'$($services[0].PsChildName)'"
''
更新: 因为我需要一台完全兼容 Posh 2.0 的机器,所以我有一个全新的虚拟机,安装了 Windows 7 SP1 Ultimate,没有任何更新。为什么没有任何更新?因为通过更新机器,我会得到更新的 .NET 版本和 Posh 补丁。我在完全最新的 Windows 10 机器上进行了测试,它运行得非常完美,只要不将输出存储到数组,Windows 7 测试机器也会成功。
在尝试调试情况并缩小问题范围几个小时后,我已经能够确定导致问题的原因。
数组 initialization/casting 失败。简单地包围 the array subexpression operator @( )
需要投射的内容就解决了这个问题。
最近的 PowerShell 版本(Windows 10 上的 5.1,未更新的 Windows 7 上的 PowerShell 2.0)似乎处理数组的方式发生了变化,尤其是 PowerShell 3.0介绍changes in collections and dictionaries
PS > [array]$services=@(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "*OpenVpnService*" })
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
PS > [array]$services=@(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -eq "OpenVpnService" })
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
PS > [array]$services=@(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "OpenVpnService" })
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
如果您已经知道服务名称,您可以这样做:
$serviceName = "WinRM"
# registry
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services$serviceName"
[bool](Get-ItemProperty -Path $regPath -Name DelayedAutoStart -ErrorAction 0)
# WMI
(Get-WmiObject Win32_Service |
Where-Object { $_.Name -eq $serviceName }).DelayedAutoStart
# result = True
$serviceName = "spooler"
# registry
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services$serviceName"
[bool](Get-ItemProperty -Path $regPath -Name DelayedAutoStart -ErrorAction 0)
# WMI
(Get-WmiObject Win32_Service |
Where-Object { $_.Name -eq $serviceName }).DelayedAutoStart
# result = False
编写符合 Posh 2.0 的脚本(要求),我需要使用注册表库获取服务的详细信息。
然而,当我使用确切的名称(并因此使用 -eq 或 -like)搜索特定服务时,结果不正确,而 -like 使用通配符,这按预期工作。我们该如何解释?
PS > [array]$services=Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "*OpenVpnService*" }
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
PS > [array]$services=Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -eq "OpenVpnService" }
PS > $services[0]
SKC VC Name Property
--- -- ---- --------
0 8
PS > "'$($services[0].PsChildName)'"
''
PS > [array]$services=Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "OpenVpnService" }
PS > $services[0]
SKC VC Name Property
--- -- ---- --------
0 8
PS > "'$($services[0].PsChildName)'"
''
更新: 因为我需要一台完全兼容 Posh 2.0 的机器,所以我有一个全新的虚拟机,安装了 Windows 7 SP1 Ultimate,没有任何更新。为什么没有任何更新?因为通过更新机器,我会得到更新的 .NET 版本和 Posh 补丁。我在完全最新的 Windows 10 机器上进行了测试,它运行得非常完美,只要不将输出存储到数组,Windows 7 测试机器也会成功。
在尝试调试情况并缩小问题范围几个小时后,我已经能够确定导致问题的原因。
数组 initialization/casting 失败。简单地包围 the array subexpression operator @( )
需要投射的内容就解决了这个问题。
最近的 PowerShell 版本(Windows 10 上的 5.1,未更新的 Windows 7 上的 PowerShell 2.0)似乎处理数组的方式发生了变化,尤其是 PowerShell 3.0介绍changes in collections and dictionaries
PS > [array]$services=@(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "*OpenVpnService*" })
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
PS > [array]$services=@(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -eq "OpenVpnService" })
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
PS > [array]$services=@(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.PsChildName -like "OpenVpnService" })
PS > $services[0]
Hive: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
SKC VC Name Property
--- -- ---- --------
0 8 OpenVpnService {Type, Start, ErrorControl, ImagePath...}
PS > "'$($services[0].PsChildName)'"
'OpenVpnService'
如果您已经知道服务名称,您可以这样做:
$serviceName = "WinRM"
# registry
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services$serviceName"
[bool](Get-ItemProperty -Path $regPath -Name DelayedAutoStart -ErrorAction 0)
# WMI
(Get-WmiObject Win32_Service |
Where-Object { $_.Name -eq $serviceName }).DelayedAutoStart
# result = True
$serviceName = "spooler"
# registry
$regPath = "HKLM:\SYSTEM\CurrentControlSet\Services$serviceName"
[bool](Get-ItemProperty -Path $regPath -Name DelayedAutoStart -ErrorAction 0)
# WMI
(Get-WmiObject Win32_Service |
Where-Object { $_.Name -eq $serviceName }).DelayedAutoStart
# result = False