代码之家  ›  专栏  ›  技术社区  ›  ryanmaddock

是否使用powershell远程删除通配符文件夹中的多个注册表项?

  •  1
  • ryanmaddock  · 技术社区  · 6 年前

    我正在编写一个脚本,该脚本将删除存储在注册表中的App-V密钥。用户打开应用程序时,会在以下位置创建密钥:

    HKLM\SOFTWARE\Microsoft\AppV\MAV\Configuration\Packages\**PackageID**\UserConfigEx\**SID**
    

    这个 PackageID 还有 SID 每次都是唯一的,我希望能够删除 希德 每个 包装 钥匙

    用户将输入SID,然后我希望使用通配符(如果可能)导航到存在的每个包ID。

    到目前为止,我有以下几点:

    #Take user input
    $SID = Read-Host "Please enter users SID"
    $computer = Read-Host "Please enter computer name"
    
    #Test connection
    Write-Host "Connecting to $computer"
    
    if (Test-Connection -ComputerName $computer -Quiet -BufferSize 16 -Count 1) {
    
    #Connect to registry and delete key
    try
    {
        $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(‘LocalMachine’, $computer)
        $regKey = $reg.OpenSubKey(“HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\AppV\\MAV\\Configuration\\Packages\\*\\UserConfigEx\\$SID”,$true )
    
        if ($regkey.GetValue(“$SID”))
        {
            $regKey.DeleteValue(“$SID”)
            Write-Host
            Write-Host "$SID key deleted successfully" -ForegroundColor Green
        }
        else
        {
            Write-Host
            Write-Host "No keys with this SID exist." -ForegroundColor Red
        }
    
    
    } catch {
    
        $ErrorMessage = $_.Exception.Message
        Write-Host "Unable to connect to $computer. Error: $($ErrorMessage)." -ForegroundColor Red 
    
    }
    
    } else 
    
        { 
    
        Write-Host "Unable to connect to $computer. Please ensure correct computer name / IP address has been entered correctly." -ForegroundColor Red
    
    }
    

    如果我运行此功能,我会收到:

    You cannot call a method on a null-valued expression.
    At line:51 char:9
    +     if ($regkey.GetValue(“$SID”))
    +         ~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull
    

    我正在使用一些我得到帮助的脚本 here 远程连接到机器。

    2 回复  |  直到 6 年前
        1
  •  3
  •   mklement0    6 年前
    • 这个 .NET注册表API不支持通配符( * )在关键路径中 .

      • 因此 $regKey.GetValue() 失败了,因为 $regKey = $reg.OpenSubKey(...) 返回 $null 因为找不到密钥,并且在 $null 总是导致问题中引用的错误消息。
    • 相比之下,PowerShell的注册提供商通过 *-Item* Cmdlet确实如此,但您需要 PowerShell remoting 为了远程使用它。

      • Windows Server 2012及更高版本默认启用PowerShell远程处理;在较旧的操作系统版本上,可以通过运行 Enable-PSRemoting 在目标计算机上(需要PSv3+)。

      • 启用PowerShell远程处理后,您需要将代码包装到 Invoke-Command -ComputerName <name> { ... } 打电话(您可能还需要向其传递凭据)。

    • 如果无法启用PowerShell远程处理,则必须 模仿 基于通配符的匹配通过 嵌套循环 基于每个元素的结果通配符匹配 .GetSubkeyNames() .

    • 顺便说一句:你永远不需要逃避 \ \\ 在PowerShell字符串中;PowerShell使用 ` 作为里面的逃逸角色 "..." 所以你唯一需要逃离的角色就是 ` 本身 `` .

    基于PowerShell远程处理的解决方案:

    注意 Invoke-Command -ComputerName ... 一定是从电话里打过来的 高贵的 一场 ( Run As Administrator ):

    try {
      Invoke-Command -ErrorAction Stop -ComputerName $computer {
    
        # Define wildcard-based path.
        $keyPath = "registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AppV\MAV\Configuration\Packages\*\UserConfigEx\$SID"
    
        # See if it matches any keys.
        if (Test-Path $keyPath) {
          # Note: I'm assuming you want to remove the entire *key*.
          #       To only remove a key's *value*, use Remove-ItemProperty.
          Remove-Item -Path $keyPath
        } else {
          Write-Warning "No keys with SID $SID exist."
        }
    
      }
    
    } catch [System.Management.Automation.Remoting.PSRemotingTransportException] {
      # Note: Depending on the specifics of your Invoke-Command call, the reason may
      #       be permissions-related; when in doubt, examine $_
      Write-Warning "Unable to connect to $computer. Please ensure correct computer name / IP address has been entered correctly:`n$_"
    } catch {
      # Other, unexpected failure.
      Throw
    }
    
        2
  •  -2
  •   committhisgit    6 年前

    看起来像是ascii与unicode引号的问题:

    你有:

    $regkey.GetValue(“$SID”)
    

    应将其替换为:

    $regkey.GetValue("$SID")