Last Update: Sep 04, 2024 | Published: Feb 19, 2016
Like most of you, I probably push my daily driver desktop too much. Usually I can tell when I’m running out of resources, simply by diminished responsiveness. With that said, it helps to quantify the sluggish responsiveness to better understand our memory needs. Most of my constraints are memory related, so I threw together a quick tool to show me how much memory is being used and how close to the edge I might be. There are several ways to get memory information, but I decided to use WMI and the Get-CimInstance cmdlet. You can get basic memory statistics from the Win32_OperatingSystem class.
$os = Get-Ciminstance Win32_OperatingSystem
As you can see, there are several memory-related properties.
Those values are all in bytes. I can use these values to calculate a percentage of free memory. I focused on physical memory.
$pctFree = [math]::Round(($os.FreePhysicalMemory/$os.TotalVisibleMemorySize)*100,2)
I’m using the Round() method from the .NET [Math] class to round the value to two decimal places. I can now display the relevant information using Select-Object and a few custom properties.
$os | Select @{Name = "PctFree"; Expression = {$pctFree}}, @{Name = "FreeGB";Expression = {[math]::Round($_.FreePhysicalMemory/1mb,2)}}, @{Name = "TotalGB";Expression = {[int]($_.TotalVisibleMemorySize/1mb)}}
That’s a good start. Once I got that working, I extended my basic concept and came up with this function.
Function Test-MemoryUsage { [cmdletbinding()] Param() $os = Get-Ciminstance Win32_OperatingSystem $pctFree = [math]::Round(($os.FreePhysicalMemory/$os.TotalVisibleMemorySize)*100,2) if ($pctFree -ge 45) { $Status = "OK" } elseif ($pctFree -ge 15 ) { $Status = "Warning" } else { $Status = "Critical" } $os | Select @{Name = "Status";Expression = {$Status}}, @{Name = "PctFree"; Expression = {$pctFree}}, @{Name = "FreeGB";Expression = {[math]::Round($_.FreePhysicalMemory/1mb,2)}}, @{Name = "TotalGB";Expression = {[int]($_.TotalVisibleMemorySize/1mb)}} }
I used and If/ElseIf structure to evaluate the percentage of free memory and determine a status. Remember in an if statement, PowerShell stops checking after the first true evaluation, so I need to put my comparisons in ascending order.
I can even create an alias for it to save some typing.
Set-Alias -Name tmu -Value Test-MemoryUsage
But I want a bit more from this, perhaps something in color to highlight a critical condition. This should be simple enough. All I need to do is look at the status property and define an associated color.
$data = Test-MemoryUsage Switch ($data.Status) { "OK" { $color = "Green" } "Warning" { $color = "Yellow" } "Critical" { $color = "Red" } }
But let’s be real. I’m not going to type that every single time. Instead I built a second function, which has the sole purpose of displaying the data from Test-MemoryUsage into a report form that suits my needs complete with its own alias.
Function Show-MemoryUsage { [cmdletbinding()] Param() #get memory usage data $data = Test-MemoryUsage Switch ($data.Status) { "OK" { $color = "Green" } "Warning" { $color = "Yellow" } "Critical" {$color = "Red" } } $title = @" Memory Check ------------ "@ Write-Host $title -foregroundColor Cyan $data | Format-Table -AutoSize | Out-String | Write-Host -ForegroundColor $color } set-alias -Name smu -Value Show-MemoryUsage
Let me point out that normally you would not include any sort of formatting in a PowerShell function, nor would you use Write-Host to display results. But in this situation, that’s exactly what I want. The only purpose of this function is to show information on the screen.
I still have the first function if I need something in the pipeline. I put both functions and the Set-Alias commands in a PowerShell script and dot source it in my PowerShell profile.
. C:ScriptsCheck-MyMemory.ps1
You could also create a module. You could even extend these tools to query remote computers. You would want to include the computername in the output and maybe even a timestamp. Again, you could use the test function if you need to export the memory data to a CSV file or process it further in PowerShell. You can also use the show function to display information to the screen.
I realize it can be struggle to create a PowerShell tool that writes to the pipeline and is still user friendly. If you are running into that situation, perhaps you need to split your needs into multiple commands, as I’ve done in this example.