Set-ItemProperty creates a duplicate registry key - powershell

I am trying to activate Long path names in Windows 10 1903.
When I run as administrator in Windows PowerShell :
Set-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value '1'
I see that a new registry key has been created, instead of overwriting existing one.
Thanks for your help.

There is no reason to assume a bug here - your command should work as intended, but it does the wrong thing (see below).
The symptom you show - duplicate value names in a registry key - are inconsistent with the command in your question.
The underlying native registry APIs do not allow creating values with duplicate names in a given registry key; if they did - which would be a serious bug - the problem would lie there, not in PowerShell.
If the registry editor really shows two values whose names appear to be identical, the only plausible explanation is that they contain invisible characters that makes them different.
As for what you tried:
The system-known LongPathsEnabled registry value of key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
is a 64-bit integer, of registry type REG_DWORD, equivalent to a [uint32] instance in .NET / PowerShell.
By using -Value '1' in your Set-ItemProperty call, you're letting it infer what registry type to write the value as, and that is REG_SZ, i.e. a literal string:
However, if the target value already exists, and is of - the correct - type REG_DWORD, PowerShell will convert the string for you.
By contrast, if no such value exists yet, you'll - incorrectly - create a REG_SZ value.
Your own answer now uses -Value 1, which makes the 1 implicitly an [int] (System.Int32), in which case PowerShell correctly infers REG_DWORD.
However - both for readability and robustness - consider using the -Type parameter to explicitly indicate the type of registry value you're planning to create (command spread across multiple lines for readability - note the ` chars. at the end of the interior lines, which must be the very last char. on their respective lines):
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' `
-Name 'LongPathsEnabled' `
-Value 1 `
-Type DWord
The -Type argument is of type Microsoft.Win32.RegistryValueKind, which, when you create or set a value, must be one of the following values (shown here mapped to their REG_* values):
String # REG_SZ
ExpandString # REG_EXPAND_SZ
Binary # REG_BINARY
DWord # REG_DWORD
MultiString # REG_MULTI_SZ
QWord # REG_QWORD
The full list of native REG_* types can be found here.

I figured it out.
Unquoted the value.
Set-ItemProperty -path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -value 1
Now I can play with WSL.
Enjoy.

Try this:
Push-Location
Set-Location 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem'
Set-ItemProperty -path .\ -Name 'LongPathsEnabled' -value 1 -Type DWord -Force
Pop-Location

Related

How do I add HKCU Regkeys value for each current user in powershell script?

I want a powershell script to run each time a user login to Windows by placed in: Shell:common startup.
This script must add about 50 Regkey's in HKCU, which is setting/path for Presetfolders for a application.
I want to use Powershell and have tried this command adding the RegKey (This command needs to be repeated for each 50 regkeys!):
New-ItemProperty -Path 'HKCU:\Software\AppName' -Name 'PresetFolder' -PropertyType String -Value '$env:userprofile\Documents\AppName\Presets1' -Force
New-ItemProperty -Path 'HKCU:\Software\AppName' -Name 'PresetFolder' -PropertyType String -Value '$env:userprofile\Documents\AppName\Presets2' -Force .......
When using "$env:userprofile" instead of c:\Users\MyUserProfile\Documents\.... the -value in the RegKey will be: "$env:userprofile\Documents\NewFolder\Presets" and not as wanted: "c:\Users\MyUserProfile\Documents\NewFolder\Presets".
I need a Variable for each userprofile!
Alternatively I can after Program installation by using admin-account, I can exported all RegKey's as a .reg-file. Before using the powershell-script to merge the RegKeys everytime a user is logging in Windows, I now need to search and replace the value of the path (-Value) from AdminUserProfil-path into a variable for each user running the script.
Part of the Reg-file:
[HKEY_CURRENT_USER\Software\AppName\Version]
"HelpDocPath"="C:\Users\\AdminUserprofiles\\Documents\\AppName\\Version\\HTML Help\\en"
"ExciterCacheInstallPath"="C:\\Program Files\\AppName\\Version\\Exciter Cache"
"DSPResourceFilesInstallPath"="C:\\Program Files\\AppName\\Version/Resources"
"InstallPath"="C:\\Program Files\\AppName\\InstallFolder"
"PresetFolder"="C:\\Users\\AdminUserprofiles\\Documents\\AppName\\Version\\Presets\\Global Presets"\
Hope anyone can help?
What do I need to type for the right path, so each user will have there own path? Do I need a variable fo rusers or..?
Thank you.
Define $env:USERPROFILE as a variable so you can call it, otherwise PS will just output what you have typed, which is what is happening in this case.
$path = "$env:USERPROFILE"
New-ItemProperty -Path 'HKCU:\Software\AppName' -Name 'PresetFolder' -PropertyType String -Value '$path\Documents\AppName\Presets1' -Force

Powershell adding random symbols to registry value?

I have a PowerShell script that adds a string value at a location:
Push-Location
Set-Location HKCU:
New-ItemProperty -Path
SOFTWARE\Microsoft\Office\16.0\Common\Security\Crypto\EscrowCerts -Name
"EscrowCert01" -Value '‎02 ee 7f' -PropertyType "String"
It works, the value is added. However, three symbols have been added to the start of the string.
Is there a way to stop this from happening?

Powershell Script to write to registry based on WMI information

I am looking to use a powershell script to WMI query the computer during post-install of the imaging sequence via MDT/SCCM. Actively there are multiple VB scripts to accomplish parts of the System Properties area (Manufacturer, Model, InstallDate, SerialNumber, etc.), and would like to consolidate this into a single script that does it all.
Running Powershell ISE as Administrator, so that wouldn't be causing for any permissions issues; the model information returns Macbook as I am testing on Windows 10 through Bootcamp.
Clear-Host
$Model = (Get-WmiObject -Class:Win32_ComputerSystem).Model
$RegKey = “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\OEMInformation”
New-Item -Path $RegKey -Name Model -Type String -Value $Model –Force
After I ran the script, these were the results (shown below).
Name Property
----- --------
Model (default) : MacBookPro11,1
However the value is not written to the registry. How could I go about the writing of the informaiton to the registry, while also allowing for multiple variables to be aligned in addition? All the values (subkeys) would need to be created and be placed at the same Registry Path of "OEMInformation".
Aim to include for Manufacturer, Model, Name, InstallDate, SystemType as well.
If I understand you correctly, you're able to write to the registry, but you're unsure how to write multiple items to the same "path".
The Windows registry is contstructed by "Keys" and one or multiple values. Your "new-item" line above actually sets a value but you don't specify one so it looks like the "magic" default value is used.
In order to set multiple ones in the same path, you'd use the Cmdlet
Set-ItemProperty, for example using:
Set-ItemProperty -Path $RegKey -Name "Model" -value $Model
You can then have multiple "properties" in that path using the same technique (just use a different value for the "Name" parameter.
I was able to get this resolved, thank you #Trondh for the assistance.
$Model = (Get-WmiObject -Class:Win32_ComputerSystem).Model
$RegPath = 'Registry::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\OEMInformation'
New-Item $RegPath -Force | New-ItemProperty -Name Model -Value $Model -Force | Out-Null

PowerShell New-Item Positional Parameter Oddities

Given the Microsoft documentation for PowerShell, I can see no reason why the following code should fail with the given error. Then again, PowerShell can fail when a script just gets too long. All the paths are double-quote strings.
##### ALGORITHM Take in keystore path, make a backup in an adjacent directory
$ksPath = $java_store_path.Substring(0, $java_store_path.LastIndexOf('\') + 1)
$backupPath = $ksPath + "backups"
New-Item $backupPath PowerShell -type directory -force
New-Item : A positional parameter cannot be found that accepts argument 'PowerShell'.
https://technet.microsoft.com/en-us/library/ee176914.aspx
New-Item c:\scripts\Windows PowerShell -type directory
If that's valid, mine should be too. I'm running on Server 2012 R2.
The example on that page is just plain wrong. It seems they meant to refer to the path C:\Scripts\WindowsPowerShell or they forgot to quote the directory with spaces in it.
So it should have been one of these:
New-Item c:\scripts\WindowsPowerShell -type directory
New-Item 'c:\scripts\Windows PowerShell' -type directory
New-Item "c:\scripts\Windows PowerShell" -type directory
Ask yourself, what would PowerShell alone have been referring to? What parameter would it have corresponded to?
Edit: as the commenters have pointed out, the example was supposed to show the nameSet parameters, where a separate -Path and -Name are specified, and purportedly PowerShell was supposed to be a value to the -Name parameter. That does look correct. The reason the example didn't work (and yours as well), is because the -Name parameter cannot be specified positionally, which you can see in the MSDN article I linked to below, and in the built-in help:
Type: String
Parameter Sets: nameSet
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: True (ByPropertyName)
Accept wildcard characters: False
In that case, their example should have been something like these:
New-Item c:\scripts\Windows -Name PowerShell -type directory
New-Item -Path c:\scripts\Windows -Name PowerShell -type directory
So reiterating, named parameters would have worked here, and would have avoided confusion.
Generally, you shouldn't be using positional parameters in scripts, unless they're extremely clear (and even then, I'd recommend avoiding).
Using named parameters would have made this easier to figure out. And tab-completion helps with filling in the parameter names and in completing paths (usually with proper quoting too).
I think you should change yours to:
New-Item -Path $backupPath -Type Directory -Force
And looking over that technet article, it's really not so good. The MSDN article on New-Item is better, and this is the information you should see when running Get-Help New-Item as well.
Side question:
Then again, PowerShell can fail when a script just gets too long.
What?

Powershell's Copy-Item gives inconsistent results on file system and registry

I am trying to use Powershell's Copy-Item commandlet with the -Recurse and -Force parameters to copy settings from one registry key and overwrite the same settings (if they exist) in another key. If I were using this same command on a file system, then any folders that exist in source and target would be overwritten in the target.
When using this command on the registry, however, if there are keys in the target that exist, the source key is copied as a subkey. Example:
Starting state:
HKCU:Software\OldVendor\Program
HKCU:Software\OldVendor\Program\Setting1
HKCU:Software\OldVendor\Program\Setting2
HKCU:Software\NewVendor\Program
HKCU:Software\NewVendor\Program\Setting1
HKCU:Software\NewVendor\Program\Setting2
Now if I run this command:
Copy-Item -Path "HKCU:Software\OldVendor\Program" -Destination "HKCU:Software\NewVendor" -Recuse -Force
I expect the same structure to be maintained. In fact, the structure under NewVendor looks like this:
HKCU:Software\NewVendor\Program
HKCU:Software\NewVendor\Program\Setting1
HKCU:Software\NewVendor\Program\Setting1\Setting1
HKCU:Software\NewVendor\Program\Setting2
HKCU:Software\NewVendor\Program\Setting2\Setting2
Can anyone tell me how to get Powershell to overwrite existing registry keys, instead of copying to subkeys?
It seems to me you want to copy items and their values, those are properties, not keys. You can list them as follows:
get-itemproperty "HKCU:Software\NewVendor\Program"
or u can use alias and omit quotes:
gp HKCU:Software\NewVendor\Program
Another, better way, which doesn't view powershell specific properties:
Get-Item HKLM:\SOFTWARE\NewVendor\Program | select -ExpandProperty Property
So, if u want to copy all the properties from one key to another:
Get-Item HKLM:\SOFTWARE\Program | select -ExpandProperty Property | % {Copy-ItemProperty -Path HKLM:\SOFTWARE\Program -Destination HKLM:\SOFTWARE\AnotherProgram -Name $_ -Verbose}
You have to use foreach loop, beacuse Copy-ItemProperty cmdlet can copy only one property been specified.