PowerShellUtils/Commands/MemoryReport/MemoryReportCommand.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management.Automation;
 
 
namespace PowerShellStandardModule1.Commands.MemoryReport;
 
[Cmdlet(VerbsCommon.Get, "MemoryReport")]
[OutputType(typeof(MemoryRecord))]
public class MemoryReportCommand : PSCmdlet
{
    protected override void ProcessRecord()
    {
        var result = new Impl().GetProcessMemoryUsageReport();
        WriteObject(result);
    }
}
 
public record MemoryRecord
{
    private const int MemoryUnit = 1024;
 
    public string Name { get; set; } = "";
    public decimal Memory { get; set; }
    public double MemoryPercent { get; set; }
    public int ProcessCount { get; set; }
    public double RunningMemorySumPercent { get; set; }
    public decimal RunningMemorySum { get; set; }
 
 
    public MemoryRecord IncreaseUnit(int units)
    {
        var multiplier = (long)Math.Pow(MemoryUnit, units);
        return this with { Memory = Memory * multiplier, RunningMemorySum = RunningMemorySum * multiplier };
    }
 
    public MemoryRecord DecreaseUnit(int units)
    {
        var divisor = (long)Math.Pow(MemoryUnit, units);
        return this with { Memory = Memory / divisor, RunningMemorySum = RunningMemorySum / divisor };
    }
 
    public Process? GetProcess()
    {
        var process = Process.GetProcessesByName(Name).FirstOrDefault();
        return process;
    }
}
 
file class Impl
{
    public List<MemoryRecord> GetProcessMemoryUsageReport()
    {
        var processes = Process.GetProcesses().ToList();
 
        var totalMemory = processes.Sum(process => process.PrivateMemorySize64);
        var data = processes
            .AsParallel()
            .GroupBy(p => p.ProcessName)
            .Select(g => new MemoryRecord
            {
                Name = g.Key,
                Memory = g.Sum(p => p.PrivateMemorySize64),
                ProcessCount = g.Count(),
            })
            .Select(x => x with { MemoryPercent = (double)x.Memory / totalMemory * 100 })
            .OrderBy(x => x.Memory)
            .ToList();
 
        decimal runningMemorySum = 0;
        double runningMemorySumPercent = 0;
 
        foreach (var process in data)
        {
            runningMemorySumPercent += process.MemoryPercent;
            runningMemorySum += process.Memory;
 
            process.RunningMemorySumPercent = runningMemorySumPercent;
            process.RunningMemorySum = runningMemorySum;
        }
 
        return data;
    }
}