使用 powershell 删除 windows 上的应用程序而不查询 win32
Delete an app on windows using powershell without querying win32
所以我想删除一个我不知道其产品 ID 的应用程序。我知道您可以使用 msiexec.exe /x 然后使用产品 ID 删除应用程序。我将如何在命令行中获取特定应用程序的产品 ID 并将值存储在变量中,以便我可以将变量放在删除命令中?
提前致谢!!
总是get-package。除了我,没有人知道这件事。这应该适用于 msi 安装。
get-package *software* | uninstall-package
如果您知道确切的名称,这应该可行。 Uninstall-package 不接受通配符。
uninstall-package 'Citrix HDX RealTime Media Engine 2.9.400'
有时,烦人的是,它会提示先安装 nuget:
install-packageprovider nuget -force
如果不是安装 msi,而是安装程序,则需要更多的字符串处理。您可能需要在末尾添加 '/S' 或其他内容以进行静默安装。
$prog,$myargs = -split (get-package 'Remote Support Jump Client *' |
% { $_.metadata['uninstallstring'] })
& $prog $myargs
也许在这种情况下 运行 它:
& "C:\Program Files (x86)\Citrix\Citrix WorkSpace 2202\TrolleyExpress.exe" /uninstall /cleanup /silent
或
$uninstall = get-package 'Citrix Workspace 2202' |
% { $_.metadata['uninstallstring'] }
$split = $uninstall -split '"'
$prog = $split[1]
$myargs = -split $split[2]
$myargs += '/silent'
& $prog $myargs
我想我有一种方法可以在有或没有 double-quotes 的情况下实现 non-msi 安装:
$uninstall = get-package whatever | % { $_.metadata['uninstallstring'] }
$prog, $myargs = $uninstall | select-string '("[^"]*"|\S)+' -AllMatches |
% matches | % value
$prog = $prog -replace '"',$null
$silentoption = '/S'
$myargs += $silentoption # whatever silent uninstall option
& $prog $myargs
这是我使用的脚本。你必须知道包的显示名称是什么......就像你去删除程序一样,它的名称是什么。它适用于我使用 WiX 创建的 MSI 包,但不适用于所有包。如果您使用的是 Windows 10+,则可以考虑使用 winget
命令。 winget 有一个卸载选项。
param (
[Parameter(Mandatory = $true)]
[string] $ProductName,
[switch] $Interactive = $false,
[switch] $key = $false
)
$log_directory = "c:\users\public"
# $log_directory = "c:\erase\logs"
if ((-not $Interactive) -and (-not (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
{
$interactive = $true
# echo "Not elevated, needs to be interactive"
}
$found = $null
$productsKeyName = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products"
$rootKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($productsKeyName)
foreach ($productKeyName in $rootKey.GetSubKeyNames())
{
#$productKeyName
try
{
$installPropertiesKey = $rootKey.OpenSubKey("$productKeyName\InstallProperties")
if ($installPropertiesKey)
{
$displayName = [string] $installPropertiesKey.GetValue("DisplayName")
if ( (! [string]::IsNullOrEmpty($displayName)) -and ($displayName -eq $ProductName))
{
$found = $productKeyName
break
}
}
}
catch
{
}
finally
{
if ($installPropertiesKey) { $installPropertiesKey.Close() }
}
}
$rootKey.Close()
if (-not $found)
{
return "First search could not find $ProductName"
}
$localPackage = $null
if (! [string]::IsNullOrEmpty($found))
{
try
{
$regkey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("$productsKeyName$found\InstallProperties")
$localPackage = $regkey.GetValue("LocalPackage")
}
catch
{
}
finally
{
if ($regkey) { $regkey.Close() }
}
}
if ($key)
{
return "Found key: $found"
}
if (![string]::IsNullOrEmpty($localPackage) -and (Test-Path $localPackage))
{
$logflags = "/lv*"
$logname = (Join-Path $log_directory "$ProductName_uninstall.log")
$args = @($logflags, $logname, "/X", $localPackage)
if (!$Interactive) { $args += "/q" }
&msiexec $args
}
else
{
"Could not find uninstall package: $ProductName"
}
所以我想删除一个我不知道其产品 ID 的应用程序。我知道您可以使用 msiexec.exe /x 然后使用产品 ID 删除应用程序。我将如何在命令行中获取特定应用程序的产品 ID 并将值存储在变量中,以便我可以将变量放在删除命令中?
提前致谢!!
总是get-package。除了我,没有人知道这件事。这应该适用于 msi 安装。
get-package *software* | uninstall-package
如果您知道确切的名称,这应该可行。 Uninstall-package 不接受通配符。
uninstall-package 'Citrix HDX RealTime Media Engine 2.9.400'
有时,烦人的是,它会提示先安装 nuget:
install-packageprovider nuget -force
如果不是安装 msi,而是安装程序,则需要更多的字符串处理。您可能需要在末尾添加 '/S' 或其他内容以进行静默安装。
$prog,$myargs = -split (get-package 'Remote Support Jump Client *' |
% { $_.metadata['uninstallstring'] })
& $prog $myargs
也许在这种情况下 运行 它:
& "C:\Program Files (x86)\Citrix\Citrix WorkSpace 2202\TrolleyExpress.exe" /uninstall /cleanup /silent
或
$uninstall = get-package 'Citrix Workspace 2202' |
% { $_.metadata['uninstallstring'] }
$split = $uninstall -split '"'
$prog = $split[1]
$myargs = -split $split[2]
$myargs += '/silent'
& $prog $myargs
我想我有一种方法可以在有或没有 double-quotes 的情况下实现 non-msi 安装:
$uninstall = get-package whatever | % { $_.metadata['uninstallstring'] }
$prog, $myargs = $uninstall | select-string '("[^"]*"|\S)+' -AllMatches |
% matches | % value
$prog = $prog -replace '"',$null
$silentoption = '/S'
$myargs += $silentoption # whatever silent uninstall option
& $prog $myargs
这是我使用的脚本。你必须知道包的显示名称是什么......就像你去删除程序一样,它的名称是什么。它适用于我使用 WiX 创建的 MSI 包,但不适用于所有包。如果您使用的是 Windows 10+,则可以考虑使用 winget
命令。 winget 有一个卸载选项。
param (
[Parameter(Mandatory = $true)]
[string] $ProductName,
[switch] $Interactive = $false,
[switch] $key = $false
)
$log_directory = "c:\users\public"
# $log_directory = "c:\erase\logs"
if ((-not $Interactive) -and (-not (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)))
{
$interactive = $true
# echo "Not elevated, needs to be interactive"
}
$found = $null
$productsKeyName = "SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products"
$rootKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey($productsKeyName)
foreach ($productKeyName in $rootKey.GetSubKeyNames())
{
#$productKeyName
try
{
$installPropertiesKey = $rootKey.OpenSubKey("$productKeyName\InstallProperties")
if ($installPropertiesKey)
{
$displayName = [string] $installPropertiesKey.GetValue("DisplayName")
if ( (! [string]::IsNullOrEmpty($displayName)) -and ($displayName -eq $ProductName))
{
$found = $productKeyName
break
}
}
}
catch
{
}
finally
{
if ($installPropertiesKey) { $installPropertiesKey.Close() }
}
}
$rootKey.Close()
if (-not $found)
{
return "First search could not find $ProductName"
}
$localPackage = $null
if (! [string]::IsNullOrEmpty($found))
{
try
{
$regkey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("$productsKeyName$found\InstallProperties")
$localPackage = $regkey.GetValue("LocalPackage")
}
catch
{
}
finally
{
if ($regkey) { $regkey.Close() }
}
}
if ($key)
{
return "Found key: $found"
}
if (![string]::IsNullOrEmpty($localPackage) -and (Test-Path $localPackage))
{
$logflags = "/lv*"
$logname = (Join-Path $log_directory "$ProductName_uninstall.log")
$args = @($logflags, $logname, "/X", $localPackage)
if (!$Interactive) { $args += "/q" }
&msiexec $args
}
else
{
"Could not find uninstall package: $ProductName"
}