我正在尝试使用 StdRegProv 类从远程服务器收集一些注册表值:
Invoke-Command -ComputerName $ComputerHost -Credential $cred -ScriptBlock { Get-WmiObject -List -Namespace "root\default" | Where-Object { $_.Name -eq "StdRegProv" } }
但它不会在输出中返回这些类的方法:
NameSpace: ROOT\default
Name Methods Properties PSComputerName
---- ------- ---------- --------------
StdRegProv
如果我在本地机器中从 ScriptBlock 执行命令,一切正常,输出如下所示:
NameSpace: ROOT\default
Name Methods Properties
---- ------- ----------
StdRegProv {CreateKey, Delet... {}
其他一些命令,例如 Get-Service,工作正常,我可以看到输出。这些有什么问题吗? 远程计算机是:安装了 .Net 3.5.1 和 PowerShell 2.0 的 Windows Server 2003
我想,StdRegProv 类在 2003 服务器中不起作用,但在本地可以正常工作
顺便说一句:
CIM cmdlet(例如,
Get-CimInstance
)取代了 Windows PowerShell v3(于 2012 年 9 月发布)中的 WMI cmdlet(例如,
Get-WmiObject
)。因此,应避免使用 WMI cmdlet,尤其是因为 PowerShell (Core) 7+(所有未来工作都将集中于 Windows PowerShell 的现代跨平台成功)甚至不再拥有。但请注意,WMI 仍然是 CIM cmdlet 的“底层”。有关更多信息,请参阅此答案。
v2,CIM cmdlet 不是一个选项。
(
Get-WmiObject
) 调用 Invoke-Command -ComputerName
,除了少数众所周知的类型之外,这会导致 类型保真度的损失: 值得注意的是,大多数类型的实例都是
[psobject]
实例,这些实例具有原始对象的所有(公共)属性的静态副本 - 有关详细信息,请参阅这个答案。
您有两个
选择:
任一:调用远程执行脚本块中的任何方法,其中Get-WmiObject
.GetStringValue
方法来检索存储在 remote计算机上注册表项
Path
的
HKEY_LOCAL_MACHINE\SOFTWARE\DefaultUserEnvironment
值中的数据:
Invoke-Command -ComputerName $ComputerHost -Credential $cred -ScriptBlock {
(Get-WmiObject -List StdRegProv).GetStringValue(2147483650, 'SOFTWARE\DefaultUserEnvironment', 'Path')
}
或:使用 WMI cmdlet 提供的 远程处理,
在这种情况下,类型保真度不会损失;但是,请注意,使用与 PowerShell 不同的远程处理基础设施,即过时的基于 DCOM 的基础设施,因此可能需要单独的配置;但是,根据您的反馈,调用者计算机上的 KB5004442 会主动阻止在针对运行较旧 Windows 版本的计算机时使用此基础设施。
# You can call methods such as `.GetStringValue()` directly
# on the output object.
(
Get-WmiObject -ComputerName $ComputerHost -Credential $cred -List StdRegProv
).GetStringValue(2147483650, 'SOFTWARE\DefaultUserEnvironment', 'Path')
为了完整起见,以下是基于 CIM cmdlet 的等效解决方案:
$regProv = Get-CimClass StdRegProv -CimSession (New-CimSession -ComputerName $ComputerHost -Credential $cred)
$regProv | Invoke-CimMethod -MethodName GetStringValue -Arguments @{ hDefKey = [Uint32] 2147483650; sSubKeyName = 'SOFTWARE\DefaultUserEnvironment'; sValueName = 'Path' }
但是,在这种情况下,您可以使用
just
Invoke-CimMethod
调用,并通过 -ClassName
参数指定目标类:
Invoke-CimMethod -ClassName StdRegProv -MethodName GetStringValue -Arguments @{ hDefKey = [Uint32] 2147483650; sSubKeyName = 'SOFTWARE\DefaultUserEnvironment'; sValueName = 'Path' }
“CIM cmdlet-Arguments
参数传递,其中需要
参数名称-值对的哈希表(字典)。 参数名称可以从
.Parameters
.CimClassMethods
属性的
Get-CimClass
属性中收集;对于由 Get-CimInstance
返回的 CIM instances,请使用
.CimClass.CimClassMethods
;例如:(Get-CimClass StdRegProv).CimClassMethods |
Where Name -eq GetStringValue |
ForEach Parameters
这会产生以下显示输出:
Name CimType Qualifiers ReferenceClassName
---- ------- ---------- ------------------
hDefKey UInt32 {ID, IN}
sSubKeyName String {ID, IN}
sValueName String {ID, in}
sValue String {ID, out}
不幸的是,参数信息不
参数或其默认值;例如,对于 GetStringValue()
,hDefKey
参数是可选的,默认为 HKEY_LOCAL_MACHINE (
2147483650
)
数字类型参数必须由其 exact
类型绑定,因此对上面的[UInt32]
hDefKey
强制转换。