I’ve had the script I wrote to keep a record of certain processes run time running for a while (I’m using it to keep a log of the games I play and when). One thing I noticed though is that there are plenty of processes matching the path I’m interested in (anything with “games” in the file path) that I’m not interested in. Launchers, background tasks, updaters or services for example.
What I need to do is set a list of exclusions and then make sure any process that matches the other criteria isn’t listed in the exclusions. The changes are below;
First, the exclusion list;
$Exceptions=@("C:\Games\Steam\bin\steamwebhelper.exe","C:\Games\Frontier\EDLaunch\WatchDog.exe", "C:\Games\Steam\bin\steamwebhelper.exe","C:\Games\Frontier\EDLaunch\EDLaunch.exe", "C:\Games\Steam\steamerrorreporter.exe","C:\Games\Steam\Steam.exe", "C:\Games\Steam\GameOverlayUI.exe")
Here I’ve set a list of exclusions, creating an array of full paths to processes I’m not interested in recording.
And the last update is changing the code that gets the list of matching processes to exclude all of them that have a path listed in the exclusion array;
$FilteredProcesses=get-process | ? {($_.Path -like $SourceFolder) -and -not ($Exceptions -contains $_.Path)} | select Path,@{ name="Start";expression={$_.StartTime}},@{name="RunningTimeInSeconds"; expression={(New-TimeSpan -Start ($_.StartTime)).TotalSeconds}} $FilteredProcesses
-and -not ($Exceptions -contains $_.Path) is the relevant addition; it just makes sure the $Exceptions array does not contain the path of the process the script is currently examining.
Here’s the updated script in full;
[CmdletBinding()] param ( [string]$SourceFolder="*games*", [string]$DataFilePath="d:\users\neil\Documents\ProcessTimes.csv" ) $DefaultDataFileName="ProcessTime.csv" $Exceptions=@("C:\Games\Steam\bin\steamwebhelper.exe","C:\Games\Frontier\EDLaunch\WatchDog.exe", "C:\Games\Steam\bin\steamwebhelper.exe","C:\Games\Frontier\EDLaunch\EDLaunch.exe", "C:\Games\Steam\steamerrorreporter.exe","C:\Games\Steam\Steam.exe", "C:\Games\Steam\GameOverlayUI.exe") if ($DataFilePath -eq "") { $DataFilePath=$PSScriptRoot + "\" +$DefaultDataFileName } function Get-MatchingProcess { param ( [System.Array]$DataArray, [parameter(Mandatory=$True)] [System.Object]$Item ) $DataArray | ? {($_.Path -eq $Item.Path) -and ( (get-date -date $_.Start -Millisecond 0) -eq ( get-date -date $Item.Start -Millisecond 0))} | Select-Object -First 1 } Write-Verbose "Process Search String : $SourceFolder" Write-Verbose "Data File Location : $DataFilePath" while($true) { Write-Verbose ("Running cycle.") if (Test-Path $DataFilePath) { [System.Array]$Data=Import-Csv -Delimiter ',' -LiteralPath $DataFilePath }else { $Data=@() } $FilteredProcesses=get-process | ? {($_.Path -like $SourceFolder) -and -not ($Exceptions -contains $_.Path)} | select Path,@{ name="Start";expression={$_.StartTime}},@{name="RunningTimeInSeconds"; expression={(New-TimeSpan -Start ($_.StartTime)).TotalSeconds}} $FilteredProcesses Foreach ($Process in $FilteredProcesses) { $Result=Get-MatchingProcess $Data $Process if ($Result) { Write-Verbose "Modifying Existing Record." $Result.RunningTimeInSeconds=(New-TimeSpan -Start $Process.Start).TotalSeconds }else { Write-Verbose "Adding New Record." $Data=$Data+$Process } } $Data | Export-Csv -Path $DataFilePath -NoTypeInformation sleep 20 }