Powershell项目 - 使用Get-ChildItem存储到数组时未展开属性

时间:2016-12-29 09:57:36

标签: powershell comparison powershell-v2.0 comparison-operators chocolatey

编写符合Posh 2.0标准的脚本(要求),我需要使用注册表基础获取服务的详细信息。

但是,当我使用确切的名称(因此使用-eq或-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测试机器也能正常运行。

2 个答案:

答案 0 :(得分:1)

在尝试调试情况并缩小问题几个小时之后,我已经能够确定导致问题的原因。

数组初始化/转换失败。只需围绕the array subexpression operator @( )需要投放的内容即可解决问题。

似乎处理数组的方式在更新的PowerShell版本(Windows 10上的5.1和未更新的Windows 7上的PowerShell 2.0)上发生了变化,特别是对于引入changes in collections and dictionaries的PowerShell 3.0

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'

答案 1 :(得分:1)

如果您已经知道服务名称,则可以执行以下操作:

$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