Powershell Pwershell.registry搜索项的值,其显示名称类似于&引用;

Powershell Pwershell.registry搜索项的值,其显示名称类似于&引用;,powershell,get,registry,key,Powershell,Get,Registry,Key,在Powershell的帮助下,我需要找到注册表项,其中的值Displayname类似于“Cisco”,并从值name“Uninstallstring”获取此项数据。 我知道这听起来有点奇怪,但是这个应用程序在每台计算机上都有不同的卸载字符串 所以 ForEach对象-InputObject(获取ChildItem'HKLM:\software\microsoft\windows\currentversion\uninstall'){ $single_item=$124;获取项目 $single

在Powershell的帮助下,我需要找到注册表项,其中的值Displayname类似于“Cisco”,并从值name“Uninstallstring”获取此项数据。 我知道这听起来有点奇怪,但是这个应用程序在每台计算机上都有不同的卸载字符串

所以

ForEach对象-InputObject(获取ChildItem'HKLM:\software\microsoft\windows\currentversion\uninstall'){
$single_item=$124;获取项目
$single_item_properties=$single_item | Get ItemProperty |选择对象-属性DisplayName,卸载字符串|其中对象{($u.DisplayName-类似“*Cisco*TSP*”)}
$uninstall_str=($single_item_properties |选择uninstall字符串)
$str_to_execute=$uninstall_str.UninstallString-替换“.*”,“”
$str_执行
启动进程-FilePath$str\u to\u execute-ArgumentList'-s','-f1“\\sandbox\Common.Installs\Utils\un.iss”'-Wait-PassThru
}
这个脚本告诉我们错误

卸载字符串


“C:\Program Files(x86)\InstallShield安装信息{01A05F96-E34D-4308-965C-65DCA4AF114D}\setup.exe”

启动进程:由于以下错误,无法执行此命令:系统找不到指定的文件

问题是结果不是字符串类型


我无法将其转换为字符串。

您显示的输出似乎与您提供的代码不匹配。当我执行您的代码时,我会根据自己的搜索得到
uninstallstring
。当我第一次看到输出时,我想“哦……他忘了他正在传递一个带有属性字符串的对象来启动进程”。但是当我查看您的代码时,我可以看到您通过执行
$uninstall\u str.UninstallString
来解释这一点。所以我不确定到底是什么错,但一个改进是使用
选择对象的
-ExpandProperty

$uninstall_str = $single_item_properties | Select -ExpandProperty UninstallString
$str_to_execute=$uninstall_str -replace '" .*','"'
但如果你愿意,我们可以做一条班轮

$str_to_execute = ($single_item_properties).UninstallString -replace '" .*','"'

这里有几个问题

  • 尽管每个对象的都有-InputObject参数,但它主要是为获取管道输入而设计的。正如文件所说

    将InputObject参数用于ForEach对象时,即使InputObject值是命令结果的集合,例如–InputObject(Get Process)-也会将InputObject值视为单个对象,而不是将命令结果管道化到ForEach对象。由于InputObject无法从数组或对象集合返回单个属性,因此建议如果使用ForEach对象对定义属性中具有特定值的对象的对象集合执行操作,则在管道中使用ForEach对象

    在代码中,脚本块只执行一次,$single_item实际上是一个数组,包含Get ChildItem的整个输出。为了一次迭代一个元素的结果,您需要通过管道将输出传输到每个对象

    Get ChildItem'HKLM:\software\microsoft\…'| ForEach对象{
    
    …或者更好的是,使用foreach控制结构,它通常运行得更快(尽管它使用更多内存):

    foreach($single_item in(获取ChildItem'HKLM:\software\microsoft\…)){
    
  • 通过管道将每个元素传送到获取项目是多余的。您可以直接通过管道传送到获取项目属性

  • 使用Where Object对其进行筛选不需要选择属性。因此,使用
    选择对象-属性DisplayName,UninstallString
    ,这将创建一个具有两个属性的PSCustomObject,然后在以后的操作中检索该PSCustomObject的UninstallString属性是多余的代码。只需先使用Where Object进行筛选,然后使用
    获取卸载字符串的值;选择-ExpandProperty UninstallString

    (有关使用-expandProperty开关的原因说明,请参阅。)

  • 使用-ExpandProperty,如果返回的任何键没有UninstallString属性,则会出现错误,因此您可能需要将
    -ErrorAction SilentlyContinue
    添加到Select Object语句中

  • 总而言之:

    foreach($single_item in(获取ChildItem'HKLM:\software\microsoft\windows\currentversion\uninstall')){
    $uninstall\u str=$single\u item`
    |获取ItemProperty`
    |?{$\.DisplayName-类似于“*Cisco*TSP*”}`
    |选择对象-ExpandProperty卸载字符串-ErrorAction SilentlyContinue
    $str_to_execute=$uninstall_str-replace'.*',''
    启动进程-FilePath$str\u to\u execute-ArgumentList'-s','-f1“\\sandbox\Common.Installs\Utils\un.iss”'-Wait-PassThru}
    }
    
    如果保证不超过一个匹配项,您可以这样做:

    $str\u to\u execute=(
    获取子项“HKLM:\software\microsoft\windows\currentversion\uninstall”`
    |获取ItemProperty`
    |?{$\.DisplayName-类似“Microsoft*”}
    ).uninstallstring$uninstall_str-replace'.*','''
    
    即使PowerShell v3+中有多个匹配密钥,更紧凑的版本实际上也可以工作,但在v2中,如果有多个匹配密钥,它将返回null


    顺便说一句,Where Object的缩写。类似地,%是每个对象的缩写(仅当您在管道中将其用作过滤器时,但无论如何都应该使用它)

    顺便说一句,在编辑您的问题时,我注意到您是否真的需要一个循环还不清楚。是否有可能多个键可能与
    *Cisco*TSP*
    匹配,并且您希望对所有键执行卸载命令,或者是否正在执行