1

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

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

PackageID和 每次都是唯一的,SID我希望能够删除SID每个键中的子PackageID键。

用户将输入 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

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

4

2 回答 2

2
  • .NET 注册表 API 不支持*密钥路径中的通配符() 。

    • 结果,$regKey.GetValue()失败,因为由于找不到密钥而$regKey = $reg.OpenSubKey(...)返回,并且调用方法总是导致问题中引用的错误消息。$null$null
  • 相比之下,PowerShell 的注册表提供程序通过*-Item*cmdlet 可以,但您需要PowerShell 远程处理才能远程使用它。

    • 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
}
于 2018-05-24T13:44:10.233 回答
-2

看起来像 ascii vs unicode 引号问题:

你有:

$regkey.GetValue(“$SID”)

应该替换为:

$regkey.GetValue("$SID")
于 2018-05-24T13:38:17.333 回答