Reputation: 515
If I run the command from with in the script
reg add "HKU\$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v AutoConfigURL /t REG_SZ /d "http://mydomaon.com/proxies/proxy.pac" /f
it works perfectly, because it is local.
When I try to change the same registry key on a remote machine and changing the line to this
reg add "\\$machinename\HKU\$sid\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v AutoConfigURL /t REG_SZ /d "http://mydomaon.com/proxies/proxy.pac" /f
It fails with ERROR: reg : ERROR: Invalid key name. + CategoryInfo : NotSpecified: (ERROR: Invalid key name.:String) [], RemoteException ERROR: + 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
}
Upvotes: 1
Views: 3846
Reputation: 5871
Here is an approach that should work (also better then using reg.exe):
Local Computer:
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
Remote Computer:
$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
}
Also here are the Type mappings for New-Itemproperty
´s -PropertyType
:
REG_SZ = String
REG_DWORD = DWord
REG_QWORD = QWord
REG_MULTI_SZ = MultiString
REG_BINARY = Binary
So after a few problems here is an updated version which should do everything including determining the local users sid by username (added linebreaks for readability, remove them when you copy)
$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
}
After furhter discussion with Kent and clearly specifying the environment (Windows XP domain-joined machines, user logged on) the script has to run in this was what we came up with:
(this works only if the user is logged in on 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
}
This is how it would work if the user was not currently log in on 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. If someone has a clue if there is a powershell cmdlet to load registry hives please comment, i could not find one on the fly
Upvotes: 1
Reputation: 200463
Using WMI you could do it like this:
$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
}
Note, however, that for remote WMI access you need administrative privileges on the remote host. Without admin privileges you could use Invoke-Command
for local WMI access on the remote host:
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
}
Note also that only domain accounts have the same SID accross hosts. For local accounts you need to determine the SID of the account on the remote host:
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
}
If the account in question is a domain account, you may want to provide the domain name when creating the NTAccount
object, because otherwise you'd be getting the wrong account/SID when there's a local account with the same name as the domain account.
$user = New-Object Security.Principal.NTAccount($env:USERDOMAIN, $env:USERNAME)
$sid = $user.Translate([Security.Principal.SecurityIdentifier]).Value
Upvotes: 0