25

I'm trying to get the physical memory size using PowerShell, but without using get-wmiobject.

I have been using the following PS cmdlet to get the physical memory size, but the value changes with each new poll.

(get-counter -counter "\Memory\Available Bytes").CounterSamples[0].CookedValue + 
(get-counter -counter "\Memory\Committed Bytes").CounterSamples[0].CookedValue

In general, this gives me a value around: 8605425664 bytes

I'm also testing the value I get from adding these counters with the returned value from

(get-wmiobject -class "win32_physicalmemory" -namespace "root\CIMV2").Capacity

This gives me the value: 8589934592 bytes

So, not only is the total physical memory calculated from counters changing, but it's value differs from the WMI value by a couple megabytes. Anyone have any ideas as to how to get the physical memory size without using WMI?

pnuts
  • 58,317
  • 11
  • 87
  • 139
eltaco431
  • 740
  • 2
  • 10
  • 24

13 Answers13

33

If you don't want to use WMI, I can suggest systeminfo.exe. But, there may be a better way to do that.

(systeminfo | Select-String 'Total Physical Memory:').ToString().Split(':')[1].Trim()
ravikanth
  • 24,922
  • 4
  • 60
  • 60
  • 1
    Interesting, on my system which has 8GB installed (or exactly 8192MB), system info reports that I have a total of 8155MB. I suspect that not all of the 8GB is usable by the system which could account for the difference. – Keith Hill Jul 16 '13 at 16:43
  • Yes. Your BIOS may be mapping certain amount of memory for BIOS shadowing functions. – ravikanth Jul 16 '13 at 16:44
  • So the question is - what is the OP actually after? Installed memory or total memory available for use by the computer? – Keith Hill Jul 16 '13 at 16:47
  • I guess installed memory. Using systeminfo.exe, you cannot actually get the accurate value but that is the only option without WMI, AFAIK. – ravikanth Jul 16 '13 at 16:48
  • Yes. I'm looking for installed memory. Thank you ravikanth. – eltaco431 Jul 16 '13 at 17:15
  • +1 Slight caveat: does not work on non-english OS, because the output is localized. But that's easy to fix, alternatively `(systeminfo | Select-String ' MB')[0]` did the trick for me. – JensG Mar 05 '16 at 15:04
  • Another Way using syteminfo with the format CSV option and converting to a structured powershell object to get the value `systeminfo /FO CSV | ConvertFrom-CSV | select "Total Physical Memory"` – Ricc Babbitt Oct 30 '19 at 03:17
30

Let's not over complicate things...:

(Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum).sum /1gb
double-beep
  • 5,031
  • 17
  • 33
  • 41
Zack A
  • 688
  • 5
  • 11
17

I'd like to make a note of this for people referencing in the future.

I wanted to avoid WMI because it uses a DCOM protocol, requiring the remote computer to have the necessary permissions, which could only be setup manually on that remote computer.

So, I wanted to avoid using WMI, but using get-counter often times didn't have the performance counter I wanted.

The solution I used was the Common Information Model (CIM). Unlike WMI, CIM doesn't use DCOM by default. Instead of returning WMI objects, CIM cmdlets return PowerShell objects.

CIM uses the Ws-MAN protocol by default, but it only works with computers that have access to Ws-Man 3.0 or later. So, earlier versions of PowerShell wouldn't be able to issue CIM cmdlets.

The cmdlet I ended up using to get total physical memory size was:

get-ciminstance -class "cim_physicalmemory" | % {$_.Capacity}
eltaco431
  • 740
  • 2
  • 10
  • 24
  • 7
    If the machine has multiple RAM banks installed, your command will return a list. The following one will show a total: `(Get-CimInstance -ClassName 'Cim_PhysicalMemory' | Measure-Object -Property Capacity -Sum).Sum` – Dark Daskin Jul 06 '16 at 10:11
  • I replaced `Get-CimInstance` with `Get-WmiObject` for good measure – Kellen Stuart Apr 20 '17 at 20:03
9

Id like to say that instead of going with the systeminfo this would help over to get the total physical memory in GB's the machine

Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | Foreach {"{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))}

you can pass this value to the variable and get the gross output for the total physical memory in the machine

   $totalmemory = Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | Foreach {"{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))}
   $totalmemory
Vigneshbabu
  • 99
  • 1
  • 2
3

For those coming here from a later day and age and one a working solution:

(Get-WmiObject -class "cim_physicalmemory" | Measure-Object -Property Capacity -Sum).Sum

this will give the total sum of bytes.

$bytes = (Get-WmiObject -class "cim_physicalmemory" | Measure-Object -Property Capacity -Sum).Sum

$kb = $bytes / 1024
$mb = $bytes / 1024 / 1024
$gb = $bytes / 1024 / 1024 / 1024

I tested this up to windows server 2008 (winver 6.0) even there this command seems to work

Joel Harkes
  • 10,975
  • 3
  • 46
  • 65
  • 1
    I prefer to use the built in size constants to convert bytes to MB, KB and GB. $kb = $bytes / 1KB $mb = $bytes / 1MB $gb = $bytes / 1GB https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-powershell-1.0/ee692684(v=technet.10) – Cody Barnes Mar 06 '19 at 21:27
3

This gives you the total amount from another WMI class:

$cs = get-wmiobject -class "Win32_ComputerSystem"
$Mem = [math]::Ceiling($cs.TotalPhysicalMemory / 1024 / 1024 / 1024)

Hope this helps.

Rishabh Agarwal
  • 1,988
  • 1
  • 16
  • 33
NVLMagic
  • 39
  • 1
0

Maybe not the best solution, but it worked for me.

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
$VBObject=[Microsoft.VisualBasic.Devices.ComputerInfo]::new()
$SystemMemory=$VBObject.TotalPhysicalMemory
0

Below gives the total physical memory.

gwmi Win32_OperatingSystem | Measure-Object -Property TotalVisibleMemorySize -Sum | % {[Math]::Round($_.sum/1024/1024)}
0

Using Get-CimInstance gives you the individual sizes of each RAM stick which you have to manually add up. Thus I prefer Get-WMIObject when possible:

(Get-WMIObject Win32_OperatingSystem).TotalVisibleMemorySize  # in KB

38326300
(Get-WMIObject Win32_OperatingSystem).TotalVisibleMemorySize / 1MB  # in GB

31.8008079528809
xjcl
  • 12,848
  • 6
  • 67
  • 89
0

This is not my creation but I found this and it displays the data beautifully in a human-readable format.

[Cmdletbinding()] 
Param( 
    [string]$Computername = "."
) 
cls 
$PysicalMemory = Get-WmiObject -class "win32_physicalmemory" -namespace "root\CIMV2" -ComputerName $Computername 
 
Write-Host "Memore Modules:" -ForegroundColor Green 
$PysicalMemory | Format-Table Tag,BankLabel,@{n="Capacity(GB)";e={$_.Capacity/1GB}},Manufacturer,PartNumber,Speed -AutoSize 
 
Write-Host "Total Memory:" -ForegroundColor Green 
Write-Host "$((($PysicalMemory).Capacity | Measure-Object -Sum).Sum/1GB)GB" 
 
$TotalSlots = ((Get-WmiObject -Class "win32_PhysicalMemoryArray" -namespace "root\CIMV2" -ComputerName $Computername).MemoryDevices | Measure-Object -Sum).Sum 
Write-Host "`nTotal Memory Slots:" -ForegroundColor Green 
Write-Host $TotalSlots 
 
$UsedSlots = (($PysicalMemory) | Measure-Object).Count  
Write-Host "`nUsed Memory Slots:" -ForegroundColor Green 
Write-Host $UsedSlots 
 
If($UsedSlots -eq $TotalSlots)
{ 
    Write-Host "All memory slots are in use. No available slots!" -ForegroundColor Yellow 
} 

Powershell ISE Screenshot

0

Tested and win32_computerSystem(cim_computerSystem) and win32_operatingSystem(cim_operatingSystem) both work when remotely querying virtual machines. The other options give fake results.

badsector
  • 21
  • 5
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 28 '22 at 22:37
0
 Get-ComputerInfo | select -Property OsTotalVisibleMemorySize
Orhan Cinar
  • 8,403
  • 2
  • 34
  • 48
0

There's lots of interesting answers here. On review I came up with:

(Get-CimInstance -ClassName "cim_physicalmemory").Capacity/1gb

Principally, it can be converted simply by selecting the required scalar value, i.e. 1kb, 1mb, 1pb or 1eb

Porky
  • 890
  • 6
  • 6