-
-
Save PSingletary/6f7042b8e0e895d64ff9364414e1df55 to your computer and use it in GitHub Desktop.
A PowerShell function to display a snapshot of process memory usage based on the workingset value. The file includes a format.ps1xml file.
This file contains hidden or 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-ProcessMemory { | |
<# | |
.SYNOPSIS | |
Get a snapshot of a process' memory usage. | |
.DESCRIPTION | |
Get a snapshot of a process' memory usage based on its workingset value. You can get the same information using Get-Process or by querying the Win32_Process WMI class with Get-CimInstance. This command uses Invoke-Command to gather the information remotely. Many of the parameters are from that cmdlet. | |
Technically you can use wildcards with process names, but because of how the function aggregates data, you might not see the results you expect. | |
.EXAMPLE | |
PS C:\> get-processmemory code,powershell,powershell_ise | |
Name Count Threads AvgMB SumMB Computername | |
---- ----- ------- ----- ----- ------------ | |
Code 7 137 121.87 853.0898 BOVINE320 | |
powershell 3 72 169.168 507.5039 BOVINE320 | |
powershell_ise 1 34 319.0078 319.0078 BOVINE320 | |
The default output displays the process name, the total process count, the total number of threads, the average workingset value per process in MB and the total workingset size of all processes also formatted in MB. | |
.EXAMPLE | |
PS C:\> get-processmemory -computername srv1,srv2,dom1 -Name lsass -cred company\artd | |
Name Count Threads AvgMB SumMB Computername | |
---- ----- ------- ----- ----- ------------ | |
lsass 1 30 59.1992 59.1992 DOM1 | |
lsass 1 7 10.6602 10.6602 SRV1 | |
lsass 1 7 9.4648 9.4648 SRV2 | |
.EXAMPLE | |
PS C:\> get-processmemory *ActiveDirectory* -Computername dom1 | select-object * | |
Name : Microsoft.ActiveDirectory.WebServices | |
Count : 1 | |
Threads : 10 | |
Average : 46940160 | |
Sum : 46940160 | |
Computername : DOM1 | |
This example uses a wildcard for the process name because the domain controller only has one related process. The output shows the raw values. | |
.EXAMPLE | |
PS C:\> Get-ProcessMemory brave,chrome,firefox | Sort-object Sum -Descending | |
Name Count Threads AvgMB SumMB Computername | |
---- ----- ------- ----- ----- ------------ | |
firefox 6 209 170.959 1025.7539 BOVINE320 | |
brave 11 192 58.1861 640.0469 BOVINE320 | |
chrome 9 153 62.3095 560.7852 BOVINE320 | |
Get browser processes and sort on the underlying SUM property in descending order. | |
.NOTES | |
Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/ | |
.LINK | |
Get-Process | |
Invoke-Command | |
.INPUTS | |
[string[]] | |
#> | |
[CmdletBinding()] | |
[OutputType("myProcessMemory")] | |
Param | |
( | |
[Parameter(Mandatory, ValueFromPipeline, Position = 0)] | |
[string[]]$Name, | |
[ValidateNotNullOrEmpty()] | |
[string[]]$Computername = $env:COMPUTERNAME, | |
[PSCredential]$Credential, | |
[switch]$UseSSL, | |
[Int32]$ThrottleLimit, | |
[ValidateSet('Default', 'Basic', 'Credssp', 'Digest', 'Kerberos', 'Negotiate', 'NegotiateWithImplicitCredential')] | |
[ValidateNotNullorEmpty()] | |
[string]$Authentication = "default" | |
) | |
Begin { | |
Write-Verbose "Starting $($MyInvocation.Mycommand)" | |
$sb = { | |
Param([string[]]$ProcessName) | |
# a process might have multiple instances so get each one by name | |
foreach ($item in $ProcessName) { | |
Get-Process -Name $item -PipelineVariable pv -OutVariable ov | | |
Measure-Object -Property WorkingSet -Sum -Average | | |
Select-Object -Property @{Name = "Name"; Expression = {$pv.name}}, | |
Count, | |
@{Name = "Threads"; Expression = {$ov.threads.count}}, | |
Average, Sum, | |
@{Name = "Computername"; Expression = {$env:computername}} | |
} | |
} #close ScriptBlock | |
#update PSBoundparamters so it can be splatted to Invoke-Command | |
$PSBoundParameters.Add("ScriptBlock", $sb) | Out-Null | |
$PSBoundParameters.add("HideComputername", $True) | Out-Null | |
} #begin | |
Process { | |
$PSBoundParameters.Remove("Name") | Out-Null | |
Write-Verbose "Querying processes $($name -join ',') on $($Computername -join ',')" | |
#need to make sure argument is treated as an array | |
$PSBoundParameters.ArgumentList = , @($Name) | |
if (-Not $PSBoundParameters.ContainsKey("Computername")) { | |
#add the default value if nothing was specified | |
$PSBoundParameters.Add("Computername", $Computername) | Out-Null | |
} | |
$PSBoundParameters | Out-String | Write-Verbose | |
Invoke-Command @PSBoundParameters | Select-Object -Property * -ExcludeProperty RunspaceID,PS* | | |
ForEach-Object { | |
#insert a custom type name for the format directive | |
$_.psobject.typenames.insert(0, "myProcessMemory") | Out-Null | |
$_ | |
} | |
} #process | |
End { | |
Write-Verbose "Ending $($MyInvocation.Mycommand)" | |
} #end | |
} #close function | |
#region formatting directives for the custom object | |
[xml]$format = @' | |
<?xml version="1.0" encoding="utf-8" ?> | |
<Configuration> | |
<ViewDefinitions> | |
<View> | |
<Name>default</Name> | |
<ViewSelectedBy> | |
<TypeName>myProcessMemory</TypeName> | |
</ViewSelectedBy> | |
<TableControl> | |
<!-- ################ TABLE DEFINITIONS ################ --> | |
<TableHeaders> | |
<TableColumnHeader> | |
<Label>Name</Label> | |
<Width>20</Width> | |
<Alignment>left</Alignment> | |
</TableColumnHeader> | |
<TableColumnHeader> | |
<Label>Count</Label> | |
<Width>7</Width> | |
<Alignment>right</Alignment> | |
</TableColumnHeader> | |
<TableColumnHeader> | |
<Label>Threads</Label> | |
<Width>7</Width> | |
<Alignment>right</Alignment> | |
</TableColumnHeader> | |
<TableColumnHeader> | |
<Label>AvgMB</Label> | |
<Width>10</Width> | |
<Alignment>right</Alignment> | |
</TableColumnHeader> | |
<TableColumnHeader> | |
<Label>SumMB</Label> | |
<Width>10</Width> | |
<Alignment>right</Alignment> | |
</TableColumnHeader> | |
<TableColumnHeader> | |
<Label>Computername</Label> | |
<Width>16</Width> | |
<Alignment>left</Alignment> | |
</TableColumnHeader> | |
</TableHeaders> | |
<TableRowEntries> | |
<TableRowEntry> | |
<TableColumnItems> | |
<TableColumnItem> | |
<PropertyName>Name</PropertyName> | |
</TableColumnItem> | |
<TableColumnItem> | |
<PropertyName>Count</PropertyName> | |
</TableColumnItem> | |
<TableColumnItem> | |
<PropertyName>Threads</PropertyName> | |
</TableColumnItem> | |
<TableColumnItem> | |
<ScriptBlock>[math]::Round($_.average/1MB,4)</ScriptBlock> | |
</TableColumnItem> | |
<TableColumnItem> | |
<ScriptBlock>[math]::Round($_.sum/1MB,4)</ScriptBlock> | |
</TableColumnItem> | |
<TableColumnItem> | |
<PropertyName>Computername</PropertyName> | |
</TableColumnItem> | |
</TableColumnItems> | |
</TableRowEntry> | |
</TableRowEntries> | |
</TableControl> | |
</View> | |
</ViewDefinitions> | |
</Configuration> | |
'@ | |
$format.Save("$env:temp\myProcessMemory.format.ps1xml") | |
Update-FormatData -AppendPath $env:temp\myProcessMemory.format.ps1xml | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment