How to Rename a Registry Key with Forward Slashes in PowerShell
Why Does Rename-Item Fail on Forward Slashes?
When administering the Windows Registry via PowerShell, you might occasionally encounter registry keys that contain forward slash characters (/), commonly used to store URLs, UNC paths, or configuration strings. While PowerShell's Registry provider generally supports these keys during read or create operations, using Rename-Item often throws an error:
Rename-Item : The registry key at the specified path does not exist.This occurs because PowerShell treats the forward slash (/) interchangeably with the backslash (\) as a path separator. When you pass a value containing / to the -NewName parameter, the underlying PowerShell Registry provider interprets the string as a nested relative path rather than a literal string name. Escaping with backticks (`/) will not prevent the provider from splitting the path.
Solution 1: Use Move-Item Instead of Rename-Item
Fortunately, the Move-Item cmdlet resolves destination paths differently than Rename-Item. If you supply the complete target path to the -Destination parameter, PowerShell correctly keeps the forward slashes intact as part of the key name.
$oldPath = "HKLM:\SOFTWARE\MySoftware\Path=//Server/UNC/path/goes/here"
$newPath = "HKLM:\SOFTWARE\MySoftware\Path=//Server/New/UNC/path/here"
# Use Move-Item to effectively rename the key
Move-Item -LiteralPath $oldPath -Destination $newPath
Tip: Always prefer using -LiteralPath instead of -Path to prevent PowerShell from misinterpreting characters like brackets, asterisks, or other wildcard symbols that often appear in path-like registry keys.
Solution 2: Use .NET Direct Registry APIs
If you prefer an approach that bypasses PowerShell's path parser completely, you can utilize the native .NET Microsoft.Win32.RegistryKey class. The Windows Registry API doesn't provide a direct "rename" method, but you can create the new key, migrate the values and subkeys recursively, and delete the original key.
Here is a robust reusable function to rename keys containing special characters:
function Rename-RegistryKeyLiteral {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[Microsoft.Win32.RegistryHive]$Hive,
[Parameter(Mandatory = $true)]
[string]$ParentPath,
[Parameter(Mandatory = $true)]
[string]$OldName,
[Parameter(Mandatory = $true)]
[string]$NewName
)
# Open the base hive and parent subkey with write access
$baseKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey($Hive, [Microsoft.Win32.RegistryView]::Default)
$parent = $baseKey.OpenSubKey($ParentPath, $true)
if (-not $parent) {
throw "Parent path '$ParentPath' could not be found."
}
$sourceKey = $parent.OpenSubKey($OldName)
if (-not $sourceKey) {
$parent.Dispose()
throw "Source key '$OldName' does not exist under '$ParentPath'."
}
# Create new subkey with the literal string name
$destKey = $parent.CreateSubKey($NewName)
# Helper scriptblock for recursive copying
function Copy-KeyRecursively($src, $dst) {
foreach ($valName in $src.GetValueNames()) {
$val = $src.GetValue($valName, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
$valKind = $src.GetValueKind($valName)
$dst.SetValue($valName, $val, $valKind)
}
foreach ($subName in $src.GetSubKeyNames()) {
$srcChild = $src.OpenSubKey($subName)
$dstChild = $dst.CreateSubKey($subName)
Copy-KeyRecursively $srcChild $dstChild
$srcChild.Dispose()
$dstChild.Dispose()
}
}
try {
Copy-KeyRecursively $sourceKey $destKey
$sourceKey.Dispose()
$destKey.Dispose()
# Delete the old subkey tree
$parent.DeleteSubKeyTree($OldName)
}
finally {
$parent.Dispose()
$baseKey.Dispose()
}
}
# Example usage:
Rename-RegistryKeyLiteral `
-Hive LocalMachine `
-ParentPath "SOFTWARE\MySoftware" `
-OldName "Path=//Server/UNC/path/goes/here" `
-NewName "Path=//Server/New/UNC/path/here"
Summary
- Rename-Item fails because its
-NewNameparameter interprets/as a directory delimiter. - Move-Item with
-LiteralPathand-Destinationprovides the quickest built-in workaround without writing external helper code. - .NET Registry APIs provide the most reliable and performant alternative when automating enterprise scripts where PowerShell provider path-mangling must be avoided.