OpenRemoteBaseKey()凭据

时间:2009-07-15 19:09:06

标签: powershell registry .net permissions

我正在尝试使用powershell来访问远程注册表,如下所示:

$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", $server)
$key = $reg.OpenSubkey($subkeyPath)

根据我无法确定的某些因素,我得到

  

使用“1”参数调用“OpenSubKey”的异常:“不允许请求的注册表访问。”

或者

  

System.UnauthorizedAccessException:尝试执行未经授权的操作。      在Microsoft.Win32.RegistryKey.Win32ErrorStatic(Int32 errorCode,String str)      在Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(RegistryHive hKey,String machineName)

很明显,这是因为我正在运行powershell脚本的用户没有相应的凭据来访问远程注册表。我希望能够提供一组用于远程注册表访问的凭据,但我无法找到任何方法来执行此操作。我还不清楚确切地指定允许哪些用户远程访问注册表的确切位置。

7 个答案:

答案 0 :(得分:5)

我想我也会把这个问题的答案添加到任何人身上。似乎无法使用RemoteRegistry添加凭据。但是,您可以使用WMI使用备用凭据查询远程注册表,如下所示:

$reg = Get-WmiObject -List -Namespace root\default -ComputerName RemotePC -Credential "Domain\User" | Where-Object {$_.Name -eq "StdRegProv"}

从这里您可以调用标准的Registry方法。以下示例将返回操作系统。

$HKLM = 2147483650
$reg.GetStringValue($HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion","ProductName").sValue

希望这有助于某人:)

答案 1 :(得分:2)

您是否正在运行远程注册表服务?它默认是禁用的,必须导致问题。在您尝试访问的所有远程计算机上检查此服务的状态。

答案 2 :(得分:2)

我无法直接评论bentaylr上面的条目,但我已经采取了他的贡献并添加了PSCredentials创建(从here计算出来),以允许您将凭据硬编码到脚本中。

安心免责声明:在脚本中使用纯文本凭据时要小心。在我的情况下,我在我正在启动的机器上使用通用凭据。根据您的情况,您可以考虑创建加密凭证文件以存储密码(参见上面的链接)。

如果您在目标计算机上登录该用户,则您使用的凭据需要能够访问注册表。

$user = "Domain\Username"
$pass = ConvertTo-SecureString "Password" -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$pass

$reg = Get-WmiObject -List -Namespace root\default -ComputerName $server -Credential $cred | Where-Object {$_.Name -eq "StdRegProv"}
$HKLM = 2147483650
$value = $reg.GetStringValue($HKLM,"Software\Microsoft\.NetFramework","InstallRoot").sValue

答案 3 :(得分:1)

PS C:\>$regKey.OpenSubKey

OverloadDefinitions

Microsoft.Win32.RegistryKey OpenSubKey(string name, **bool Writable**)

PS C:\>$key.OpenSubKey($subkeyName,**$true**)

http://msdn.microsoft.com/en-us/library/xthy8s8d%28v=vs.110%29.aspx

答案 4 :(得分:1)

$ key.OpenSubKey($ subkeyName)在写保护模式下打开子键, $ key.OpenSubKey($ subkeyName,$ true)以可写模式打开它

因此,在$ key.OpenSubKey($ subkeyName,$ true)之后你应该能够创建一个新的子项或值

如果你在$ key.OpenSubKey($ subkeyName)之后尝试相同的事情,你会得到“UnauthorizedAccessException”

答案 5 :(得分:0)

来找你的问题的答案,但今天早上在谷歌搜索我注意到第一个参数是一个类型而不是字符串...希望这有帮助:

$machine = "<Machine Name Goes Here>"
$type = [Microsoft.Win32.RegistryHive]::LocalMachine
$regkey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($type,$machine)
$subkey = $regKey.OpenSubKey($key)
foreach ($sub in $regKey.GetSubKeyNames()){$sub}

答案 6 :(得分:0)

我首先要感谢所有上面的答案真的很有帮助,想补充一点,你可以使用Get-Credential命令收集凭据,而无需在脚本中对其进行硬编码。我已经使用上面的建议在我的脚本中编写了以下代码和查询:

$userCredentials = Get-Credential -Credential <domain\username>
$objReg = Get-WmiObject -List -Namespace root\default -ComputerName $server -Credential $userCredentials | Where-Object{$_.Name -eq "StdRegProv"}
$subKeyNames = $objReg.EnumKey($HKLM,"SOFTWARE\Microsoft\Updates\Microsoft .Net Framework 4.5.1").sNames

上面的代码返回指定密钥中的所有子密钥名称,以便我可以确定已应用于服务器的OS以外的已安装更新。如果要使用$ objReg变量确定所有收集可能性,请运行:

$objReg | Get-Member

您将看到可以针对注册表执行的所有可能查询的列表。希望这有帮助!