This is another old WMI function I have rewritten to use CIM instead. This one queries computers for memory information.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-PhysicalMemory { | |
<# | |
.SYNOPSIS | |
Get information about the physical memory installed on a computer. | |
.DESCRIPTION | |
This function uses CIM to query one or more computer for physical memory information. | |
It will first try to connect using 'WSMAN' protocol, but will fall back to using 'DCOM' if | |
this fails. | |
.EXAMPLE | |
Get-PhysicalMemory | |
Will query the local computer for physical memory information. | |
.EXAMPLE | |
Get-PhysicalMemory Server01 -Credential domain/user01 | |
Will try to query 'Server01' with the credentials of 'domain/user01'. | |
.OUTPUTS | |
PSObject | |
.NOTES | |
Author: Øyvind Kallstad | |
Date: 08.12.2014 | |
Version: 1.0 | |
#> | |
[CmdletBinding()] | |
param ( | |
# Specifies the target computer. Enter a fully qualified domain name, NetBIOS name, or an IP address. When the remote computer is in a different domain than the local computer, | |
# the fully qualified domain name is required. | |
[Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] | |
[ValidateNotNullorEmpty()] | |
[string[]] $ComputerName = $env:COMPUTERNAME, | |
# Specifies a user account that has permission to perform this action. | |
[Parameter()] | |
[System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, | |
# Use this parameter to force the creation of a new CIM session. The default behaviour is to save the session and reuse it if possible. | |
[Parameter()] | |
[switch] $ForceNewCimSession | |
) | |
process { | |
foreach ($computer in $ComputerName) { | |
try { | |
# define hashtable for Test-WSMan properties | |
$wsmanProperties = @{ | |
ComputerName = $computer | |
ErrorAction = 'SilentlyContinue' | |
} | |
if ($PSBoundParameters['Credential']){ | |
$wsmanProperties.Authentication = 'Basic' | |
$wsmanProperties.Credential = $Credential | |
} | |
# check if wsman is responding | |
$wsmanTest = Test-WSMan @wsmanProperties | |
# based on whether the result of the wsman test, we decide on the protocol to use for the cim session | |
if (-not([string]::IsNullOrEmpty($wsmanTest))) { | |
$cimSessionOption = New-CimSessionOption –Protocol Wsman | |
Write-Verbose 'Using protocol "Wsman"' | |
} | |
else { | |
$cimSessionOption = New-CimSessionOption –Protocol Dcom | |
Write-Verbose 'Using protocol "Dcom"' | |
} | |
# define hashtable for cim session properties | |
$cimSessionProperties = @{ | |
Name = $computer | |
ComputerName = $computer | |
SessionOption = $cimSessionOption | |
Verbose = $false | |
ErrorAction = 'Stop' | |
} | |
if ($PSBoundParameters['Credential']){ $cimSessionProperties.Credential = $Credential} | |
# first check to see if a cim session already exist, if so use this – if not, we create a new one | |
# if -ForceNewCimSession is used, always create a new cim session | |
if ((-not($cimSession = Get-CimSession –Name $computer –ErrorAction SilentlyContinue)) -or ($ForceNewCimSession)) { | |
Write-Verbose 'Creating new CIM session' | |
$cimSession = New-CimSession @cimSessionProperties –SkipTestConnection | |
} else { Write-Verbose 'Using existing CIM session' } | |
# run query to get data | |
$physicalMemory = Get-CimInstance –CimSession $cimSession –Query 'SELECT BankLabel,Capacity,DataWidth,Description,DeviceLocator,FormFactor,InterleaveDataDepth,InterleavePosition,Manufacturer,MemoryType,PartNumber,PositionInRow,SerialNumber,Speed,Tag,TotalWidth,TypeDetail FROM Win32_PhysicalMemory' –Verbose:$false –ErrorAction Stop | |
foreach ($memory in $physicalMemory) { | |
switch($memory.FormFactor) { | |
'0' {$memoryFF = 'Unknown'} | |
'1' {$memoryFF = 'Other'} | |
'2' {$memoryFF = 'SIP'} | |
'3' {$memoryFF = 'DIP'} | |
'4' {$memoryFF = 'ZIP'} | |
'5' {$memoryFF = 'SOJ'} | |
'6' {$memoryFF = 'Proprietary'} | |
'7' {$memoryFF = 'SIMM'} | |
'8' {$memoryFF = 'DIMM'} | |
'9' {$memoryFF = 'TSOP'} | |
'10' {$memoryFF = 'PGA'} | |
'11' {$memoryFF = 'RIMM'} | |
'12' {$memoryFF = 'SODIMM'} | |
'13' {$memoryFF = 'SRIMM'} | |
'14' {$memoryFF = 'SMD'} | |
'15' {$memoryFF = 'SSMP'} | |
'16' {$memoryFF = 'QFP'} | |
'17' {$memoryFF = 'TQFP'} | |
'18' {$memoryFF = 'SOIC'} | |
'19' {$memoryFF = 'LCC'} | |
'20' {$memoryFF = 'PLCC'} | |
'21' {$memoryFF = 'BGA'} | |
'22' {$memoryFF = 'FPBGA'} | |
'23' {$memoryFF = 'LGA'} | |
DEFAULT {$memoryFF = 'Unknown'} | |
} | |
switch ($memory.MemoryType) { | |
'0' {$memoryType = 'Unknown'} | |
'1' {$memoryType = 'Other'} | |
'2' {$memoryType = 'DRAM'} | |
'3' {$memoryType = 'Synchronous DRAM'} | |
'4' {$memoryType = 'Cache DRAM'} | |
'5' {$memoryType = 'EDO'} | |
'6' {$memoryType = 'EDRAM'} | |
'7' {$memoryType = 'VRAM'} | |
'8' {$memoryType = 'SRAM'} | |
'9' {$memoryType = 'RAM'} | |
'10' {$memoryType = 'ROM'} | |
'11' {$memoryType = 'Flash'} | |
'12' {$memoryType = 'EEPROM'} | |
'13' {$memoryType = 'FEPROM'} | |
'14' {$memoryType = 'EPROM'} | |
'15' {$memoryType = 'CDRAM'} | |
'16' {$memoryType = '3DRAM'} | |
'17' {$memoryType = 'SDRAM'} | |
'18' {$memoryType = 'SGRAM'} | |
'19' {$memoryType = 'RDRAM'} | |
'20' {$memoryType = 'DDR'} | |
'21' {$memoryType = 'DDR-2'} | |
DEFAULT {$memoryType = 'Unknown'} | |
} | |
switch ($memory.InterleavePosition) { | |
'0' {$interleavePosition = 'NonInterleaved'} | |
'1' {$interleavePosition = 'First position' } | |
'2' {$interleavePosition = 'Second position'} | |
DEFAULT {$interleavePosition = 'unknown'} | |
} | |
$typeDetails = @() | |
if($memory.TypeDetail -band 1) {$typeDetails += 'Reserved'} | |
if($memory.TypeDetail -band 2) {$typeDetails += 'Other'} | |
if($memory.TypeDetail -band 4) {$typeDetails += 'Unknown'} | |
if($memory.TypeDetail -band 8) {$typeDetails += 'Fast-paged'} | |
if($memory.TypeDetail -band 16) {$typeDetails += 'Static column'} | |
if($memory.TypeDetail -band 32) {$typeDetails += 'Pseudo-static'} | |
if($memory.TypeDetail -band 64) {$typeDetails += 'RAMBUS'} | |
if($memory.TypeDetail -band 128) {$typeDetails += 'Synchronous'} | |
if($memory.TypeDetail -band 256) {$typeDetails += 'CMOS'} | |
if($memory.TypeDetail -band 512) {$typeDetails += 'EDO'} | |
if($memory.TypeDetail -band 1024){$typeDetails += 'Window DRAM'} | |
if($memory.TypeDetail -band 2048){$typeDetails += 'Cache DRAM'} | |
if($memory.TypeDetail -band 4096){$typeDetails += 'Nonvolatile'} | |
$output = [PSCustomObject] [Ordered] @{ | |
ComputerName = $computer | |
BankLabel = $memory.BankLabel | |
Capacity = $memory.Capacity | |
CapacityMB = ($memory.Capacity/1mb) | |
DataWidth = $memory.DataWidth | |
Description = $memory.Description | |
DeviceLocator = $memory.DeviceLocator | |
FormFactor = $memoryFF | |
InterleaveDataDepth = $memory.InterleaveDataDepth | |
InterleavePosition = $interleavePosition | |
Manufacturer = $memory.Manufacturer | |
MemoryType = $memoryType | |
PartNumber = $memory.PartNumber | |
PositionInRow = $memory.PositionInRow | |
SerialNumber = $memory.SerialNumber | |
Speed = $memory.Speed | |
Tag = $memory.Tag | |
TotalWidth = $memory.TotalWidth | |
TypeDetails = $typeDetails -join ', ' | |
} | |
$defaultProperties = @('ComputerName','BankLabel','DeviceLocator','CapacityMB','Speed','FormFactor','Manufacturer') | |
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultProperties) | |
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) | |
$output | Add-Member –MemberType MemberSet –Name PSStandardMembers –Value $PSStandardMembers –Force | |
Write-Output $output | |
Remove-Variable –Name memoryFF,interleavePosition,typeDetails,memoryType –ErrorAction SilentlyContinue | |
} | |
} | |
catch { | |
# if the connection fail we don't want to keep the session | |
Remove-CimSession –Name $computer –ErrorAction SilentlyContinue | |
Write-Warning "At line:$($_.InvocationInfo.ScriptLineNumber) char:$($_.InvocationInfo.OffsetInLine) Command:$($_.InvocationInfo.InvocationName), Exception: '$($_.Exception.Message.Trim())'" | |
} | |
} | |
} | |
} |
Nice! Really fast on my laptop! I like how it catches the errors gracefully. A bit against the best practices that huge “try{}catch{}” block, but why follow these guidlines if it is only to be a *$¨!# in the but!? (I actually know the answer: It is to have a more precise error handeling, and specifically, to be able to use the finally{} scriptblock).
I personally like to add a “Get-Credential” right after my credential variable when I use it. (But it will make it mandatory).
[System.Management.Automation.Credential()] $Credential = (Get-credential)
Great work!
LikeLike
Thanks. Yeah, I tend to use large try-catch blocks. For me it’s enough that I catch any exceptions. If I’m working on a really complicated script, I’ll do it differently of course, but these functions are really just meant to do small things, so it works well I think.
LikeLike