{"id":7409,"date":"2020-04-24T13:21:54","date_gmt":"2020-04-24T17:21:54","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=7409"},"modified":"2020-04-24T13:21:57","modified_gmt":"2020-04-24T17:21:57","slug":"importing-pester-results-into-powershell","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/","title":{"rendered":"Importing Pester Results into PowerShell"},"content":{"rendered":"<p>Last week, a PowerShell scripting <a href=\"https:\/\/ironscripter.us\/pestering-for-a-powershell-challenge\/\" target=\"_blank\" rel=\"noopener noreferrer\">challenge<\/a> was posted on the Iron Scripter web site.&nbsp; The idea was that when you run a Pester test, you can save the results to a specially formatted&nbsp; XML file.<\/p>\n<p><!--StartFragment --><\/p>\n<pre>Invoke-Pester C:\\scripts\\sample.test.ps1 -OutputFile d:\\temp\\results.xml -OutputFormat JUnitXml<\/pre>\n<p><!--EndFragment --><\/p>\n<p>I get this result.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7410\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.png\" alt=\"pester-export\" width=\"1552\" height=\"863\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.png 1552w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export-300x167.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export-1024x569.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export-768x427.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export-1536x854.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export-850x473.png 850w\" sizes=\"auto, (max-width: 1552px) 100vw, 1552px\" \/>The challenge was to write a PowerShell command that could take the XML file and recreate this output as much as possible. Here's my result.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7411\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import.png\" alt=\"pester-import\" width=\"1360\" height=\"892\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import.png 1360w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import-300x197.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import-1024x672.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import-768x504.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import-350x230.png 350w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-import-850x558.png 850w\" sizes=\"auto, (max-width: 1360px) 100vw, 1360px\" \/>I have added a metadata header, but otherwise I think this is a pretty good recreation. Are you curious how I did this? If you want to try your hand at the challenge first, stop reading now.<\/p>\n<h2>Spoiler Alert<\/h2>\n<p>I wrote my function to recreate Pester results using the JunitXML format. It would be nice at some point to modify the function to be able to handle both XML formats. The function I wrote has a Path parameter . I can specify a value or pipe a file to the command.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Param(\n        [Parameter(position = 0, ValueFromPipeline, HelpMessage = \"Specify the path to the JunitXML Pester test file.\")]\n        [ValidateNotNullorEmpty()]\n        #verify the file exists and it is an XML file\n        [ValidateScript({\n            If ((Test-Path $_) -AND ($_.split('.')[-1] -eq 'XML' )) {\n                $True\n            }\n            else {\n                #display a custom validation error message\n                Throw \"The file could not be found or wasn't an XML file.\"\n            }\n        })]\n        [Alias(\"pspath\")]\n        [string]$Path\n    )\n<\/pre>\n<p>The parameter definition is using a few validation tests. The main test is to ensure that the file exists and that it ends in XML. I have other validation later to test if it is a JunitXML file. Yes, I know that I could technically export the results using any file extension, but I'm assuming XML plus I wanted to demonstrate this technique.<\/p>\n<p>The other feature in the parameter is that I am creating my own custom error message. When you use [ValidateScript()], the scriptblock must give you True or False.&nbsp; In my case, if the test fails, I am throwing a customized error message.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7412\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1.png\" alt=\"paramfail-1\" width=\"1860\" height=\"270\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1.png 1860w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1-300x44.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1-1024x149.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1-768x111.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1-1536x223.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-1-850x123.png 850w\" sizes=\"auto, (max-width: 1860px) 100vw, 1860px\" \/><\/p>\n<p>PowerShell 7 handles this even nicer.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7413\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2.png\" alt=\"paramfail-2\" width=\"2057\" height=\"132\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2.png 2057w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2-300x19.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2-1024x66.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2-768x49.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2-1536x99.png 1536w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2-2048x131.png 2048w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/paramfail-2-850x55.png 850w\" sizes=\"auto, (max-width: 2057px) 100vw, 2057px\" \/><\/p>\n<p>At this point it becomes a matter of parsing the XML document.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">Process {\n        Write-Verbose \"Processing $Path\"\n        [xml]$doc = Get-Content -path $Path\n<\/pre>\n<p>I can look inside the XML to determine if this is a junit file. If it isn't I'll bail out of the command.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">if ($doc.testsuites.noNamespaceSchemaLocation -notmatch \"junit\") {\n            Write-Warning \"Could not import $Path. You must specify a Pester test result file using the JUnitXML format.\"\n            #abort\n            return\n        }\n<\/pre>\n<p>Otherwise, I'm parsing the document to get the metadata information which is assembled in a here-string and written to the host using Write-Host. In fact, the entire function writes directly to the console using Write-Host. Nothing is written to the pipeline. Although I will show you an option later. For this challenge, using Write-Host is perfectly fine. Another option would be to write a version of my function for PowerShell 7 and use ANSI escapes for the colorization. I'll save that for another time or you can write it.<\/p>\n<h2>Parsing Tests<\/h2>\n<p>The tricky part was parsing the test results. I had this XML to work with.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">&lt;testcase name=\"Alpha.Should have a value over 1\" status=\"Passed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.465\" \/&gt;\n    &lt;testcase name=\"Alpha.Should fail on a null value\" status=\"Failed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.190\"&gt;\n      &lt;failure message=\"Expected $true, but got $false.\" \/&gt;\n    &lt;\/testcase&gt;\n    &lt;testcase name=\"Alpha.Should accept a mandatory Computername parameter\" status=\"Passed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.300\" \/&gt;\n    &lt;testcase name=\"Alpha.Testing.Should have a value of 4\" status=\"Passed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.894\" \/&gt;\n    &lt;testcase name=\"Alpha.Testing.Should run without error\" status=\"Passed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"1.150\" \/&gt;\n    &lt;testcase name=\"Bravo.Should have a value less than 1\" status=\"Passed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.525\" \/&gt;\n    &lt;testcase name=\"Bravo.Should export the gravitational constant\" status=\"Skipped\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.000\"&gt;\n      &lt;skipped message=\"\" \/&gt;\n    &lt;\/testcase&gt;\n    &lt;testcase name=\"Bravo.Should run without errors\" status=\"Passed\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"2.357\" \/&gt;\n    &lt;testcase name=\"Bravo.Should run with credentials\" status=\"Pending\" classname=\"C:\\work\\sample.test.ps1\" assertions=\"0\" time=\"0.000\"&gt;\n      &lt;skipped message=\"\" \/&gt;\n    &lt;\/testcase&gt;\n<\/pre>\n<p>The Name attribute is the key item. The first part, up to the first period, is the Describe block. In my sample this is Alpha and Bravo.&nbsp; Anything after the period is the assertion or the It statement. Unless, there is an intermediate word like 'Testing'. This is a Pester Context element.<\/p>\n<p>I tried several techniques to pull this text apart. Eventually I settled on using a regular expression pattern.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">[regex]$rx = \"(?^[\\w-_\\s]+(?=\\.))\\.((?(?&lt;=\\.)\\w+(?=\\.))\\.)?(?(?&lt;=\\.).*)\"\n<\/pre>\n<p>The pattern uses named captures to identify the Describe, Context and Assertion components.<\/p>\n<blockquote><p>Looking to learn more about regular expressions in PowerShell? I <a href=\"https:\/\/bit.ly\/2KthTF6\" target=\"_blank\" rel=\"noopener noreferrer\">created an entire course<\/a> on the subject for Pluralsight.<\/p><\/blockquote>\n<p>I use this pattern to turn each test case into a custom object.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">$tests = $doc.testsuites.testsuite.testcase | Group-Object -property Name\n        Write-Verbose \"Processing $($tests.count) tests\"\n\n        #turn each test into an object using a regex to split\n        $testobj = foreach ($test in $Tests) {\n            $m = $rx.Matches($test.name)\n            [pscustomobject]@{\n                Describe  = $m.groups[2]\n                Context   = $m.groups[3]\n                Assertion = $m.groups[4]\n                TestCase  = $test.group\n            }\n        } #foreach test\n<\/pre>\n<p>I found this to be much easier to work with. Now I can use commands like Group-Object and ForEach to process the results in an orderly fashion, writing results to the host based east test. I ended up creating a private helper function, _parseTestCase, that would write the result to the host. When you look at the code, you'll see I'm using a Switch statement to determine what symbol and foreground color to use.<\/p>\n<p>For the summary, I grouped the TestCase node on the Status property as a hashtable. The hashtable keys will things like 'Failed' and 'Skipped'. This makes it easy to get the counts that I need to display.<\/p>\n<pre class=\"lang:ps mark:0 decode:true\">#write the summary information to the host in color\n        $testHash = $doc.testsuites.testsuite.testcase | Group-Object -property Status -AsHashTable -AsString\n\n        Write-Host \"Tests completed in $(New-TimeSpan -seconds $doc.testsuites.time)\" -ForegroundColor White\n        Write-Host \"Tests Passed: $($doc.testsuites.tests), \" -ForegroundColor White -NoNewline\n        Write-Host \"Failed: $($TestHash[\"Failed\"].count), \" -ForegroundColor Red -NoNewline\n        Write-Host \"Skipped: $($TestHash[\"Skipped\"].count), \" -ForegroundColor Yellow -NoNewline\n        Write-Host \"Pending: $($TestHash[\"Pending\"].count), \" -ForegroundColor gray -NoNewline\n        Write-Host \"Inconclusive: $($TestHash[\"Inconclusive\"].count)\" -ForegroundColor DarkGray\n<\/pre>\n<p>The complete code is on Github.<br \/>\n<script src=\"https:\/\/gist.github.com\/jdhitsolutions\/e350a5e4a338a241e6a2ae31d683f6cc.js\"><\/script><\/p>\n<p>The function has an alias of 'iptr'. I haven't tested with a lot of different test files so there may be things I've overlooked. But for the tests I write, this appears to be working.<\/p>\n<h2>Write-Information<\/h2>\n<p>I have one more thing to show you. Even though my code is using Write-Host, not all is lost. Write-Host is also a wrapper for Write-Information. Which means when I run my command like this (using my alias)<\/p>\n<p><!--StartFragment --><\/p>\n<pre class=\"lang:ps mark:0 decode:true\">PS C:\\&gt;; iptr S:\\sample.pester-results.xml -InformationVariable out<\/pre>\n<p><!--EndFragment --><\/p>\n<p>I get a variable, $out.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7414\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1.png\" alt=\"informationvariable-1\" width=\"1325\" height=\"940\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1.png 1325w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1-300x213.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1-1024x726.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1-768x545.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/informationvariable-1-850x603.png 850w\" sizes=\"auto, (max-width: 1325px) 100vw, 1325px\" \/>But this is actually a rich object.<\/p>\n<p><!--StartFragment --><\/p>\n<pre class=\"lang:text mark:0 decode:true\">PS C:\\&gt; $out[0..1] | select *\n\n\nMessageData :\n********************************************************************************\nTest File : C:\\work\\sample.test.ps1\nTest Result : C:\\scripts\\sample.pester-results.xml\nTest Date : 4\/13\/2020 7:04:48 PM\nComputername : DESKTOP1\n********************************************************************************\nSource : C:\\scripts\\Analyze-TestResult.ps1\nTimeGenerated : 4\/24\/2020 12:57:33 PM\nTags : {PSHOST}\nUser : BOVINE320\\Jeff\nComputer : Bovine320\nProcessId : 17492\nNativeThreadId : 26760\nManagedThreadId : 14\n\nMessageData :\nDescribing Alpha\nSource : C:\\scripts\\Analyze-TestResult.ps1\nTimeGenerated : 4\/24\/2020 12:57:33 PM\nTags : {PSHOST}\nUser : BOVINE320\\Jeff\nComputer : Bovine320\nProcessId : 17492\nNativeThreadId : 26760\nManagedThreadId : 14<\/pre>\n<p><!--EndFragment --><\/p>\n<p>I can do anything I want with this data. I could re-export what I needed to a json or xml file. Or send it to a text file. The format won't be the same without a little tweaking.&nbsp; But again, I'll leave that exercise for you.<\/p>\n<p>In the meantime, if you didn't create your own challenge solution, I hope you'll give this a try and let me know what you think. Enjoy your weekend.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last week, a PowerShell scripting challenge was posted on the Iron Scripter web site.&nbsp; The idea was that when you run a Pester test, you can save the results to a specially formatted&nbsp; 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 a PowerShell command that could&#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: Importing Pester Results into #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,8],"tags":[618,520,534,250,540,206],"class_list":["post-7409","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-iron-scripter","tag-pester","tag-powershell","tag-regular-expressions","tag-scripting","tag-xml"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Importing Pester Results into PowerShell &#8226; The Lonely Administrator<\/title>\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\/7409\/importing-pester-results-into-powershell\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Importing Pester Results into PowerShell &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"Last week, a PowerShell scripting challenge was posted on the Iron Scripter web site.&nbsp; The idea was that when you run a Pester test, you can save the results to a specially formatted&nbsp; XML file. Invoke-Pester C:scriptssample.test.ps1 -OutputFile d:tempresults.xml -OutputFormat JUnitXml I get this result. The challenge was to write a PowerShell command that could...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-24T17:21:54+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-04-24T17:21:57+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.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=\"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\\\/7409\\\/importing-pester-results-into-powershell\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Importing Pester Results into PowerShell\",\"datePublished\":\"2020-04-24T17:21:54+00:00\",\"dateModified\":\"2020-04-24T17:21:57+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/\"},\"wordCount\":820,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/pester-export.png\",\"keywords\":[\"Iron Scripter\",\"Pester\",\"PowerShell\",\"Regular Expressions\",\"Scripting\",\"xml\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/\",\"name\":\"Importing Pester Results into PowerShell &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/pester-export.png\",\"datePublished\":\"2020-04-24T17:21:54+00:00\",\"dateModified\":\"2020-04-24T17:21:57+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/pester-export.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2020\\\/04\\\/pester-export.png\",\"width\":1552,\"height\":863},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/7409\\\/importing-pester-results-into-powershell\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Importing Pester Results into PowerShell\"}]},{\"@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":"Importing Pester Results into PowerShell &#8226; The Lonely Administrator","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\/7409\/importing-pester-results-into-powershell\/","og_locale":"en_US","og_type":"article","og_title":"Importing Pester Results into PowerShell &#8226; The Lonely Administrator","og_description":"Last week, a PowerShell scripting challenge was posted on the Iron Scripter web site.&nbsp; The idea was that when you run a Pester test, you can save the results to a specially formatted&nbsp; XML file. Invoke-Pester C:scriptssample.test.ps1 -OutputFile d:tempresults.xml -OutputFormat JUnitXml I get this result. The challenge was to write a PowerShell command that could...","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/","og_site_name":"The Lonely Administrator","article_published_time":"2020-04-24T17:21:54+00:00","article_modified_time":"2020-04-24T17:21:57+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.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":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Importing Pester Results into PowerShell","datePublished":"2020-04-24T17:21:54+00:00","dateModified":"2020-04-24T17:21:57+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/"},"wordCount":820,"commentCount":0,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.png","keywords":["Iron Scripter","Pester","PowerShell","Regular Expressions","Scripting","xml"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/","name":"Importing Pester Results into PowerShell &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.png","datePublished":"2020-04-24T17:21:54+00:00","dateModified":"2020-04-24T17:21:57+00:00","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/04\/pester-export.png","width":1552,"height":863},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7409\/importing-pester-results-into-powershell\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Importing Pester Results into PowerShell"}]},{"@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":7559,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7559\/an-expanded-powershell-scripting-inventory-tool\/","url_meta":{"origin":7409,"position":0},"title":"An Expanded PowerShell Scripting Inventory Tool","author":"Jeffery Hicks","date":"June 19, 2020","format":false,"excerpt":"The other day I shared my code that I worked up to solve an Iron Scripter PowerShell challenge. One of the shortcomings was that I didn't address a challenge to include a property that would indicate what file was using a given command. I also felt I could do better\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\/06\/get-psscriptinventory.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/get-psscriptinventory.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/get-psscriptinventory.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/get-psscriptinventory.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/get-psscriptinventory.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/get-psscriptinventory.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":4994,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4994\/creating-new-powershell-projects\/","url_meta":{"origin":7409,"position":1},"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":7549,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7549\/building-a-powershell-inventory\/","url_meta":{"origin":7409,"position":2},"title":"Building a PowerShell Inventory","author":"Jeffery Hicks","date":"June 16, 2020","format":false,"excerpt":"A few weeks ago, a new Iron Scripter PowerShell scripting challenge was issued. For this challenge we were asked to write some PowerShell code that we could use to inventory our PowerShell script library.\u00a0 Here's how I approached the problem, which by no means is the only way. Lines of\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\/06\/ast-results.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/ast-results.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/06\/ast-results.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":8107,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8107\/scripting-challenge-meetup\/","url_meta":{"origin":7409,"position":3},"title":"Scripting Challenge Meetup","author":"Jeffery Hicks","date":"February 1, 2021","format":false,"excerpt":"As you probably know, I am the PowerShell problem master behind the challenges from the Iron Scripter site. Solving a PowerShell scripting challenge is a great way to test your skills and expand your knowledge. The final result is merely a means to an end. How you get there and\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\/02\/rubik.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":8759,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8759\/discovering-pester-tags-with-the-powershell-ast\/","url_meta":{"origin":7409,"position":4},"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":8766,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8766\/discovering-pester-tags-revisited\/","url_meta":{"origin":7409,"position":5},"title":"Discovering Pester Tags Revisited","author":"Jeffery Hicks","date":"January 6, 2022","format":false,"excerpt":"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\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\/container-tags.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/7409","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=7409"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/7409\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=7409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=7409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=7409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}