You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell脚本开发:对比进程文件与当前进程并提取新进程信息

解决你的PowerShell进程对比脚本疑问

嘿,作为PowerShell新手能梳理出这么清晰的思路真的很不错!我来一步步帮你解决每个疑问,最后给你完整的可运行脚本。

疑问1:如何从文本文件中仅读取进程名称?

用Get-Process > proc.txt生成的文件是默认的表格输出,前3行是标题和分隔线,后面才是进程数据。我们可以这样精准提取名称:

# 读取文件,跳过标题行,过滤空行,分割每行取名称列
$savedProcessNames = Get-Content $inputFile | 
    Select-Object -Skip 3 | 
    Where-Object { $_ -match '\S' } | 
    ForEach-Object {
        # 按任意空白字符分割,取第二个元素(对应Name列)
        ($_ -split '\s+')[1]
    }

这里-Skip 3跳过无用的标题和分隔线,Where-Object过滤掉可能的空行,-split '\s+'处理每行的空格分隔逻辑,确保准确拿到进程名称。

疑问2:如何仅保留新进程(而非所有差异进程)到变量中?

Compare-Object确实会返回两边的差异,但它的SideIndicator属性可以帮我们精准筛选:=>表示**仅存在于右边集合(当前运行进程)**的项,也就是你要找的新进程。我们可以这样过滤:

$currentProcessNames = (Get-Process).Name
# 对比两个名称集合,只保留当前有但文件里没有的进程
$newProcessNames = Compare-Object -ReferenceObject $savedProcessNames -DifferenceObject $currentProcessNames |
    Where-Object { $_.SideIndicator -eq '=>' } |
    Select-Object -ExpandProperty InputObject

用-ExpandProperty InputObject把结果直接转换成名称字符串的集合,方便后续直接调用进程查询命令。

疑问3:如何根据进程名称获取所需的其余进程信息?

直接用Get-Process -Name $newProcessNames就能获取这些进程的完整对象,然后我们可以提取需要的属性,还能计算运行时长:

$newProcesses = Get-Process -Name $newProcessNames |
    Select-Object Id,
                  Name,
                  @{Name='StartTime'; Expression={ $_.StartTime.ToString('yyyy-MM-dd HH:mm:ss') }},
                  @{Name='RunningTime'; Expression={
                      $runtime = (Get-Date) - $_.StartTime
                      # 格式化运行时长为友好的天/时/分格式
                      "{0}天 {1}小时 {2}分钟" -f $runtime.Days, $runtime.Hours, $runtime.Minutes
                  }}

这里用计算属性(@{Name=; Expression=})来格式化启动时间,以及计算并展示易读的运行时长,比直接输出原始TimeSpan对象更直观。

疑问4:如何将信息整齐地整合到一个文件中?

有两种实用方式,按需选择:

  1. 格式化表格输出:适合直接查看,用Format-Table配合Out-File:
$newProcesses | Format-Table -AutoSize | Out-File -FilePath "NewProcesses_$(Get-Date -Format 'yyyyMMddHHmmss').txt" -Encoding UTF8
  1. CSV文件输出:适合后续用Excel等工具分析,用Export-Csv:
$newProcesses | Export-Csv -FilePath "NewProcesses_$(Get-Date -Format 'yyyyMMddHHmmss').csv" -NoTypeInformation -Encoding UTF8

同时我们也可以把结果输出到控制台,方便实时查看:

$newProcesses | Format-Table -AutoSize

完整的脚本实现

把上面的步骤整合起来,做成可以接受文件参数的完整脚本:

<#
.SYNOPSIS
对比保存的进程列表和当前运行进程,找出新增的进程并输出详细信息
.PARAMETER InputFile
由`Get-Process > proc.txt`生成的进程列表文本文件路径
#>
param(
    [Parameter(Mandatory=$true)]
    [string]$InputFile
)

# 1. 验证文件存在并提取保存的进程名称
if (-not (Test-Path $InputFile)) {
    Write-Error "文件 $InputFile 不存在!"
    exit 1
}
$savedProcessNames = Get-Content $InputFile | 
    Select-Object -Skip 3 | 
    Where-Object { $_ -match '\S' } | 
    ForEach-Object { ($_ -split '\s+')[1] }

# 2. 获取当前运行的进程名称
$currentProcessNames = (Get-Process).Name

# 3. 找出仅当前存在的新进程名称
$newProcessNames = Compare-Object -ReferenceObject $savedProcessNames -DifferenceObject $currentProcessNames |
    Where-Object { $_.SideIndicator -eq '=>' } |
    Select-Object -ExpandProperty InputObject

if (-not $newProcessNames) {
    Write-Host "没有发现新增的进程!"
    exit 0
}

# 4. 获取新进程的详细信息并格式化
$newProcesses = Get-Process -Name $newProcessNames |
    Select-Object Id,
                  Name,
                  @{Name='StartTime'; Expression={ $_.StartTime.ToString('yyyy-MM-dd HH:mm:ss') }},
                  @{Name='RunningTime'; Expression={
                      $runtime = (Get-Date) - $_.StartTime
                      "{0}天 {1}小时 {2}分钟" -f $runtime.Days, $runtime.Hours, $runtime.Minutes
                  }}

# 5. 输出到控制台并写入文件
Write-Host "发现以下新增进程:"
$newProcesses | Format-Table -AutoSize

$outputFileName = "NewProcesses_$(Get-Date -Format 'yyyyMMddHHmmss').txt"
$newProcesses | Format-Table -AutoSize | Out-File -FilePath $outputFileName -Encoding UTF8
Write-Host "详细信息已保存到文件:$outputFileName"

使用方法

  1. 先运行Get-Process > proc.txt生成基准进程列表
  2. 运行脚本:.\Find-NewProcesses.ps1 -InputFile .\proc.txt

内容的提问来源于stack exchange,提问作者Patai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:38:55