将所有正在运行的进程写入PowerShell中的文本文件

时间:2018-09-11 13:21:56

标签: powershell

此代码的目的是从特定文件夹中获取所有已使用的可执行文件的列表。一个月后,我们将删除不在此列表中的所有exe文件。

我目前使用以下方法得到正确的结果:

while ($true) {
    foreach ($process in Get-Process | where {$_.Path -imatch 'ksv'} | select -Unique) {
        $dir = $process | Get-ChildItem;
        New-Object -TypeName PSObject -Property @{
            'Path' = $process.Path;
        } | Out-String | Add-Content -LiteralPath Z:\processList.txt 
     }
     Get-Content Z:\processList.txt | sort | Get-Unique > Z:\uniqueprocesslist.txt
 }

我将摆脱while循环,因为它最终将作为服务运行。

问题是它会在processlist.txt中创建一个巨大的列表,我想删除该列表以节省空间。

我试图提出一种更好的解决方案,该解决方案在添加新的处理路径之前扫描文本文件以查看路径是否已被写入。我不确定自己在做什么错,但是什么也没写到文本文件

while ($true) {
    foreach ($process in Get-Process | where {$_.Path -imatch 'ksv'} | select -Unique) {
        $dir = $process | Get-ChildItem;
        $progPath = New-Object -TypeName PSObject -Property @{
            'Path' = $process.Path
        }
        $file = Get-Content "Z:\processList.txt"
        $containsLine = $file | %{$_ -match $progPath}
        if ($containsLine -contains $false) {
            Add-Content -LiteralPath Z:\processList.txt
        }
    }
}

2 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,则希望在文件的特定目录中构建可执行文件的“最近使用”列表,并在每次运行脚本时更新该(唯一)列表。

应该执行以下操作:

$listfile = 'Z:\processlist.txt'

# Build a dictionary from known paths, so that we can check for already known
# paths with an index lookup instead of a linear search over an array.
$list = @{}
if (Test-Path -LiteralPath $listfile) {
    Get-Content $listfile | ForEach-Object {
        $list[$_] = $true
    }
}

# List processes, expand their path, then check if the path contains the
# string "ksv" and isn't already known. Append the results to the list file.
Get-Process |
    Select-Object -Expand Path |
    Sort-Object -Unique |
    Where-Object {$_ -like '*ksv*' -and -not $list.ContainsKey($_)} |
    Add-Content $listfile

出于性能原因,使用哈希表查找和通配符匹配,因为它们比数组和正则表达式匹配中的线性搜索要快得多。

答案 1 :(得分:0)

while ($true) {
    $file = Get-Content "Z:\processList.txt"
    $KSVPaths = Get-Process | 
                      Where-Object {$_.Path -imatch 'ksv'} |
                        Select-Object -ExpandProperty Path |
                          Select-Object -Unique
    ForEach ($KSVPath in $KSVPaths) {
         if ($KSVPath -notin $file) {
             Add-Content -Path $file -Value $KSVPath
         }
    }
}