{"id":6336,"date":"2018-12-28T12:28:17","date_gmt":"2018-12-28T17:28:17","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=6336"},"modified":"2019-01-02T09:09:02","modified_gmt":"2019-01-02T14:09:02","slug":"building-a-powershell-process-memory-tool","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/","title":{"rendered":"Building a PowerShell Process Memory Tool"},"content":{"rendered":"<p>This week I've been testing out a new browser, <a href=\"https:\/\/brave.com\" target=\"_blank\" rel=\"noopener\">Brave<\/a>, as a possible replacement for Firefox. One of the reasons I switched to Firefox from Chrome was performance and better resource utilization. Brave may now be a better choice, but that's not what this article is about. In order to assess resource utilization I turned to the <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113324\" target=\"_blank\" rel=\"noopener\">Get-Process<\/a> PowerShell cmdlet. Because I found myself needing to get some very specific results, I decided to write a PowerShell function to simplify the process. This is why <em>you<\/em> should be learning and using PowerShell, to build your own tools to solve <em>your<\/em> business needs. Here is some of the story on my development process.<\/p>\n<p><!--more--><\/p>\n<h1>Start with the Basics<\/h1>\n<p>I first started with a core PowerShell expression to display process information, using the Workingset property.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Get-Process brave | Measure-Object Workingset -sum -average | \nSelect-object Count,Sum,Average\n<\/pre>\n<p>Substitute in any process you want like chrome to see similar results. This simple expression gets all the brave processes and pipes them to <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113349\" target=\"_blank\" rel=\"noopener\">Measure-Object<\/a> which calculates the sum and average of the workingset property. It would be helpful to see the process name in the output especially because I intend to do comparisons with Firefox. If I do this:<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Get-Process brave,firefox | Measure-Object Workingset -sum -average | \nSelect-object Count,Sum,Average\n<\/pre>\n<p>I get the sum for both browsers. No. I would need to run Get-Process and Measure-Object for each process. One way would be to use <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113300\" target=\"_blank\" rel=\"noopener\">ForEach-Object<\/a>.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">\"brave\",\"firefox\" | foreach-object {\nGet-Process -name $_ -PipelineVariable pv | \nMeasure-Object Workingset -sum -average | \nSelect-object @{Name=\"Name\";Expression = {$pv.name}},\nCount,Sum,Average\n}\n<\/pre>\n<p>This is better. I'm using the common PipelineVariable parameter to retrieve the process name. Measure-Object's output doesn't include the process name from Get-Process so in order for <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113387\" target=\"_blank\" rel=\"noopener\">Select-Object<\/a> to work I need a way to access something from earlier in the pipeline. That's what PipelineVariable achieves.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image-16.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Getting process data with PowerShell\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png\" alt=\"Getting process data with PowerShell\" width=\"938\" height=\"416\" border=\"0\" \/><\/a><\/p>\n<h1>Formatting Values<\/h1>\n<p>I don't know about you but I can't readily convert all those bytes into something more meaningful. But PowerShell can.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">\"brave\",\"firefox\" | foreach-object {\nGet-Process -name $_ -PipelineVariable pv | \nMeasure-Object Workingset -sum -average | \nSelect-object @{Name=\"Name\";Expression = {$pv.name}},\nCount,\n@{Name=\"SumMB\";Expression = {[math]::round($_.Sum\/1MB,2)}},\n@{Name=\"AvgMB\";Expression = {[math]::round($_.Average\/1MB,2)}}\n}\n<\/pre>\n<p>I now have code that generates the friendly result I need.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image-17.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"PowerShell formatted results\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-17.png\" alt=\"PowerShell formatted results\" width=\"565\" height=\"198\" border=\"0\" \/><\/a><\/p>\n<p>But I need to make this flexible and re-usable. This is where functions come into play. I can quickly turn this into a function.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Function Get-MyProcess {\n[cmdletbinding()]\nParam([string[]]$Name)\n\n$Name | foreach-object {\nGet-Process -name $_ -PipelineVariable pv | \nMeasure-Object Workingset -sum -average | \nSelect-object @{Name=\"Name\";Expression = {$pv.name}},\nCount,\n@{Name=\"SumMB\";Expression = {[math]::round($_.Sum\/1MB,2)}},\n@{Name=\"AvgMB\";Expression = {[math]::round($_.Average\/1MB,2)}}\n}\n\n}\n<\/pre>\n<p>And it works.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image-18.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Results from a basic PowerShell function\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-18.png\" alt=\"Results from a basic PowerShell function\" width=\"773\" height=\"254\" border=\"0\" \/><\/a><\/p>\n<h1>Scaling Out<\/h1>\n<p>At this point I <em>could<\/em> consider this complete. However, when I write PowerShell functions, especially something is getting values or data, I typically want to be able to have it work with remote computers. My initial thought was that because Get-Process has a -Computername parameter, all I had to do was add it to my function and pass it along in the code. The potential downside to this approach is that when you connect to a remote computer in this way, you are connecting over legacy remoting connections. I'm trying to avoid using legacy connections where possible so that means I need to take advantage of PowerShell remoting.\u00a0 One solution would be to wrap my Get-Process command inside an Invoke-Command expression.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Function Get-MyProcess {\n[cmdletbinding()]\nParam([string[]]$Name,[string]$Computername = $env:computername)\n\nInvoke-Command -ScriptBlock {\n$using:Name | foreach-object {\nGet-Process -name $_ -PipelineVariable pv | \nMeasure-Object Workingset -sum -average | \nSelect-object @{Name=\"Name\";Expression = {$pv.name}},\nCount,\n@{Name=\"SumMB\";Expression = {[math]::round($_.Sum\/1MB,2)}},\n@{Name=\"AvgMB\";Expression = {[math]::round($_.Average\/1MB,2)}}\n}\n} -ComputerName $computername\n}\n<\/pre>\n<p>This is getting closer to a mature, PowerShell function.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image-19.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Getting process data via PowerShell remoting\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-19.png\" alt=\"Getting process data via PowerShell remoting\" width=\"977\" height=\"727\" border=\"0\" \/><\/a><\/p>\n<h1>Functions Don't Format<\/h1>\n<p>As you can see, this function doesn't include any error handling. And since I never need to see the RunspaceID property I would always have to wrap my function in another PowerShell expression to remove it. It would be nicer if the function wrote an object to the pipeline with just values I wanted to see. The other potential drawback is that my sum and average values are formatted in MB. I have made an assumption that limits the flexibility of this function. I was initially lazy. The better approach is to write an object to the pipeline with raw, unformatted data.<\/p>\n<p>As I revised the function, this became the core of the scriptblock:<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">foreach ($item in $ProcessName) {\n    Get-Process -Name $item -PipelineVariable pv -OutVariable ov |\n        Measure-Object -Property WorkingSet -Sum -Average |\n        Select-Object -Property @{Name = \"Name\"; Expression = {$pv.name}},\n    Count, \n    @{Name = \"Threads\"; Expression = {$ov.threads.count}},\n    Average, Sum,\n    @{Name = \"Computername\"; Expression = {$env:computername}} \n}\n<\/pre>\n<p>The output values were now back to bytes. But you know, I really would like to see them formatted as MB by default. PowerShell can do that and if fact does that all the time. When you run Get-Process the default display is formatted for you. What you see is not the raw value of the underlying process objects.\u00a0 PowerShell is using a format directive. You can too.<\/p>\n<h1>Format Data<\/h1>\n<p>First, you need to give your output object a type name. I could have built a function using a PowerShell class. But it is just as easy to insert a type name.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Invoke-Command @PSBoundParameters | Select-Object -Property * -ExcludeProperty RunspaceID,PS* |\nForEach-Object {\n    #insert a custom type name for the format directive\n    $_.psobject.typenames.insert(0, \"myProcessMemory\") | Out-Null\n    $_\n}\n<\/pre>\n<p>Now the tricky part. Format directives are special XML files saved with a .ps1xml file. One of the things I can do is define a custom heading and value.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">&lt;TableColumnItem&gt;\n    &lt;ScriptBlock&gt;[math]::Round($_.average\/1MB,4)&lt;\/ScriptBlock&gt;\n&lt;\/TableColumnItem&gt;\n<\/pre>\n<p>The default output uses the formatting directives but I can still use the underlying actual property names.<\/p>\n<p><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image-20.png\"><img loading=\"lazy\" decoding=\"async\" style=\"display: inline; background-image: none;\" title=\"Using a proper PowerShell function\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-20.png\" alt=\"Using a proper PowerShell function\" width=\"1028\" height=\"232\" border=\"0\" \/><\/a><\/p>\n<p>By the way, don't read too much into these results as Firefox has a lot of extensions and Brave has several open tabs.<\/p>\n<p>Instead of creating a separate .ps1xml file, I included the contents as a here string in my script file with my function and create a temporary file which is then imported using <a title=\"Read online help for this command\" href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=113420\" target=\"_blank\" rel=\"noopener\">Update-FormatData<\/a>. The complete file is on <a href=\"https:\/\/gist.github.com\/jdhitsolutions\/c56e470bcbca31bc09ba93e4ecdd69ed\" target=\"_blank\" rel=\"noopener\">Github<\/a>.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/jdhitsolutions\/c56e470bcbca31bc09ba93e4ecdd69ed.js\"><\/script><\/p>\n<p>Yes, this took a little bit of time to develop, but I now have a re-usable and flexible PowerShell function. and a model that I can use for future functions. I think it is helpful to see the development process as much as the final product. If you have feedback or questions, please feel free to leave a comment.\u00a0 Enjoy!<\/p>\n<h2>Update 2 January 2019<\/h2>\n<p>I've updated the code in the Github gist to better handle the use of wildcards. I also tweaked the formatting directives.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This week I&#8217;ve been testing out a new browser, Brave, as a possible replacement for Firefox. One of the reasons I switched to Firefox from Chrome was performance and better resource utilization. Brave may now be a better choice, but that&#8217;s not what this article is about. In order to assess resource utilization I turned&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"new on the blog: Building a #PowerShell Process Memory Tool","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[350,224,534,599,540],"class_list":["post-6336","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-format","tag-function","tag-powershell","tag-process","tag-scripting"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building a PowerShell Process Memory Tool &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"Follow the development process as I build a PowerShell function to get process memory utilization. You can learn as much from the process as the result.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building a PowerShell Process Memory Tool &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"Follow the development process as I build a PowerShell function to get process memory utilization. You can learn as much from the process as the result.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2018-12-28T17:28:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-01-02T14:09:02+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Building a PowerShell Process Memory Tool\",\"datePublished\":\"2018-12-28T17:28:17+00:00\",\"dateModified\":\"2019-01-02T14:09:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/\"},\"wordCount\":887,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/12\\\/image_thumb-16.png\",\"keywords\":[\"Format\",\"Function\",\"PowerShell\",\"process\",\"Scripting\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/\",\"name\":\"Building a PowerShell Process Memory Tool &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/12\\\/image_thumb-16.png\",\"datePublished\":\"2018-12-28T17:28:17+00:00\",\"dateModified\":\"2019-01-02T14:09:02+00:00\",\"description\":\"Follow the development process as I build a PowerShell function to get process memory utilization. You can learn as much from the process as the result.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/12\\\/image_thumb-16.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2018\\\/12\\\/image_thumb-16.png\",\"width\":938,\"height\":416},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/6336\\\/building-a-powershell-process-memory-tool\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Building a PowerShell Process Memory Tool\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Building a PowerShell Process Memory Tool &#8226; The Lonely Administrator","description":"Follow the development process as I build a PowerShell function to get process memory utilization. You can learn as much from the process as the result.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/","og_locale":"en_US","og_type":"article","og_title":"Building a PowerShell Process Memory Tool &#8226; The Lonely Administrator","og_description":"Follow the development process as I build a PowerShell function to get process memory utilization. You can learn as much from the process as the result.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/","og_site_name":"The Lonely Administrator","article_published_time":"2018-12-28T17:28:17+00:00","article_modified_time":"2019-01-02T14:09:02+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Building a PowerShell Process Memory Tool","datePublished":"2018-12-28T17:28:17+00:00","dateModified":"2019-01-02T14:09:02+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/"},"wordCount":887,"commentCount":3,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png","keywords":["Format","Function","PowerShell","process","Scripting"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/","name":"Building a PowerShell Process Memory Tool &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png","datePublished":"2018-12-28T17:28:17+00:00","dateModified":"2019-01-02T14:09:02+00:00","description":"Follow the development process as I build a PowerShell function to get process memory utilization. You can learn as much from the process as the result.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2018\/12\/image_thumb-16.png","width":938,"height":416},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6336\/building-a-powershell-process-memory-tool\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Building a PowerShell Process Memory Tool"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":99,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/99\/powershell-process-uptime\/","url_meta":{"origin":6336,"position":0},"title":"PowerShell Process Uptime","author":"Jeffery Hicks","date":"February 15, 2007","format":false,"excerpt":"Not too long ago, I wrote an MCPMag Tip Sheet column on using the pipeline in PowerShell. I showed how you could get the start time of a specified service: $svcname=Read-Host \"Enter a service name\" ; get-process | where {$_.id -eq (get-wmiobject win32_service | where {$_.name -eq $svcname}).ProcessID} | select\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1431,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/1431\/process-snapshot\/","url_meta":{"origin":6336,"position":1},"title":"Process Snapshot","author":"Jeffery Hicks","date":"May 11, 2011","format":false,"excerpt":"Yesterday I ended up running an impromptu browser test, comparing memory utilization. See what Twitter can do to your time!! The browsers themselves are really irrelevant. What you might find useful is the little PowerShell code I put together to periodically check and compare the browser processes. I decided to\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1441,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/1441\/get-process-detail\/","url_meta":{"origin":6336,"position":2},"title":"Get Process Detail","author":"Jeffery Hicks","date":"May 12, 2011","format":false,"excerpt":"The other day I posted a snippet of code that I as using to monitor process memory utilization for a few web browsers. I thought the information and technique were useful enough to modularize in the form of a function. Perhaps I want to check working set on a different\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":5734,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/5734\/sending-files-to-your-browser-with-powershell\/","url_meta":{"origin":6336,"position":3},"title":"Sending Files to Your Browser with PowerShell","author":"Jeffery Hicks","date":"November 6, 2017","format":false,"excerpt":"Over the course of the last year I've been using markdown files much more, especially as part of the Platyps module. Even though I have a markdown editor and I can also preview files in VS Code, sometimes I want to see the file in my browser which has a\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/11\/image_thumb.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/11\/image_thumb.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/11\/image_thumb.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/11\/image_thumb.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":6348,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6348\/building-more-powershell-functions\/","url_meta":{"origin":6336,"position":4},"title":"Building More PowerShell Functions","author":"Jeffery Hicks","date":"January 3, 2019","format":false,"excerpt":"In a recent post I discussed the the process you might go through in developing a PowerShell function. By the end, I not only had a new tool for my PowerShell toolbox, but I had a function outline that I could re-use. If you read the previous article then you\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-3.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-3.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-3.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-3.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":5602,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/5602\/whos-driving-this-shell\/","url_meta":{"origin":6336,"position":5},"title":"Who&rsquo;s Driving this Shell?","author":"Jeffery Hicks","date":"August 8, 2017","format":false,"excerpt":"Microsoft has been busy with the next iteration of PowerShell. As you should already know, this version will run cross-platform. The executable, or engine, is naturally different than what you are used to with Windows PowerShell. As I was trying out the latest PowerShell beta, I needed to identify the\u2026","rel":"","context":"In &quot;PowerCLI&quot;","block_context":{"text":"PowerCLI","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powercli\/"},"img":{"alt_text":"2017-08-08_10-29-38","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/08\/2017-08-08_10-29-38_thumb.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/08\/2017-08-08_10-29-38_thumb.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/08\/2017-08-08_10-29-38_thumb.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2017\/08\/2017-08-08_10-29-38_thumb.png?resize=700%2C400 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/6336","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=6336"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/6336\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=6336"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=6336"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=6336"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}