{"id":8766,"date":"2022-01-06T09:47:17","date_gmt":"2022-01-06T14:47:17","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=8766"},"modified":"2022-01-06T09:53:09","modified_gmt":"2022-01-06T14:53:09","slug":"discovering-pester-tags-revisited","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/","title":{"rendered":"Discovering Pester Tags Revisited"},"content":{"rendered":"\n<p>Yesterday I shared some <a href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8759\/discovering-pester-tags-with-the-powershell-ast\/\" target=\"_blank\" rel=\"noreferrer noopener\">PowerShell code I wrote to discover tags in a Pester test<\/a>. It works nicely and I have no reason to complain. But as usual, there is never simply one way to do something in PowerShell. I got a suggestion from <a href=\"https:\/\/twitter.com\/FrodeFlaten\" target=\"_blank\" rel=\"noreferrer noopener\">@FrodeFlaten<\/a> on Twitter on an approach using the new configuration object in Pester 5.2. I'll readily admit that I am still getting up to speed on the latest version of Pester. That's one of my goals for this year, so this was a great chance to learn something new.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">PesterConfiguration<\/h2>\n\n\n\n<p>In previous versions of Pester, you could control Invoke-Pester through a set of parameters. Now we can use a configuration object that contains all the test settings. You can create a default object with New-PesterConfiguration.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png\"><img loading=\"lazy\" decoding=\"async\" width=\"615\" height=\"262\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png\" alt=\"pester configuration object\" class=\"wp-image-8767\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png 615w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-300x128.png 300w\" sizes=\"auto, (max-width: 615px) 100vw, 615px\" \/><\/a><\/figure>\n\n\n\n<p>The suggestion was to configure Pester to skip running all tests and pass the test object to the pipeline. The configuration object has a set of nested properties. Here's Run.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"245\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run-1024x245.png\" alt=\"pester configuration run\" class=\"wp-image-8768\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run-1024x245.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run-300x72.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run-768x184.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run-850x203.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration-run.png 1309w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>I can now modify the configuration object.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$config.Run.SkipRun = $true\n$config.run.path = 'C:\\scripts\\PSFunctionTools\\tests\\psfunctiontools.tests.ps1'\n$config.run.PassThru = $True\n$config.Output.Verbosity = \"none\"<\/code><\/pre>\n\n\n\n<p>The properties should be self-explanatory. Since I'm not really running the test, I don't need to see any test results. I'll run Invoke-Pester using the configuration object.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$r = Invoke-Pester -Configuration $config -WarningAction SilentlyContinue<\/code><\/pre>\n\n\n\n<p>I'm using the warning action to suppress any deprecation messages. Not really necessary, but it makes for a cleaner experience.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Pester Test Object<\/h2>\n\n\n\n<p>Because I used a Passthru configuration, I get a result like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pestertestobject.png\"><img loading=\"lazy\" decoding=\"async\" width=\"988\" height=\"665\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pestertestobject.png\" alt=\"pester test object\" class=\"wp-image-8769\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pestertestobject.png 988w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pestertestobject-300x202.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pestertestobject-768x517.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pestertestobject-850x572.png 850w\" sizes=\"auto, (max-width: 988px) 100vw, 988px\" \/><\/a><\/figure>\n\n\n\n<p>I can get tags from all individual tests easily enough.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\"> $($r.tests.tag).Where({$_}).foreach({$_.toLower()}) | Select-Object -unique<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/test-tags.png\"><img loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"164\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/test-tags.png\" alt=\"pester test tags\" class=\"wp-image-8770\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/test-tags.png 738w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/test-tags-300x67.png 300w\" sizes=\"auto, (max-width: 738px) 100vw, 738px\" \/><\/a><\/figure>\n\n\n\n<p>I'm doing some filtering and processing to get a unique list of tags.<\/p>\n\n\n\n<p>But containers like Describe and Context can also have tags.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pester-containers.png\"><img loading=\"lazy\" decoding=\"async\" width=\"532\" height=\"425\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pester-containers.png\" alt=\"\" class=\"wp-image-8771\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pester-containers.png 532w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pester-containers-300x240.png 300w\" sizes=\"auto, (max-width: 532px) 100vw, 532px\" \/><\/a><\/figure>\n\n\n\n<p>What you see are all Describe blocks and their tags. But that first Describe block has a nested Context blog which also has a tag. I need to recurse through containers to identify their tags.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">function _recurseBlock {\n    Param([object]$block)\n    $block.tag\n    if ($block.blocks) {\n        foreach ($item in $block.blocks) {\n            _recurseBlock $item\n        }\n    }\n}\n\nforeach ($block in $r.containers.blocks) {\n    _recurseBlock $block\n}<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/container-tags.png\"><img loading=\"lazy\" decoding=\"async\" width=\"418\" height=\"422\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/container-tags.png\" alt=\"pester container tags\" class=\"wp-image-8772\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/container-tags.png 418w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/container-tags-297x300.png 297w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/container-tags-150x150.png 150w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/container-tags-300x303.png 300w\" sizes=\"auto, (max-width: 418px) 100vw, 418px\" \/><\/a><\/figure>\n\n\n\n<p>The nested Contex block has a tag of \"structure\". Of course, I can process this list to get unique items. Combine these results with the test tags and I should have everything I need.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Revised PowerShell Function<\/h2>\n\n\n\n<p>With all of this in mind, I wrote a revised version of my function.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">#requires -version 7.1\n#requires -module @{ModuleName = 'Pester';ModuleVersion='5.2'}\n\nFunction Get-PesterTag {\n    #thanks to https:\/\/twitter.com\/FrodeFlaten for the suggestion\n    [cmdletbinding()]\n    [OutputType(\"pesterTag\")]\n    Param(\n        [Parameter(\n            Position = 0,\n            Mandatory,\n            HelpMessage = \"Specify a Pester test file\",\n            ValueFromPipeline\n        )]\n        [ValidateScript({\n                #validate file exits\n                if (Test-Path $_) {\n                    #now test for extension\n                    if ($_ -match \"\\.ps1$\") {\n                        $True\n                    }\n                    else {\n                        Throw \"The filename must end in '.ps1'.\"\n                    }\n                }\n                else {\n                    Throw \"Cannot find file $_.\"\n                }\n            })]\n        [string]$Path\n    )\n\n    Begin {\n        Write-Verbose \"[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)\"\n        $config = New-PesterConfiguration\n        $config.Run.SkipRun = $true\n        $config.run.PassThru = $True\n        $config.Output.Verbosity = \"none\"\n\n        #a private helper function to recurse through Describe and Context test blocks\n        function _recurseBlock {\n            Param([object]$block)\n            $block.tag\n            if ($block.blocks) {\n                foreach ($item in $block.blocks) {\n                    _recurseBlock $item\n                }\n            }\n        }\n        #Initiate a list to hold tags\n        $list = [system.collections.generic.list[string]]::new()\n\n    } #begin\n\n    Process {\n        $Path = Convert-Path $path\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Getting tags from $Path\"\n        $config.run.path = $path\n        Write-Verbose \"[$((Get-Date).TimeofDay) PROCESS] Invoking Pester\"\n        $r = Invoke-Pester -Configuration $config -WarningAction SilentlyContinue\n\n        #get Test tags and add unique items to the list\n        $($r.tests.tag).Where({ $_ }).foreach({\n                $t = $_.toLower();\n                if (-Not ($list.Contains($t))) {\n                    $list.add($t)\n                } })\n\n        #get block tags\n        foreach ($block in $r.containers.blocks) {\n            _recurseBlock $block | ForEach-Object {\n                $t = $_.toLower()\n                #add item to the list if not already there\n                if (-Not ($list.Contains($t))) {\n                    $list.add($t)\n                }\n            } #foreach tag\n        } #foreach block\n\n        if ($list.count -gt 0) {\n            [pscustomobject]@{\n                PSTypename = \"pesterTag\"\n                Path       = $Path\n                Tags       = $List | Sort-Object\n            }\n        }\n        else {\n            Write-Warning \"No tags found in $Path\"\n        }\n    } #process\n\n    End {\n        Write-Verbose \"[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)\"\n    } #end\n\n} #close Get-PesterTag\n<\/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\/2022\/01\/get-pestertags-revised.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"362\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-pestertags-revised-1024x362.png\" alt=\"\" class=\"wp-image-8773\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-pestertags-revised-1024x362.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-pestertags-revised-300x106.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-pestertags-revised-768x272.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-pestertags-revised-850x301.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-pestertags-revised.png 1111w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>The function still writes an object to the pipeline but it uses a different approach to get the same results. However, there are tradeoffs. <\/p>\n\n\n\n<p>My first function using regular expressions runs very fast. It processed this test file in 0.54ms. This version using the Pester configuration object takes 0.9ms. Frankly, I'm not going to quibble over this minute difference. In fact, this new version is going to be more accurate as it is processing the actual test file. My version using the PowerShell AST might not differentiate between live code and something that might have been commented out (I'd have to test that to be sure) so I'll most likely stick with this new version.<\/p>\n\n\n\n<p>In fact, now that I know more about the Pester configuration object a number of ideas are sparking. I'm confident I'll be back.<\/p>\n\n\n\n<p>Oh, before I forget. This new function only works in PowerShell 7. At least as written. I think Microsoft made some changes under the hood on how it unrolls collections of objects which is how I can easily get the tag property. If you are stuck with Windows PowerShell, you would need to use the AST version. Or feel free to modify this code to work in Windows PowerShell. A big goal for me this year is to leave Windows PowerShell behind. I'd rather spend my time learning new things instead of struggling with backward compatibility. I hope you can move forward with me.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yesterday I shared some PowerShell code I wrote to discover tags in a Pester test. It works nicely and I have no reason to complain. But as usual, there is never simply one way to do something in PowerShell. I got a suggestion from @FrodeFlaten on Twitter on an approach using the new configuration object&#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: Revisiting #Pester tag discovery with #PowerShell","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,610],"tags":[224,520,534],"class_list":["post-8766","post","type-post","status-publish","format-standard","hentry","category-powershell","category-powershell-7","tag-function","tag-pester","tag-powershell"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Discovering Pester Tags Revisited &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"I revisit my task of getting Pester test tags using the Pester configuration object. I have a new PowerShell 7 function that gets the job done.\" \/>\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\/8766\/discovering-pester-tags-revisited\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Discovering Pester Tags Revisited &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"I revisit my task of getting Pester test tags using the Pester configuration object. I have a new PowerShell 7 function that gets the job done.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2022-01-06T14:47:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-01-06T14:53:09+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.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=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Discovering Pester Tags Revisited\",\"datePublished\":\"2022-01-06T14:47:17+00:00\",\"dateModified\":\"2022-01-06T14:53:09+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/\"},\"wordCount\":607,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/pesterconfiguration.png\",\"keywords\":[\"Function\",\"Pester\",\"PowerShell\"],\"articleSection\":[\"PowerShell\",\"PowerShell 7\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/\",\"name\":\"Discovering Pester Tags Revisited &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/pesterconfiguration.png\",\"datePublished\":\"2022-01-06T14:47:17+00:00\",\"dateModified\":\"2022-01-06T14:53:09+00:00\",\"description\":\"I revisit my task of getting Pester test tags using the Pester configuration object. I have a new PowerShell 7 function that gets the job done.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/pesterconfiguration.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/pesterconfiguration.png\",\"width\":615,\"height\":262},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8766\\\/discovering-pester-tags-revisited\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Discovering Pester Tags Revisited\"}]},{\"@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":"Discovering Pester Tags Revisited &#8226; The Lonely Administrator","description":"I revisit my task of getting Pester test tags using the Pester configuration object. I have a new PowerShell 7 function that gets the job done.","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\/8766\/discovering-pester-tags-revisited\/","og_locale":"en_US","og_type":"article","og_title":"Discovering Pester Tags Revisited &#8226; The Lonely Administrator","og_description":"I revisit my task of getting Pester test tags using the Pester configuration object. I have a new PowerShell 7 function that gets the job done.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/","og_site_name":"The Lonely Administrator","article_published_time":"2022-01-06T14:47:17+00:00","article_modified_time":"2022-01-06T14:53:09+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.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":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Discovering Pester Tags Revisited","datePublished":"2022-01-06T14:47:17+00:00","dateModified":"2022-01-06T14:53:09+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/"},"wordCount":607,"commentCount":1,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png","keywords":["Function","Pester","PowerShell"],"articleSection":["PowerShell","PowerShell 7"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/","name":"Discovering Pester Tags Revisited &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png","datePublished":"2022-01-06T14:47:17+00:00","dateModified":"2022-01-06T14:53:09+00:00","description":"I revisit my task of getting Pester test tags using the Pester configuration object. I have a new PowerShell 7 function that gets the job done.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/pesterconfiguration.png","width":615,"height":262},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Discovering Pester Tags Revisited"}]},{"@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":8759,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8759\/discovering-pester-tags-with-the-powershell-ast\/","url_meta":{"origin":8766,"position":0},"title":"Discovering Pester Tags with the PowerShell AST","author":"Jeffery Hicks","date":"January 5, 2022","format":false,"excerpt":"As I resolved at the end of last year, I am doing more with Pester in 2022. I'm getting a bit more comfortable with Pester 5 and as my tests grow in complexity I am embracing the use of tags. You can add tags to different Pester test elements. Then\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\/2022\/01\/get-all-tag-values.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-all-tag-values.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-all-tag-values.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/get-all-tag-values.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":8754,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8754\/accelerate-pester-test-development\/","url_meta":{"origin":8766,"position":1},"title":"Accelerate Pester Test Development","author":"Jeffery Hicks","date":"December 28, 2021","format":false,"excerpt":"The other day I shared my PowerShell plans for 2022. And needless to say, I didn't wait to dig in. I am working on a new module and since it won't be published until next month, I went ahead and marked it as Core only. I also started writing a\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\/2021\/12\/new-pesterblock.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/new-pesterblock.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/new-pesterblock.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/new-pesterblock.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/new-pesterblock.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/12\/new-pesterblock.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":8750,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8750\/powershell-plans-for-2022\/","url_meta":{"origin":8766,"position":2},"title":"PowerShell Plans for 2022","author":"Jeffery Hicks","date":"December 27, 2021","format":false,"excerpt":"I'm not much for writing year in review pieces. Nor, to be honest, do I often write New Year's resolutions. But I've been thinking about the work I've done this past year and what I might be doing in 2022 so I thought I'd share some thoughts on what 2022\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"binoculars","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/07\/pexels-skitterphoto-63901.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":7409,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/","url_meta":{"origin":8766,"position":3},"title":"Importing Pester Results into PowerShell","author":"Jeffery Hicks","date":"April 24, 2020","format":false,"excerpt":"Last week, a PowerShell scripting challenge was posted on the Iron Scripter web site.\u00a0 The idea was that when you run a Pester test, you can save the results to a specially formatted\u00a0 XML file. Invoke-Pester C:\\scripts\\sample.test.ps1 -OutputFile d:\\temp\\results.xml -OutputFormat JUnitXml I get this result. The challenge was to write\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\/04\/informationvariable-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":4994,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4994\/creating-new-powershell-projects\/","url_meta":{"origin":8766,"position":4},"title":"Creating New PowerShell Projects","author":"Jeffery Hicks","date":"May 17, 2016","format":false,"excerpt":"I've been writing scripts since the early days of DOS batch files. Like many of you I simply stick them all in a folder and move on to the next project. Most of my work is just for me or writing projects so this methodology worked just fine for me.\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\/2016\/05\/image_thumb.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2016\/05\/image_thumb.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2016\/05\/image_thumb.png?resize=525%2C300 1.5x"},"classes":[]},{"id":9023,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/9023\/powershell-first-timers\/","url_meta":{"origin":8766,"position":5},"title":"PowerShell First-Timers","author":"Jeffery Hicks","date":"May 11, 2022","format":false,"excerpt":"Are you a PowerShell first-timer? Someone who is finally dipping their toes into the PowerShell pool. Or maybe you want to poke around and see what all the fuss is about. If so, here are some steps you might want to take. Even if you've been using PowerShell for a\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\/2022\/05\/pester-install-fail.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/05\/pester-install-fail.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/05\/pester-install-fail.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/05\/pester-install-fail.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8766","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=8766"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8766\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=8766"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=8766"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=8766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}