导出特定的注册表项

Export Specific Registry Keys

我写了一个脚本来导出特定的注册表键和其中的子键,但不幸的是我的脚本得到了键,但无法过滤掉项目中的子键。

请帮助我获取每个对象的子项并将该数据导出为 CSV 格式。

$Servers = $env:COMPUTERNAME #Get-Content -Path 

Foreach ($vm in $Servers) {
$TCPIP_Interface = Get-ChildItem -Path HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces

foreach ($interface in $TCPIP_Interface){
Get-ItemProperty -Path $interface| Where-Object -Like DhcpIPAddress,DhcpNameServer,DhcpServer,DhcpDefaultGateway

}
#| Select-Object -Property DhcpIPAddress,DhcpNameServer,DhcpServer,DhcpDefaultGateway #| Export-Csv -Path "C:\temp\TCPIP_Interface_Details.csv" -NoTypeInformation
}

每个 $interface 都是一个对象,其中 .Path 是有趣的属性。

尝试:

$Servers = $env:COMPUTERNAME # Get-Content -Path 

$result = foreach ($vm in $Servers) {
    Invoke-Command -ComputerName $vm -ScriptBlock {
        Get-ChildItem -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces' | ForEach-Object {
            Get-ItemProperty -Path $_.PSPath | Where-Object { $_.PsObject.Properties.Name -like 'Dhcp*' }
        }
    } | Select-Object -Property @{Name = 'ComputerName'; Expression = {$_.PSComputerName}}, 
                                DhcpIPAddress,
                                @{Name = 'DhcpNameServer'; Expression = {$_.DhcpNameServer -split ' ' -join '; '}},
                                DhcpServer, 
                                @{Name = 'DhcpDefaultGateway'; Expression = {$_.DhcpDefaultGateway -join '; '}}
}
$result | Export-Csv -Path "C:\temp\TCPIP_Interface_Details.csv" -NoTypeInformation

当然,您可能需要将参数 -Credential 添加到 Invoke-Command cmdlet 并提供有效的管理员凭据

撇开针对多台远程计算机的方面(您需要 Invoke-Command -ComputerName $Servers { ... }), you can simplify your code as follows (I'm also omitting the Export-Csv 调用):

$regPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces'
Get-ItemProperty $regPath\* |
  Select-Object DhcpIPAddress,DhcpNameServer,DhcpServer,DhcpDefaultGateway |
    Where-Object { $_.psobject.Properties.Value -ne $null }
  • 使用通配符路径 $regPath\* 隐式循环遍历 $regPath 中的所有子键并检索它们的属性。

  • Where-Object { $_.psobject.Properties.Value -ne $null } filters out any of the custom objects created by the Select-Object call that do not at least have one non-$null property value, using the intrinsic .psobject property.

需要做更多的工作才能:

  • 添加一个 Server 属性 来反映执行机器的主机名。

  • 数组DhcpDefaultGateway属性转换为字符串值一,通过加入 , 潜在的多个地址,以便导出到 CSV 有意义(array-valued 属性最终在 CSV 中逐字 System.String[])。

两者都可以通过 calculated properties:

实现
$regPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces'
Get-ItemProperty $regPath\* |
    Select-Object @{
                     Name='Server';
                     Expression = { $env:COMPUTERNAME }
                  }, 
                  DhcpIPAddress, DhcpNameServer, DhcpServer, 
                  @{
                    Name = 'DhcpDefaultGateway';
                    Expression = { $_.DhcpDefaultGateway -join ', ' }
                  } |
      Where-Object { 
        $_.psobject.Properties.Where({ $_.Name -ne 'Server' }).Value -ne $null 
      }

注意:如果您想在所有服务器上的调用计算机上的单个 CSV 文件中收集所有信息,请执行某些操作像下面这样:

Invoke-Command -Servers $Servers { ... } | 
  Select-Object * -Exclude PS*, RunspaceId |
    Export-Csv C:\temp\TCPIP_Interface_Details.csv NoTypeInformation
  • -Exclude PS*, RunspaceId 排除 PowerShell remoting 自动添加到所有输出对象的属性。

至于你试过的

  • 你的Get-ChildItem call returned objects of type [Microsoft.Win32.RegistryKey].

  • 将它们传递给 Get-ItemProperty -Path 字符串化 它们,结果是 registry-native要上报的路径;例如:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{223a2c0a-88d9-11e6-b808-806e6f6e6963}
    
  • PowerShell 不直接识别此类路径并假定它们是(相对)file-system 路径。要强制将其解释为 registry 路径,您有树选项:

    • 最好使用管道提供输入路径:

       # Note: This binds the .PSPath property value to the -LiteralPath parameter.
       $interface | Get-ItemProperty
      
    • 使用 PowerShell 装饰对象的 .PSPath 属性:

       # Note: Parameter -Path implied; for full robustness, use -LiteralPath
       Get-ItemProperty $interface.PSPath
      
    • registry:: 提供商前缀添加到字符串化产生的 registry-native 路径中:

       Get-ItemProperty registry::$interface
      
  • 我认为 Where-Object -Like DhcpIPAddress,DhcpNameServer,DhcpServer,DhcpDefaultGateway 是试图过滤掉 Select-Object 调用产生的“空”对象,以便只有具有所选属性实际值的对象返回并导出为 CSV。

    • 但是,即使语法上这种方法也行不通,因为从 PowerShell 7 开始,2.x 您不能隐式地将操作应用于每个输入对象整体 使用simplified syntax;相反,您必须通过 -Property 参数指定一个 属性 来操作,第一个 positional 参数隐式绑定。

      • 也就是说,能够对每个输入对象作为一个整体进行隐式操作会很方便,GitHub issue #8357建议增加对它的支持。
    • 因此,您的命令等同于以下命令,但失败了,因为 -Property 仅支持 单个 属性 名称(字符串):

      Where-Object -Property DhcpIPAddress,DhcpNameServer,DhcpServer,DhcpDefaultGateway -Like
      
    • 因此您的逻辑需要传递 script block ({ ... }) to Where-Object's (positionally implied) -FilterScript parameter, in which the input object as a whole can be referenced as usual, via the automatic $_ variable。但是,即使您的 -like 操作也不会按预期工作;请参阅顶部的命令,了解如何过滤掉仅具有 $null 属性 值的对象。