导出特定的注册表项
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
属性 值的对象。
我写了一个脚本来导出特定的注册表键和其中的子键,但不幸的是我的脚本得到了键,但无法过滤掉项目中的子键。
请帮助我获取每个对象的子项并将该数据导出为 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 theSelect-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 (
{ ... }
) toWhere-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
属性 值的对象。