.net - Powershell - .net 远程注册表返回空白
问题描述
当使用 .NET 方法[Microsoft.win32.registrykey]
尝试查询远程注册表项时,我只会在每一步都获得空值
像这样建立一些变量:
$computer = '192.168.200.10'
$key = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\7-zip"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$reg = [Microsoft.win32.registrykey]::OpenRemoteBaseKey($type, $computer)
如果我然后尝试这样的事情:
$reg.opensubkey($key)
我会得到一个空白的“名称”和“属性”列。我已经尝试删除这remote
方面的内容并尝试::OpenBaseKey
查看我自己的 HKLM 配置单元,但它仍然返回空白。
这一切都始于一个脚本,该脚本将找到给定程序的卸载字符串,包括它是否仅在 HKU 配置单元中注册。最终目的是针对 LAN 上的远程计算机运行它,以查找我感兴趣的任何程序的卸载字符串。
尝试在不导入任何其他模块的情况下执行此操作,因为我希望能够按原样共享它。只是挠头弄清楚如何查询远程注册表。
这是我的查询在本地显示的示例。
$64bit = get-itemproperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*,HKU:\${sid}\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, UninstallString, PSChildName | Where-Object { $_.DisplayName -like "$process*"}
$32bit = get-itemproperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, UninstallString, PSChildName | Where-Object { $_.DisplayName -like "$process*"}
该$sid
变量是根据登录用户较早找到的。
解决方案
我会得到一个空白的“名称”和“属性”列。
这本身并不表示问题;这只是一个显示问题 - 见底部。
虽然您可以直接使用该[Microsoft.Win32.RegistryHive]
类型来获得所需的内容,但它会比使用 PowerShell 的Get-ItemProperty
cmdlet 更复杂、更冗长。
Get-ItemProperty
本身缺乏针对远程注册表的能力,但您可以将其与PowerShell remoting结合使用,这可能需要在目标计算机上进行事先设置 - 请参阅about_Remote_FAQ。
# Create a session on the target computer.
# The target machine must have PowerShell remoting enabled.
# You may have to specify credentials with -Credential
$session = New-PSSession -ComputerName '192.168.200.10'
# Use Invoke-Command with the session to execute your commands remotely.
$64bit = Invoke-Command -Session $session {
get-itemproperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, HKU:\${using:sid}\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, UninstallString, PSChildName |
Where-Object { $_.DisplayName -like "${using:process}*"}
}
$32bit = Invoke-Command -Session $session {
get-itemproperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, UninstallString, PSChildName |
Where-Object { $_.DisplayName -like "${using:process}*"}
}
# Close the session.
Remove-PSSession $session
重要提示:注意局部变量$sid
和如何$process
被引用为${using:sid}
和${using:process}
,这是远程执行的脚本块看到它们所必需的。
请注意,通过远程处理接收到的输出在远程端进行序列化,在本地端进行反序列化,这意味着只有少数众所周知的类型被反序列化为其原始类型。所有其他都是基于类型的具有静态属性值的原始对象的近似值。[pscustomobject]
虽然有时这可能是个问题,但在您的情况下不会出现这种情况,因为您的命令输出的对象是[pscustomobject]
开始时的实例,因为使用Select-Object
.
至于你原来的症状:
看似空白的属性是一个显示问题,与针对远程注册表[1]无关:
应用的输出格式$reg.opensubkey($key)
基于type的 PowerShell格式指令Microsoft.Win32.RegistryKey
,但这些指令依赖于此类实例,以使用 PowerShell 提供程序属性进行扩充,这些属性仅在您通过/获取Microsoft.Win32.RegistryKey
实例时存在。Get-Item
Get-ChildItem
相比之下,Microsoft.Win32.RegistryKey
直接通过 .NET API 获得的实例缺少格式化所依赖的提供程序添加的属性,导致格式化定义呈现空白列值。
如前所述,无论您是针对本地注册表还是远程注册表,此问题都会独立存在,因此让我用本地密钥演示该问题:
$base = [Microsoft.Win32.RegistryKey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::CurrentUser, 'Registry64')
$subkey = $base.OpenSubKey('Console')
$subkey # output
以上,即使打开HKEY_CURRENT_USER]\Console
成功,也会产生一个看似空的对象:
Name Property
---- --------
一个简单的解决方法是使用 强制显式显示真实属性Format-List *
,例如:
PS> $subkey | Format-List *
SubKeyCount : 2
View : Registry64
Handle : Microsoft.Win32.SafeHandles.SafeRegistryHandle
ValueCount : 46
Name : HKEY_CURRENT_USER\Console
请注意,以上内容不会提供目标键的值和数据的显示,这是 PowerShell 默认提供的方式,出于礼貌,通过计算Property
列提供;你也必须做更多的工作才能显示出来。
[1]
顺便说一句:当前(PowerShell Core 7.0.0-preview.3)针对远程注册表时存在一个单独但相关的问题,但前提是您确实使用Get-Item
/ Get-ChildItem
:请参阅此帖子
推荐阅读
- python - 查找 GTK 小部件的类型
- r - 有没有办法在 R 中自动区分时间序列?
- python-3.x - 使用 TensorFlow 2.0 keras:NotFoundError FetchOutputs 节点:未找到 [Op:AutoShardDataset]
- amazon-web-services - 用于停止包含标签但不包含标签值的 EC2 实例的 Cloud Custodian 策略
- android - 具有两个文本视图的 Step Viewer
- python - 在 Windows 上成功 shutil.rmtree 后,os.mkdir 可能会因 PermissionError 而失败
- javascript - 将列表理解python转换为javascript
- drools - 如何在 dslr 规则中使用 not()?
- mysql - 如何防止分支之间的自动递增冲突?
- c# - 编译器如何为实数文字选择隐式运算符重载