如何使用 PowerShell 删除 REG_DWORD 注册表值,其中注册表值如“*String*”?
How to delete REG_DWORD registry value where registry value like '*String*' using PowerShell?
PowerShell 在其父注册表项的 $\_.Property
中将注册表值(及其注册表数据)显示为数组。如何 select 并仅删除值类似于 \*String\*
的注册表值?
我曾尝试在 Whosebug 和 Google 上搜索高价和低价,尝试了很多涉及 Get-Item
、Get-ItemProperty
、Get-ChildItem
、Select-Object
的组合(包括 -ExpandProperty
参数)和 Where-Object
到 select 我想要的注册表值(在继续合并删除之前)。我现在处于完全无能为力的地步,无法弄清楚如何简单地找到特定注册表项中存在的 \*Text\*
之类的注册表值并将其删除。如此简单的事情似乎如此困难!我不知道如何处理数组中的数据!
Get-Item -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs
注册表项 HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs
的每个注册表值都列为 $\_.Property
下数组的一部分。我期待的结果是我可以做一些大致类似于 $\_.RegistryValue -Like '\*Text\*' | Remove-Item
的事情来删除匹配 \*Text\*
.
的注册表值
为了确保某些词汇的技术用法正确,"registry key" 在 regedit.exe 中显示为一个文件夹。
A "registry value" 是任何类型的条目,例如 REG\_SZ
、REG\_DWORD
、REG\_MZ
等。注册表值包含 "registry data",根据注册表类型,它可能是一个字符串,一个 32 位值(有时表示为 1、0 或 0x000000、0x000001)。
我们经常将 "registry values" 称为 'registry keys'(这是不正确的技术用法),将 "registry data" 称为 'registry values'(也是不正确的技术用法),并且 "registry keys" 作为 folders/location/"this place in the registry".
仅按值名称过滤器删除注册表值:
更新,根据自己的简化:
# The target registry key's full path.
$keyPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs'
# Pass the value name pattern to Remove-ItemProperty's -Name parameter.
# Remove `-WhatIf` if the preview suggests that the operation works as intended.
Remove-ItemProperty -Path $keyPath -Name *Text* -WhatIf
陷阱:如果你想使用通配符表达式比如*Text*
和-Name
,你必须将其与 -Path
而不是 -LiteralPath
组合,即使键路径本身不是通配符;
-LiteralPath
,-Name
也按字面意思(逐字)。
如果确实需要使用 -LiteralPath
(例如,如果文字路径包含 *
字符,例如 HKEY_CLASSES_ROOT\*
):
# The target registry key's full path.
$keyPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs'
# Get an array of all value names that match the name wildcard pattern.
$valueNames = (Get-Item -LiteralPath $keyPath).Property -like '*Text*'
# Pass the array of value names to Remove-ItemProperty's -Name parameter.
# Remove `-WhatIf` if the preview suggests that the operation works as intended.
if ($valueNames) {
Remove-ItemProperty -LiteralPath $keyPath -Name $valueNames -WhatIf
}
注意使用 Get-Item
而不是 Get-ItemProperty
。[1]
Get-Item
returns 代表整个键的对象,类型为 [Microsoft.Win32.RegistryKey]
,PowerShell 用 .Property
注释 属性 装饰,其中包含所有键值名称的数组。
重要:在.Property
数组中,PowerShell翻译默认值名称,即empty string (''
) 在 API 级别,进入名称 '(default)'
.
将运算符 -like
应用于 array LHS 使其充当 filter 只有 returns a匹配项的子数组。
Remove-ItemProperty
的 -Name
参数直接接受 数组 的 属性(注册表值)名称以从目标键中删除。
正在按值名称删除值 and/or 数据过滤器:
注意:由于使用了-PipelineVariable
公共参数,此解决方案需要PSv4+。
# The target registry key's full path.
$keyPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs'
$pattern = '*Text*'
# Look for $pattern in both the name and the data.
# Remove `-WhatIf` if the preview suggests that the operation works as intended.
Get-Item -LiteralPath $keyPath -PipelineVariable key |
ForEach-Object Property |
Where-Object {
$valueName = ($_, '')[$_ -eq '(default)'] # translate '(default)' to '' for API
$valueName -like $pattern -or $key.GetValue($valueName) -like $pattern
} |
Remove-ItemProperty -LiteralPath $keyPath -WhatIf
-PipelineVariable key
将 Get-Item
返回的 [Microsoft.Win32.RegistryKey]
实例存储在变量 $key
中供以后在管道中使用。
ForEach-Object Property
枚举目标键的值名称(通过 .Property
注释 属性 PowerShell 添加到输出 [Microsoft.Win32.RegistryKey]
实例,如讨论的那样) .
在Where-Object
脚本块中,$_
然后引用手头的值名称,$key.GetValue(<valueName>)
用于检索关联数据。
- 重要:在
.Property
数组中,PowerShell翻译默认值名称,即empty string (''
) 在 API 级别,进入名称 '(default)'
;因此,如果 $_
是 '(default)'
,您必须在调用 $_.GetValue(<valueName>)
之前将其转换为 ''
,这就是
($_, '')[$_ -eq '(default)']
所做的。
然后将任何符合条件的值名称通过管道传输到 Remove-ItemProperty
,这会将这些名称隐式绑定到其 -Name
参数。
如果您只想到列出匹配值及其数据,请参阅this answer。
[1] Get-ItemProperty -Path $keyPath -Name *Text*
在技术上也有效,但输出是 类型 [pscustomobject]
的单个对象 ,其 你必须通过反射枚举的属性,因为属性名称反映了匹配的值名称;虽然通过 this answer 中所示的 .psobject.properties
可以工作并允许您也通过 data 进行过滤,但陷阱是 PowerShell 的注册表提供程序会自动将其自己的属性添加到属性集合,即 PSPath
、PsParentPath
、PSChildName
、PSDrive
、PSProvider
,这意味着按名称过滤的通配符表达式可能会意外包含它们或者,更糟糕的是,如果键上恰好存在同名的值(即使不太可能),提供者属性会覆盖它们。
注册表提供商太糟糕了。我只希望 get-itemproperty 像这样工作:
# get-itemproperty2.ps1
# get-childitem skips top level key, use get-item
# can't remove default name
param([parameter(ValueFromPipeline)]$key)
process {
$valuenames = $key.getvaluenames()
if ($valuenames) {
$valuenames | foreach {
$value = $_
[pscustomobject] @{
Path = $key -replace 'HKEY_CURRENT_USER',
'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
Name = $Value
Value = $Key.GetValue($Value)
Type = $Key.GetValueKind($Value)
}
}
} else {
[pscustomobject] @{
Path = $key -replace 'HKEY_CURRENT_USER',
'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
Name = ''
Value = ''
Type = ''
}
}
}
然后你可以这样做:
PS C:\users\me> get-item hkcu:\key1 | get-itemproperty2
Path Name Value Type
---- ---- ----- ----
HKCU:\key1 name1 value1 String
HKCU:\key1 name2 value2 String
PS C:\users\me> get-item hkcu:\key1 | get-itemproperty2 | where name -eq name1
Path Name Value Type
---- ---- ----- ----
HKCU:\key1 name1 value1 String
PS C:\users\me> get-item hkcu:\key1 | get-itemproperty2 | where name -eq name1 | Remove-ItemProperty -whatif
What if: Performing the operation "Remove Property" on target "Item: HKEY_CURRENT_USER\key1 Property: name1".
PS C:\users\me> get-childitem -recurse hkcu:\key1 | get-itemproperty2
Path Name Value Type
---- ---- ----- ----
HKCU:\key1\key2 name2 value2 String
HKCU:\key1\key2 default String
HKCU:\key1\key2\key3 name3 value3 String
HKCU:\key1\key2\key3\key4
PowerShell 在其父注册表项的 $\_.Property
中将注册表值(及其注册表数据)显示为数组。如何 select 并仅删除值类似于 \*String\*
的注册表值?
我曾尝试在 Whosebug 和 Google 上搜索高价和低价,尝试了很多涉及 Get-Item
、Get-ItemProperty
、Get-ChildItem
、Select-Object
的组合(包括 -ExpandProperty
参数)和 Where-Object
到 select 我想要的注册表值(在继续合并删除之前)。我现在处于完全无能为力的地步,无法弄清楚如何简单地找到特定注册表项中存在的 \*Text\*
之类的注册表值并将其删除。如此简单的事情似乎如此困难!我不知道如何处理数组中的数据!
Get-Item -Path HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs
注册表项 HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs
的每个注册表值都列为 $\_.Property
下数组的一部分。我期待的结果是我可以做一些大致类似于 $\_.RegistryValue -Like '\*Text\*' | Remove-Item
的事情来删除匹配 \*Text\*
.
为了确保某些词汇的技术用法正确,"registry key" 在 regedit.exe 中显示为一个文件夹。
A "registry value" 是任何类型的条目,例如 REG\_SZ
、REG\_DWORD
、REG\_MZ
等。注册表值包含 "registry data",根据注册表类型,它可能是一个字符串,一个 32 位值(有时表示为 1、0 或 0x000000、0x000001)。
我们经常将 "registry values" 称为 'registry keys'(这是不正确的技术用法),将 "registry data" 称为 'registry values'(也是不正确的技术用法),并且 "registry keys" 作为 folders/location/"this place in the registry".
仅按值名称过滤器删除注册表值:
更新,根据自己的简化:
# The target registry key's full path.
$keyPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs'
# Pass the value name pattern to Remove-ItemProperty's -Name parameter.
# Remove `-WhatIf` if the preview suggests that the operation works as intended.
Remove-ItemProperty -Path $keyPath -Name *Text* -WhatIf
陷阱:如果你想使用通配符表达式比如*Text*
和-Name
,你必须将其与 -Path
而不是 -LiteralPath
组合,即使键路径本身不是通配符; -LiteralPath
,-Name
也按字面意思(逐字)。
如果确实需要使用 -LiteralPath
(例如,如果文字路径包含 *
字符,例如 HKEY_CLASSES_ROOT\*
):
# The target registry key's full path.
$keyPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs'
# Get an array of all value names that match the name wildcard pattern.
$valueNames = (Get-Item -LiteralPath $keyPath).Property -like '*Text*'
# Pass the array of value names to Remove-ItemProperty's -Name parameter.
# Remove `-WhatIf` if the preview suggests that the operation works as intended.
if ($valueNames) {
Remove-ItemProperty -LiteralPath $keyPath -Name $valueNames -WhatIf
}
注意使用 Get-Item
而不是 Get-ItemProperty
。[1]
Get-Item
returns 代表整个键的对象,类型为 [Microsoft.Win32.RegistryKey]
,PowerShell 用 .Property
注释 属性 装饰,其中包含所有键值名称的数组。
重要:在.Property
数组中,PowerShell翻译默认值名称,即empty string (''
) 在 API 级别,进入名称 '(default)'
.
将运算符 -like
应用于 array LHS 使其充当 filter 只有 returns a匹配项的子数组。
Remove-ItemProperty
的 -Name
参数直接接受 数组 的 属性(注册表值)名称以从目标键中删除。
正在按值名称删除值 and/or 数据过滤器:
注意:由于使用了-PipelineVariable
公共参数,此解决方案需要PSv4+。
# The target registry key's full path.
$keyPath = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\SharedDLLs'
$pattern = '*Text*'
# Look for $pattern in both the name and the data.
# Remove `-WhatIf` if the preview suggests that the operation works as intended.
Get-Item -LiteralPath $keyPath -PipelineVariable key |
ForEach-Object Property |
Where-Object {
$valueName = ($_, '')[$_ -eq '(default)'] # translate '(default)' to '' for API
$valueName -like $pattern -or $key.GetValue($valueName) -like $pattern
} |
Remove-ItemProperty -LiteralPath $keyPath -WhatIf
-PipelineVariable key
将Get-Item
返回的[Microsoft.Win32.RegistryKey]
实例存储在变量$key
中供以后在管道中使用。ForEach-Object Property
枚举目标键的值名称(通过.Property
注释 属性 PowerShell 添加到输出[Microsoft.Win32.RegistryKey]
实例,如讨论的那样) .在
Where-Object
脚本块中,$_
然后引用手头的值名称,$key.GetValue(<valueName>)
用于检索关联数据。- 重要:在
.Property
数组中,PowerShell翻译默认值名称,即empty string (''
) 在 API 级别,进入名称'(default)'
;因此,如果$_
是'(default)'
,您必须在调用$_.GetValue(<valueName>)
之前将其转换为''
,这就是($_, '')[$_ -eq '(default)']
所做的。
- 重要:在
然后将任何符合条件的值名称通过管道传输到
Remove-ItemProperty
,这会将这些名称隐式绑定到其-Name
参数。
如果您只想到列出匹配值及其数据,请参阅this answer。
[1] Get-ItemProperty -Path $keyPath -Name *Text*
在技术上也有效,但输出是 类型 [pscustomobject]
的单个对象 ,其 你必须通过反射枚举的属性,因为属性名称反映了匹配的值名称;虽然通过 this answer 中所示的 .psobject.properties
可以工作并允许您也通过 data 进行过滤,但陷阱是 PowerShell 的注册表提供程序会自动将其自己的属性添加到属性集合,即 PSPath
、PsParentPath
、PSChildName
、PSDrive
、PSProvider
,这意味着按名称过滤的通配符表达式可能会意外包含它们或者,更糟糕的是,如果键上恰好存在同名的值(即使不太可能),提供者属性会覆盖它们。
注册表提供商太糟糕了。我只希望 get-itemproperty 像这样工作:
# get-itemproperty2.ps1
# get-childitem skips top level key, use get-item
# can't remove default name
param([parameter(ValueFromPipeline)]$key)
process {
$valuenames = $key.getvaluenames()
if ($valuenames) {
$valuenames | foreach {
$value = $_
[pscustomobject] @{
Path = $key -replace 'HKEY_CURRENT_USER',
'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
Name = $Value
Value = $Key.GetValue($Value)
Type = $Key.GetValueKind($Value)
}
}
} else {
[pscustomobject] @{
Path = $key -replace 'HKEY_CURRENT_USER',
'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
Name = ''
Value = ''
Type = ''
}
}
}
然后你可以这样做:
PS C:\users\me> get-item hkcu:\key1 | get-itemproperty2
Path Name Value Type
---- ---- ----- ----
HKCU:\key1 name1 value1 String
HKCU:\key1 name2 value2 String
PS C:\users\me> get-item hkcu:\key1 | get-itemproperty2 | where name -eq name1
Path Name Value Type
---- ---- ----- ----
HKCU:\key1 name1 value1 String
PS C:\users\me> get-item hkcu:\key1 | get-itemproperty2 | where name -eq name1 | Remove-ItemProperty -whatif
What if: Performing the operation "Remove Property" on target "Item: HKEY_CURRENT_USER\key1 Property: name1".
PS C:\users\me> get-childitem -recurse hkcu:\key1 | get-itemproperty2
Path Name Value Type
---- ---- ----- ----
HKCU:\key1\key2 name2 value2 String
HKCU:\key1\key2 default String
HKCU:\key1\key2\key3 name3 value3 String
HKCU:\key1\key2\key3\key4