{"id":8321,"date":"2021-04-15T15:25:34","date_gmt":"2021-04-15T19:25:34","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=8321"},"modified":"2021-04-15T15:25:38","modified_gmt":"2021-04-15T19:25:38","slug":"building-a-powershell-process-detection-tool","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/","title":{"rendered":"Building a PowerShell Process Detection Tool"},"content":{"rendered":"\n<div class=\"wp-block-image is-style-default\"><figure class=\"alignleft size-large\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"160\" height=\"106\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg\" alt=\"\" class=\"wp-image-8322\"\/><\/a><\/figure><\/div>\n\n\n\n<p>I spend my entire working day in a PowerShell prompt. It is often a combination of Windows PowerShell and PowerShell 7. Sometimes I'm in a session with a loaded profile, sometimes not. Sometimes I have a PowerShell 7 Preview session running. And then there are the scheduled jobs which also run PowerShell. Over the years, I've written a number of variations of a PowerShell script or function to discover all of the running PowerShell sessions on my computer. But I think I have finally written the final version of a PowerShell process detection tool.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Find Processes<\/h2>\n\n\n\n<p>I wanted a tool that would run in both Windows PowerShell and PowerShell 7 on a Windows platform. I also wanted to be able to discover information such as the process owner, the command used to start the process, and the parent process. Querying the Win32_Process class with Get-CimInstance was the best choice. Although, as you'll see I also still need Get-Process.<\/p>\n\n\n\n<p>Because we always want to filter early, I'll use the -Filter parameter to get only the pwsh.exe processes.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Get-CimInstance&nbsp;-ClassName&nbsp;win32_process&nbsp;-filter&nbsp;\"name&nbsp;=&nbsp;'pwsh.exe'\"&nbsp;|\nSelect-Object&nbsp;-property&nbsp;\"ProcessID\",&nbsp;\"HandleCount\",&nbsp;\"CommandLine\",&nbsp;\"ParentProcessID\",&nbsp;\"CreationDate\",\"WorkingSetSize\",\"Name\"<\/code><\/pre>\n\n\n\n<p>Remember WMI\/CIM filters use the legacy operators. This gives me a number of processes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"243\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process-1024x243.png\" alt=\"\" class=\"wp-image-8323\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process-1024x243.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process-300x71.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process-768x182.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process-1536x364.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process-850x202.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/gcim-process.png 1614w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The CommandLine property looks very useful. I also have the parent process ID. I can use Get-Process to grab that process. Even though I'm the only user on my desktop, I can also get the process owner by invoking the GetOwner() method with Invoke-CimMethod. In other words, I have the foundation of what kind of result I want. The Get-CimInstance command is the core of my eventual tool. <strong>I think it is important when building PowerShell tools that you have a working expression that you can run at a PowerShell prompt<\/strong>. Now I can dress it up.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Objects are Fundamental<\/h2>\n\n\n\n<p>The goal of most PowerShell commands is to write or work with objects. Certainly a \"get\" command, which is what I'm building, should write an object to the pipeline. My initial expression with Select-Object achieves that result. But for a script, that kind of code can get cumbersome. Especially as I start adding custom properties. Instead, I like to use code like this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$items&nbsp;=&nbsp;Get-CimInstance&nbsp;-ClassName&nbsp;win32_process&nbsp;-filter&nbsp;\"name&nbsp;=&nbsp;'pwsh.exe'\"&nbsp;\nforeach&nbsp;($item&nbsp;in&nbsp;$items)&nbsp;{\n&nbsp;&nbsp;&nbsp;&nbsp;#get&nbsp;owner\n&nbsp;&nbsp;&nbsp;&nbsp;$owner&nbsp;=&nbsp;Invoke-CimMethod&nbsp;-InputObject&nbsp;$item&nbsp;-MethodName&nbsp;GetOwner\n&nbsp;&nbsp;&nbsp;&nbsp;$parent&nbsp;=&nbsp;Get-Process&nbsp;-Id&nbsp;$item.ParentprocessID\n&nbsp;&nbsp;&nbsp;&nbsp;[PSCustomObject]@{\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PSTypename&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;\"PowerShellProcess\"\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$item.ProcessID\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$item.Name\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Handles&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$item.HandleCount\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WorkingSet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$item.WorkingSetSize\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParentProcessID&nbsp;=&nbsp;$item.ParentProcessID\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParentProcess&nbsp;&nbsp;&nbsp;=&nbsp;$parent.Name\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParentPath&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$parent.Path\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Started&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$item.CreationDate\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Owner&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;\"$($owner.Domain)\\$($owner.user)\"\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CommandLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;$item.Commandline\n&nbsp;&nbsp;&nbsp;&nbsp;}\n}<\/code><\/pre>\n\n\n\n<p>I could have piped Get-CimInstance to Select-Object and used custom properties defined with hashtables, but I find the approach above easier to write, read, and debug. Each process object serves as the basis for a new custom object. I'm adding additional information The PSTypeName key defines the object type. Without it, I would have a generic PSCustomobject which isn't necessarily a bad thing. But I have plans which I'll get to momentarily. This code gives me an object result like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">ProcessID       : 11828\nName            : pwsh.exe\nHandles         : 1410\nWorkingSet      : 197029888\nParentProcessID : 25596\nParentProcess   : WindowsTerminal\nParentPath      : C:\\Program Files\\WindowsAppsMicrosoft.WindowsTerminal_1.6.10571.0_x64__8wekyb3d8bbwe\\WindowsTerminal.exe\nStarted         : 4\/15\/2021 10:28:24 AM\nOwner           : PROSPERO\\Jeff\nCommandLine     : \"C:\\Program Files\\PowerShell\\7\\pwsh.exe\" -nologo<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Extending the Object<\/h2>\n\n\n\n<p>I like creating commands that give me a rich result. I can't always foresee how I might use a result. I prefer not to have to go back and re-write a function. I'd have rather have too much detail than not enough. In this situation, I'm also thinking about how I might use the results and what would make it even easier. In looking at the output, I can think of a few things.<\/p>\n\n\n\n<p>First, since I know when the process started, it is very easy to calculate a run time. But I want this to be dynamic and not statically assigned in the ForEach loop. I need a ScriptProperty. PowerShell objects can have properties whose values are calculated by a scriptblock everytime you access the property. I want that. One of the reasons I defined a type name is so that I can use Update-TypeData and define an additional property.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Update-TypeData&nbsp;-TypeName&nbsp;PowerShellProcess&nbsp;-MemberType&nbsp;ScriptProperty&nbsp;-MemberName&nbsp;Runtime&nbsp;-Value&nbsp;{&nbsp;(Get-Date)&nbsp;-&nbsp;$this.Started&nbsp;}&nbsp;-Force<\/code><\/pre>\n\n\n\n<p>I also would like to save some typing when accessing a few properties I know I will access often. For example, instead of having to type WorkingSet, how about an alias of WS. You see this often in PowerShell. Yes, I could have used WS in my object definition, but I prefer to use meaningful property names. If I want a shortcut, I can define an alias property.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Update-TypeData&nbsp;-TypeName&nbsp;PowerShellProcess&nbsp;-MemberType&nbsp;AliasProperty&nbsp;-MemberName&nbsp;ID&nbsp;-Value&nbsp;ProcessID&nbsp;-Force\nUpdate-TypeData&nbsp;-TypeName&nbsp;PowerShellProcess&nbsp;-MemberType&nbsp;AliasProperty&nbsp;-MemberName&nbsp;WS&nbsp;-Value&nbsp;WorkingSet&nbsp;-Force\nUpdate-TypeData&nbsp;-TypeName&nbsp;PowerShellProcess&nbsp;-MemberType&nbsp;AliasProperty&nbsp;-MemberName&nbsp;cli&nbsp;-Value&nbsp;Commandline&nbsp;-Force<\/code><\/pre>\n\n\n\n<p>Now I can run a command like this (where $p is the collection of PowerShellProcess objects.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$p | sort ParentProcess | format-table -GroupBy ParentProcess -Property ID,Name,WS,Owner,Runtime  <\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/powershellprocess-format.png\"><img loading=\"lazy\" decoding=\"async\" width=\"905\" height=\"407\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/powershellprocess-format.png\" alt=\"\" class=\"wp-image-8327\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/powershellprocess-format.png 905w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/powershellprocess-format-300x135.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/powershellprocess-format-768x345.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/powershellprocess-format-850x382.png 850w\" sizes=\"auto, (max-width: 905px) 100vw, 905px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Formatting the Results<\/h2>\n\n\n\n<p>A moment ago I mentioned I like rich objects. It is easier to not show something by default than have to rewrite code to get more information. I'm mostly happy with the raw object I'm getting now. I have a few other things that might be nice to have, but I think the code to get them is going to be a bit more complicated so I'll hold off for now. Instead, I need to focus on what I want the default output to be. I don't have to see all properties. It would be nice to see them in a more structured manner. For that I will need a custom format .ps1xml file.<\/p>\n\n\n\n<p>I've written about this before, but using New-PSFormatXML from the PSScriptTools module makes this very easy. All I need is a sample object with all properties defined.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">(Get-PSPowerShell)[0]&nbsp;|&nbsp;New-PSFormatXML&nbsp;-Path&nbsp;c:\\scripts\\powershellprocess.format.ps1xml&nbsp;-FormatType&nbsp;List&nbsp;-ViewName&nbsp;default\n(Get-PSPowerShell)[0]&nbsp;|&nbsp;New-PSFormatXML&nbsp;-Path&nbsp;c:\\scripts\\powershellprocess.format.ps1xml&nbsp;-append&nbsp;-FormatType&nbsp;table&nbsp;-ViewName&nbsp;cmd&nbsp;-GroupBy&nbsp;Commandline&nbsp;-Properties&nbsp;ProcessID,ParentProcessID,Owner,Started,Runtime\n(Get-PSPowerShell)[0]&nbsp;|&nbsp;New-PSFormatXML&nbsp;-Path&nbsp;c:\\scripts\\powershellprocess.format.ps1xml&nbsp;-append&nbsp;-FormatType&nbsp;table&nbsp;-ViewName&nbsp;parent&nbsp;-GroupBy&nbsp;ParentProcess&nbsp;-Properties&nbsp;ID,Owner,Started,Runtime&nbsp;-Wrap<\/code><\/pre>\n\n\n\n<p>I then edited the ps1xml file to adjust the formatting and add some customizations. For example, in the default display I thought it would be nice to highlight the current process. The function I ended up with also includes a parameter to exclude the current process. But if I do include it, I want to show it in green.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"xml\" class=\"language-xml\">&lt;Label&gt;ProcessID&lt;\/Label&gt;\n&lt;ScriptBlock&gt;\n&nbsp;&nbsp;&lt;!--&nbsp;highlight&nbsp;the&nbsp;current&nbsp;process&nbsp;ID&nbsp;using&nbsp;ANSI--&gt;\nif&nbsp;($host.name&nbsp;-match&nbsp;\"console|code\"&nbsp;-AND&nbsp;$_.processID&nbsp;-eq&nbsp;$pid)&nbsp;{\n&nbsp;&nbsp;\"$([char]27)[92m$($_.ProcessID)$([char]27)[0m\"\n}\nelse&nbsp;{\n&nbsp;&nbsp;$_.ProcessID\n}\n&lt;\/ScriptBlock&gt;<\/code><\/pre>\n\n\n\n<p>I added similar code for the process owner. If the owner is someone other than me (or the person running the command, I want to show that in red.<\/p>\n\n\n\n<p>Once the format file is complete, I can load it into my session.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">Update-FormatData&nbsp;$PSScriptRoot\\powershellprocess.format.ps1xml<\/code><\/pre>\n\n\n\n<p>The first view in the file, will be the default. This is a screen shot from a few days ago.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-default.png\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"514\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-default.png\" alt=\"\" class=\"wp-image-8328\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-default.png 900w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-default-300x171.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-default-768x439.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-default-850x485.png 850w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><\/figure>\n\n\n\n<p>But I also knew I would want to view the results in a few ways. That's why I created additional views. The additional views in the format file are tables. The first view is the default when piping to Format-Table.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-table.png\"><img loading=\"lazy\" decoding=\"async\" width=\"872\" height=\"416\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-table.png\" alt=\"\" class=\"wp-image-8329\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-table.png 872w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-table-300x143.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-table-768x366.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-table-850x406.png 850w\" sizes=\"auto, (max-width: 872px) 100vw, 872px\" \/><\/a><\/figure>\n\n\n\n<p>You can see the \"other\" process owner highlighted in red. I also added second table view named \"cmd\".<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-cmd.png\"><img loading=\"lazy\" decoding=\"async\" width=\"931\" height=\"328\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-cmd.png\" alt=\"\" class=\"wp-image-8330\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-cmd.png 931w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-cmd-300x106.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-cmd-768x271.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/get-pspowershell-cmd-850x299.png 850w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Want to Try?<\/h2>\n\n\n\n<p>The end result is that I know have a command which provides rich detail. Yet, I can manage what I see and how I see it with custom type and format extensions. It isn't difficult to add these extensions and they add tremendous value to your work. Think of them as \"force multipliers\".<\/p>\n\n\n\n<p>I've posted the function and format ps1xml as a <a href=\"https:\/\/gist.github.com\/jdhitsolutions\/9439c6b49d9019b950156b45fe8a4d0b\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub gist<\/a>. Save both files to the same directory. The ps1 file will load the format file so make sure you keep the file names or edit accordingly. Dot source the .ps1 file and then you are ready to go running Get-PSPowerShell or its alias <em>gpsp<\/em>. The command has comment-based help with examples. I've added comments throughout the script file to explain what I am doing and why.<\/p>\n\n\n\n<p>Even if you don't have a need for this function, I hope you'll pay attention to the PowerShell scripting patterns and techniques. If you are going to take the time to create a PowerShell tool, you might as well make it the best it can be.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I spend my entire working day in a PowerShell prompt. It is often a combination of Windows PowerShell and PowerShell 7. Sometimes I&#8217;m in a session with a loaded profile, sometimes not. Sometimes I have a PowerShell 7 Preview session running. And then there are the scheduled jobs which also run PowerShell. Over the years,&#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 Detection 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":[388,534,599,540],"class_list":["post-8321","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-get-ciminstance","tag-powershell","tag-process","tag-scripting"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Building a PowerShell Process Detection Tool &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"I built a PowerShell tool to find PowerShell and pwsh processes. Complete with type and format extensions. Use as a model for your own work.\" \/>\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\/8321\/building-a-powershell-process-detection-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 Detection Tool &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"I built a PowerShell tool to find PowerShell and pwsh processes. Complete with type and format extensions. Use as a model for your own work.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-15T19:25:34+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-04-15T19:25:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg\" \/>\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=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Building a PowerShell Process Detection Tool\",\"datePublished\":\"2021-04-15T19:25:34+00:00\",\"dateModified\":\"2021-04-15T19:25:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/\"},\"wordCount\":1206,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-andrea-piacquadio-3769697.jpg\",\"keywords\":[\"Get-CIMInstance\",\"PowerShell\",\"process\",\"Scripting\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/\",\"name\":\"Building a PowerShell Process Detection Tool &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-andrea-piacquadio-3769697.jpg\",\"datePublished\":\"2021-04-15T19:25:34+00:00\",\"dateModified\":\"2021-04-15T19:25:38+00:00\",\"description\":\"I built a PowerShell tool to find PowerShell and pwsh processes. Complete with type and format extensions. Use as a model for your own work.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-tool\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-andrea-piacquadio-3769697.jpg\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/pexels-andrea-piacquadio-3769697.jpg\",\"width\":160,\"height\":106},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8321\\\/building-a-powershell-process-detection-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 Detection 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 Detection Tool &#8226; The Lonely Administrator","description":"I built a PowerShell tool to find PowerShell and pwsh processes. Complete with type and format extensions. Use as a model for your own work.","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\/8321\/building-a-powershell-process-detection-tool\/","og_locale":"en_US","og_type":"article","og_title":"Building a PowerShell Process Detection Tool &#8226; The Lonely Administrator","og_description":"I built a PowerShell tool to find PowerShell and pwsh processes. Complete with type and format extensions. Use as a model for your own work.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/","og_site_name":"The Lonely Administrator","article_published_time":"2021-04-15T19:25:34+00:00","article_modified_time":"2021-04-15T19:25:38+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg","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":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Building a PowerShell Process Detection Tool","datePublished":"2021-04-15T19:25:34+00:00","dateModified":"2021-04-15T19:25:38+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/"},"wordCount":1206,"commentCount":0,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg","keywords":["Get-CIMInstance","PowerShell","process","Scripting"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/","name":"Building a PowerShell Process Detection Tool &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg","datePublished":"2021-04-15T19:25:34+00:00","dateModified":"2021-04-15T19:25:38+00:00","description":"I built a PowerShell tool to find PowerShell and pwsh processes. Complete with type and format extensions. Use as a model for your own work.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-tool\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/04\/pexels-andrea-piacquadio-3769697.jpg","width":160,"height":106},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8321\/building-a-powershell-process-detection-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 Detection 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":7468,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7468\/powershell-7-scripting-with-the-powershell-ise\/","url_meta":{"origin":8321,"position":0},"title":"PowerShell 7 Scripting with the PowerShell ISE","author":"Jeffery Hicks","date":"May 11, 2020","format":false,"excerpt":"By now, everyone should have gotten the memo that with the move to PowerShell 7, the PowerShell ISE should be considered deprecated. When it comes to PowerShell script and module development for PowerShell 7, the recommended tool is Visual Studio Code. It is free and offers so much more than\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\/2020\/05\/ise-ps7.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":912,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/912\/powershell-is-not-ominipotent\/","url_meta":{"origin":8321,"position":1},"title":"PowerShell Is Not Omnipotent","author":"Jeffery Hicks","date":"September 7, 2010","format":false,"excerpt":"Last week I was working on a problem in a PowerShell forum. The admin was having problems getting Add-Computer to work. After a bit of \"try this\/try that\" something became clear, and it's something that is easy to overlook. Especially when we get lulled into thinking PowerShell is omnipotent. Now,\u2026","rel":"","context":"In &quot;Best Practices&quot;","block_context":{"text":"Best Practices","link":"https:\/\/jdhitsolutions.com\/blog\/category\/best-practices\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1171,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/1171\/powershell-deep-dive-formatting-and-extensions\/","url_meta":{"origin":8321,"position":2},"title":"PowerShell Deep Dive Formatting and Extensions","author":"Jeffery Hicks","date":"February 25, 2011","format":false,"excerpt":"I just found out I will be presenting at the PowerShell Deep Dive April 18-19 that is part of TEC 2011. This promises to be THE PowerShell event everyone has been waiting for. I'll be presenting on format and type extensions. Mastering Format and Type Extensions Windows PowerShell is designed\u2026","rel":"","context":"In &quot;Conferences&quot;","block_context":{"text":"Conferences","link":"https:\/\/jdhitsolutions.com\/blog\/category\/conferences\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":346,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/346\/powershell-exit-stage-left\/","url_meta":{"origin":8321,"position":3},"title":"Powershell: Exit Stage Left","author":"Jeffery Hicks","date":"September 1, 2009","format":false,"excerpt":"While reviewing and revising the manuscript for Windows PowerShell v2.0: TFM 3rd ed. I had the opportunity to revisit our chapter on working with events in PowerShell. An event in Windows is when something happens like a mouse-click, a process being created or window resized. In PowerShell you can easily\u2026","rel":"","context":"In &quot;CommandLine&quot;","block_context":{"text":"CommandLine","link":"https:\/\/jdhitsolutions.com\/blog\/category\/commandline\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2823,"url":"https:\/\/jdhitsolutions.com\/blog\/training\/2823\/powershell-in-the-big-o\/","url_meta":{"origin":8321,"position":4},"title":"PowerShell in the Big O","author":"Jeffery Hicks","date":"February 27, 2013","format":false,"excerpt":"I am speaking at SQL Saturday #197 in Omaha, NE on Saturday, April 6th. But even better, I will be doing a full day pre-conference session on Friday. The title of my session is Prof. PowerShell: or How I Learned to Stop Worrying and Love PowerShell. For those of you\u2026","rel":"","context":"In &quot;Conferences&quot;","block_context":{"text":"Conferences","link":"https:\/\/jdhitsolutions.com\/blog\/category\/conferences\/"},"img":{"alt_text":"omaha","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/02\/omaha-150x150.jpg?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":6428,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell-core\/6428\/a-powershell-core-out-gridview-solution\/","url_meta":{"origin":8321,"position":5},"title":"A PowerShell Core Out-Gridview Solution","author":"Jeffery Hicks","date":"January 15, 2019","format":false,"excerpt":"As many of you know, this year I've made the jump to PowerShell Core as my \"daily driver\". A major driving factor was to discover the limitations. There are certainly plenty of advantages as we move to a cross-platform world. But the PowerShell Core is based .NET Core which does\u2026","rel":"","context":"In &quot;PowerShell Core&quot;","block_context":{"text":"PowerShell Core","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-core\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-16.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-16.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-16.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/01\/image_thumb-16.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8321","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=8321"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8321\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=8321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=8321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=8321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}