在PS脚本中运行Reg.exe将无法在远程计算机上运行错误:密钥名称无效

时间:2014-10-18 23:32:51

标签: powershell

如果我在脚本中运行命令

reg add "HKU\$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v AutoConfigURL /t REG_SZ /d "http://mydomaon.com/proxies/proxy.pac" /f

它完美无缺,因为它是本地的。

当我尝试更改远程计算机上的相同注册表项并将该行更改为此

reg add "\\$machinename\HKU\$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v AutoConfigURL /t REG_SZ /d "http://mydomaon.com/proxies/proxy.pac" /f

失败了 错误:reg:错误:密钥名称无效。 + CategoryInfo:NotSpecified :(错误:密钥名称无效。:String)[],RemoteException 错误:+ FullyQualifiedErrorId:NativeCommandError

ForEach ($machine in $machines)
{

    $User = New-Object System.Security.Principal.NTAccount($env:UserName)
    $sid = $User.Translate([System.Security.Principal.SecurityIdentifier]).value
    New-PSDrive HKU Registry HKEY_USERS
#       Get-Item "HKU:\${sid}"
    Set-Location HKU:\
    cd HKU:\
    reg add '$SID\Software\Microsoft\Windows\CurrentVersion\Internet Settings' /v AutoConfigURL /t REG_SZ /d 'http://proxy.domain.com/proxies/proxy.pac' /f

}

2 个答案:

答案 0 :(得分:1)

这是一种应该工作的方法(也比使用reg.exe更好):

本地电脑:

New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS
New-ItemProperty -Path "HKU:\$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name      AutoConfigURL -PropertyType String -value "http://proy.domain.com/proxies/proxy.pac" -Force

远程计算机:

$credential = Get-Credential
Foreach($machine in $computers){

    Invoke-Command -ComputerName $machine -Credential $credential -ScriptBlock {$temp = $args[0];
    New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS; New-ItemProperty -Path "HKU:\$temp\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -PropertyType String -Name AutoConfigURL -Value "http://proy.domain.com/proxies/proxy.pac" -Force} -argumentlist $sid
}

此处还有New-Itemproperty -PropertyType的类型映射:

  

REG_SZ = String

     

REG_DWORD = DWord

     

REG_QWORD = QWord

     

REG_MULTI_SZ = MultiString

     

REG_BINARY =二进制

所以在这里遇到一些问题之后是一个更新版本,它应该做所有事情,包括通过用户名确定本地用户sid(为了便于阅读添加了换行符,在复制时删除它们)

$username = "yourUsername"
$credential = Get-Credential
Foreach($machine in $computers){

    Invoke-Command -ComputerName $machine -Credential $credential -ScriptBlock {$temp = $args[0];
    New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS; 
    $sid = (Get-CimInstance -Class Win32_UserAccount | where {$_.Name -eq $temp} | select SID).SID;
    New-ItemProperty -Path "HKU:\$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -PropertyType String -Name AutoConfigURL -Value "http://proy.domain.com/proxies/proxy.pac" -Force
    } -argumentlist $username

}

在与Kent讨论并明确指定环境(Windows XP加入域的计算机,用户已登录)之后,脚本必须在此处运行才能实现:

(仅当用户登录XP时才有效)

$sid = ((get-aduser $username).SID).Value 
$credential = Get-Credential
Foreach($machine in $computers){

Invoke-Command -ComputerName $machine -Credential $credential -ScriptBlock {New-PSDrive -Name HKU -PSProvider Registry -Root Registry::HKEY_USERS; New-ItemProperty -Path "HKU:\$($args[0])\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -PropertyType String -Name AutoConfigURL -Value "http://proxy.domain.com/proxies/proxy.pac" -Force} -argumentlist $sid

}

如果用户当前没有登录XP,这就是它的工作方式:

$defaultprofilepath = "C:\documents and settings"
$username = "username"
$profilepath = "$defaultprofilepath\$username"
$credential = Get-Credential
Foreach($machine in $computers){

Invoke-Command -ComputerName $machine -Credential $credential -ScriptBlock {reg load "HKU\TempDir" "$($args[0])\NTUSER.DAT"; reg add "HKU\TempDir\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v AutoConfigURL /t REG_SZ /d 'http://proxy.domain.com/proxies/proxy.pac' /f; reg unload "HKU\TempDir"} -argumentlist $profilepath

}

P.S。如果有人知道如果有一个powershell cmdlet来加载注册表配置单元请注释,我找不到一个动态

答案 1 :(得分:0)

使用WMI你可以这样做:

$computers = ...

$user   = New-Object Security.Principal.NTAccount($env:USERNAME)
$sid    = $user.Translate([Security.Principal.SecurityIdentifier]).Value
$subkey = "$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
$url    = 'http://proy.domain.com/proxies/proxy.pac'
$HKU    = [convert]::ToUInt32('0x80000003', 16)

$credential = Get-Credential
foreach ($machine in $computers) {
  $reg = Get-WmiObject -List -Namespace 'root/default' -Computer $machine `
           -Credential $credential | ? { $_.Name -eq 'StdRegProv' }
  $reg.SetStringValue($HKU, $subkey, 'AutoConfigURL', $url) | Out-Null
}

但请注意,对于远程WMI访问,您需要远程主机上的管理权限。如果没有管理员权限,您可以使用Invoke-Command在远程主机上进行本地WMI访问:

foreach ($machine in $computers) {
  Invoke-Command -Computer $machine -Credential $credential -ScriptBlock {
    $reg = Get-WmiObject -List -Namespace 'root/default' |
             ? { $_.Name -eq 'StdRegProv' }
    $reg.SetStringValue($args[0], $args[1], 'AutoConfigURL', $args[2]) | Out-Null
  } -ArgumentList $HKU, $subkey, $url
}

另请注意,只有域帐户在主机上具有相同的SID。对于本地帐户,您需要确定远程主机上帐户的SID:

foreach ($machine in $computers) {
  Invoke-Command -Computer $machine -Credential $credential -ScriptBlock {
    $user   = New-Object Security.Principal.NTAccount($args[0])
    $sid    = $user.Translate([Security.Principal.SecurityIdentifier]).Value
    $subkey = "$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings"

    $reg = Get-WmiObject -List -Namespace 'root/default' |
             ? { $_.Name -eq 'StdRegProv' }
    $reg.SetStringValue($args[1], $subkey, 'AutoConfigURL', $args[2]) | Out-Null
  } -ArgumentList $env:USERNAME, $HKU, $url
}

如果相关帐户 是域帐户,您可能需要在创建NTAccount对象时提供域名,否则您将收到错误的帐户/ SID,当有一个与域帐户同名的本地帐户时。

$user = New-Object Security.Principal.NTAccount($env:USERDOMAIN, $env:USERNAME)
$sid  = $user.Translate([Security.Principal.SecurityIdentifier]).Value