【问题标题】:In Powershell how to bypass a certain Product code/Patch code when deleting old .msi?在 Powershell 中删除旧 .msi 时如何绕过某个产品代码/补丁代码?
【发布时间】:2019-12-06 14:28:58
【问题描述】:

大家好,希望有人可以帮助我。我有一个 powershell 脚本,可以识别旧的 .msi 并将它们从 Windows/Installer 文件夹中删除,但我需要添加一些代码来绕过或(跳过)某个产品 ID/源哈希。基本上我需要脚本来跳过这个: {1610CB69-BE80-41B9-9B77-E346C1DA12F3} 并且不要将其删除。有谁知道我如何做到这一点?

这是我的脚本:

<#
    This script uses VB script to identify which files need to be saved and then removes everything else.
#>

$VBSFile = @"
'' Identify which patches are registered on the system, and to which
'' products those patches are installed.
'Option Explicit
Dim msi : Set msi = CreateObject("WindowsInstaller.Installer")
'Output CSV header
WScript.Echo "The data format is ProductCode, PatchCode, PatchLocation"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("output.txt", True)
objFile.WriteLine "ProductCode, PatchCode, PatchLocation"
objFile.WriteLine ""
' Enumerate all products
Dim products : Set products = msi.Products
Dim productCode
For Each productCode in products
    ' For each product, enumerate its applied patches
    Dim patches : Set patches = msi.Patches(productCode)
    Dim patchCode
    For Each patchCode in patches
        ' Get the local patch location
        Dim location : location = msi.PatchInfo(patchCode, "LocalPackage")
        objFile.WriteLine productCode & ", " & patchCode & ", " & location

    Next
Next
WScript.Echo "Data written to output.txt, these are the registered objects and SHOULD be kept!"
"@

$VBSFile | Set-Content .\WiMsps.vbs

cscript .\WiMsps.vbs 

$savelist = Import-Csv .\output.txt

$filelocation = $savelist | select -ExpandProperty PatchLocation

#First pass to remove exact file names
dir C:\windows\Installer -file | ForEach-Object{
    $fullname = $_.FullName
    if($filelocation | Where-Object{$_ -like "*$fullname*"}){
        "Keeping $fullname"
    }
    else{
        Remove-Item $fullname -Force -Verbose
    }


}

#second pass to match product and patch codes
dir C:\windows\Installer -Directory | ForEach-Object{
    $fullname = $_.name
    if($savelist | Where-Object{$_.ProductCode -like "*$fullname*" -or $_.PatchCode -like "*$fullname*" }){
        "Keeping $fullname"
    }
    else{
        Remove-Item $_.fullname -Force -Verbose -Recurse
    }

}
pause

基本上现在它正在删除所有无法找到依赖源的内容。或者至少我认为它是......我从其他人那里得到了这个脚本,所以是的,基本上我不知道该怎么做。

【问题讨论】:

  • 如果匹配值否从数组中删除?也可以对多个值执行此操作 [Array]$index = $row.Split(" ") -ne $Guid1 -ne $Guid2
  • 是的,如果它匹配一个值。那么我会把它放在哪里呢? [Array]$index = $row.Split(" ") -ne $Guid1 -ne $Guid2 我猜在 (" ") 里面可以放产品代码,它会跳过吗?
  • 在您遍历并将 GUIDS 列表放入一个数组之后。那么您指定的 guid 将被删除
  • 在不知道自己在做什么的情况下,不能像这样手动破解此文件夹,即使这样也很危险。我在下面添加了一些建议。总体目标是什么:just cleanupcreate disk space 还是什么?

标签: powershell windows-installer delete-file


【解决方案1】:

MSI 缓存文件夹你不能在这个文件夹里乱来!您通常会得到无法卸载的产品

  • 这是一个“超级隐藏”文件夹,这意味着即使您显示隐藏文件它也不会显示,您还必须“显示操作系统文件”。这有力地暗示了它的重要性以及与改变其内容相关的危险。
  • 所有内容都是自动管理的。一些剩余文件可能在此处,但应通过操作系统内置的其他机制清理它们 - 例如 cleanmgr.exe。在下面的链接中了解更多信息。卸载相关产品时,也应删除这些文件。

磁盘空间:如果您想清理一些磁盘空间,不妨试试以下建议:Ways to clear disk space。还有a long version of the same list。请至少访问第一个链接并找到有关 cleanmgr.exe 的信息。您还可以从运行对话框运行较新的 ms-settings:storagesense。链接中也有描述。

工具摘要:可通过 Windows Key + Tap R 访问:

  • cleanmgr.exe
  • ms-settings:storagesense

COM 自动化:作为记录,您可以通过 COM 自动化选择性地卸载产品(不包括您的产品),如下所示:

Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
Set products = installer.ProductsEx("", "", 7)

'Iterate over all MSI packages on the box
For Each product In products
   If LCase("{1610CB69-BE80-41B9-9B77-E346C1DA12F3}") = LCase(product.productcode) Then
        MsgBox "Found Product: " + product.InstallProperty("ProductName")
      Else
        ' Can run uninstall here via COM method - ADMIN RIGHTS!
        ' installer.ConfigureProduct product.productcode, 0, 2       
   End If
Next

MsgBox "Finished."

Powershell MSI 模块:还有一个Powershell module for MSI made by deployment guru Heath Stewart。 Github.com:https://github.com/heaths/psmsi。我没有积极使用它,但肯定这个模块已经解决了大多数问题,并且会比通过 COM 更好的选择?就我个人而言,我只会使用 VBScript 和 COM - 在我看来更容易。

【讨论】:

  • 天啊,非常感谢。是的,这绝对是我正在寻找的答案。是的,我们一直试图远离 Installer 文件夹,但注意到一些非常旧的大型 .msi(s) 只是占用空间。实际上,我们现在正在做 cleanmgr 并使用存储感知。谢谢你的回答!
  • 您现在有不能卸载的产品吗? (当您干预此文件夹时往往会发生)。如果是这样,请参阅此列表:Get rid of un-uninstallable packagesMS Fix It 的条目对于小规模来说应该足够了。如果答案是可以接受的,请勾选左侧的框以将其设置为接受。
  • 是的,我们的一个应用程序出现了问题,因为软件包已被删除,只是不想在其他计算机上为同一应用程序重复该问题。好的,我检查了你的答案,但它不会让我投票,因为我还是这个论坛的新手
  • 没关系 - 我会给你一票赞成这个格式很好的问题。欢迎来到论坛。
猜你喜欢
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-05
  • 1970-01-01
相关资源
最近更新 更多