使用 PowerShell 查找过时的安装的程序

使用 PowerShell 查找过时的安装的程序

除了以递归方式访问 Program Files 的每个子文件夹以获取最新访问日期之外,有没有更简单的方法可以使用 PowerShell 查找过时的安装的程序?

这似乎是一个非常基本的常见需求,应该有一个比递归获取子项并比较所有文件日期更简单的命令。

答案1

您可以通过两种方式执行此操作:注册表查询或通过 CIM/WMI(您可以搜索“列出已安装的软件 powershell”第一个链接已经告诉你这一点。)。

CIM/WMI 方式的工作方式如下:

# Local Machine:
Get-CimInstance Win32_Product 

# Remote Machine:
$CimSession = New-CimSession Servername -Credential (Get-Credential)
Get-CimInstance Win32_Product -CimSession $CimSession

# Pipe to Where-Object to Filter vendors, or names etc.
Get-CimInstance Win32_Product | Where-Object {$_.Vendor -eq 'SomeVendor'}

不过我个人总是查询注册表。您需要查询以下键来获取 32 位和 64 位应用程序:

  • HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall
  • HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

我为此编写了一个函数,我经常使用它。见下文。

用法:

# Lists all installed Programs
Get-InstalledSoftware

# List only software that matches a filter
Get-InstalledSoftware *firefox*

# List software that matches a filter and return all properties
Get-InstalledSoftware *firefox* -properties *

# Do the same on remote machines
Get-InstalledSoftware -ComputerName ServerA, ServerB -Credential (Get-Credential)

该函数如下:

function Get-InstalledSoftware {
    
    param (
        # filters displayname of installed apps to search for
        [string]$filter = '*', 
        # tell the function what properties should be returned
        [string[]]$properties = @("DisplayName","InstallDate","InstallLocation"), 
        # remote computername(s)
        [string[]]$ComputerName,
        # credential for remote computer(s)
        [pscredential]$Credential
    )

    # reg paths to query
    $regpath = @(
        "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
        "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
    )

    # put together the splat for remote usage of function
    $splat = @{}
    if ($ComputerName) { $splat['ComputerName'] = $ComputerName }
    if ($Credential) { $splat['Credential'] = $Credential }

    # Run the command, either locally or remote if $splat has values
    Invoke-Command @splat -ScriptBlock { 
        param ($regpath, $filter, $properties)
        $regpath | ForEach-Object { Get-ItemProperty $_ } | 
        Where-Object { ![string]::IsNullOrEmpty($_.DisplayName) -and $_.DisplayName -like $filter } | 
        Select-Object $properties 
    } -ArgumentList $regpath, $filter, $properties
}

相关内容