除了以递归方式访问 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
}