Answers: <p>After resolving some syntax issues, I found the true cause of failing to throw the error.
  In my prior usage I was doing this through Inspec provisioner, which handled the exit codes. </p>
  
  <p>If you are using Pester and having to do the workaround I described above, then to ensure error's in a step are thrown you need to throw an exit code other than 0. </p>
  
  <p>The two steps I took that seem to work fine (I like some emoji fire in my logs )</p>
  
  <pre><code>$ErrorActionPreference = 'Stop'
  
  try 
  {
  # Do code here
  }
  catch
  {
     Write-Error " Failed to do something important `$TestFile: $TestFile"
    exit 1  # packer will recognize failure at this point
  }
  </code></pre>
  
  <p>Note that you will want to make sure your Azure DevOps Pipeline has the following settings to publish test results regardless of failing:</p>
  
  <pre class="lang-yaml prettyprint-override"><code># ℹ  Using Invoke-Build to call Packer. You can do this with a packer extension or any other way you prefer
  - task: PowerShell@2
    displayName: Run Packer Configuration
    inputs:
        filePath: build/build.ps1
        arguments: '-Task PackerBuild -Configuration $(Configuration)'
        errorActionPreference: 'Continue'
        pwsh: true
    continueOnError: true #I want to publish the test results regardless
  
  - task: PublishTestResults@2
    displayName: Publish Pester Tests
    inputs:
        testResultsFormat: 'NUnit'
        testResultsFiles: '**/TEST-*.xml'
    condition: succeededOrFailed()
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2020-03-11T21:07:32.477Z
Answers: 2020-03-11T21:07:32.477Z
Answers: sheldonhull
Body: <p>I'm building a packer pipeline and having an issue in getting the failure of a powershell provisioner step to fail the packer job itself. This is important as without failing the Packer job, the AMI would be published, despite the test failure.</p>
  
  <p>How I'm proceeding:</p>
  
  <ol>
  <li>Run provisioning setup steps</li>
  <li>Copy Pester Script to Remote machine</li>
  <li>Invoke inline powershell statement to <code>Invoke-Pester</code></li>
  <li>Download the test results from the Pester remote run</li>
  <li>Next provisioning step parses the file to count errors and throws error upon issue count > 0</li>
  </ol>
  
  <p>However, even with issue count being > 0 it is not causing the pipeline to fail. Additionally some errors thrown in other provisioner steps also fail to cause the Packer job to stop. I've set <code>$ErrorActionPreference = 'Stop'</code> on one of them and it didn't seem to make any difference.</p>
  
  <p>Here's part of the provisioning workflow for packer. </p>
  
  <pre><code>...     {
              "type": "file",
              "source": "{{ template_dir }}/tests/windows-server.tests.ps1",
              "destination": "{{ user `TEMP_DIRECTORY` }}/"
          },
          {
              "type": "powershell",
              "environment_vars": [
                  "TEMP_DIRECTORY={{ user `TEMP_DIRECTORY` }}/"
              ],
              "inline": [
                  "if(-not (Get-InstalledModule Pester -MinimumVersion 4.10.1)){ Install-Module Pester -Scope AllUsers -AllowClobber -Force -verbose} ",
                  "Import-Module Pester -MinimumVersion 4.10.1 -Force -DisableNameChecking",
                  "$null = New-Item -Path $ENV:TEMP_DIRECTORY -ItemType Directory -Force -ErrorAction SilentlyContinue",
                  "$testresult = Invoke-Pester -Script (Join-Path $ENV:TEMP_DIRECTORY 'windows-server.tests.ps1') -OutputFile (Join-Path $ENV:TEMP_DIRECTORY 'TEST-pester-results.xml') -OutputFormat 'NUnitXML' -PassThru"
              ]
          },
          {
              "type": "file",
              "direction": "download",
              "source": "{{ user `TEMP_DIRECTORY` }}/TEST-pester-results.xml",
              "destination": "{{ template_dir }}/artifacts/TEST-pester-results.xml"
          }, ...
  </code></pre>
  
  <p>Once this part is done it's followed by this step which is some logic from this blog post: </p>
  
  <pre><code>  {
              "environment_vars": [
                  "TEMP_DIRECTORY={{ user `TEMP_DIRECTORY` }}/"
              ],
              "script": "./scripts/Get-TestResults.ps1",
              "type": "powershell"
          },
  
  </code></pre>
  
  <p>The <code>Get-TestResults.ps1</code> has the following function thanks to this article: <a href="https://samcogan.com/testing-packer-images-with-pester" rel="nofollow noreferrer">Testing Packer Images with Pester</a> written originally by <a href="https://stackoverflow.com/users/8768/sam-cogan">Sam Cogan</a> and modified slightly by me.</p>
  
  <pre><code>[cmdletbinding()]
  param()
  $TestFile = Join-Path $ENV:TEMP_DIRECTORY 'TEST-pester-results.xml'
  
  if (Test-Path -Path $TestFile -PathType Leaf)
  {
      [xml]$testResults = Get-Content -Path $TestFile -Raw
      $totalIssues=[int]$($testResults.'test-results'.errors) + [int]$($testResults.'test-results'.failures) + [int]$($testResults.'test-results'.invalid)
      exit $totalIssues
  }
  else
  {
      Write-Error " Failed to find `$TestFile: $TestFile"
      Write-Warning "$(Get-ChildItem $ENV:TEMP_DIRECTORY -Recurse | Format-Table -autosize -wrap | Out-String)"
      Write-Error " Failed to find `$TestFile: $TestFile"
      exit 1  #not a good exit :-)
  
  }
  
  </code></pre>
  
Comments: CC BY-SA 4.0
Comments: 2020-03-11T19:03:57.860Z
Comments: I found one syntax issue when reworking through this, as the default Packer behavior per PowerShell's default behavior is `$ErrorActionPreference = 'continue'` . I set manually now at the top of all my scripts and also fixed a syntax issue on `Get-TestResults` and will see if it works correctly this time. Fingers crossed 
Comments: sheldonhull
Tags: <azure-devops><packer>
Title: How do fail a Packer pipeline upon powershell provisioner pester test failure?
UserDisplayName: sheldonhull
ThreadText: # How do fail a Packer pipeline upon powershell provisioner pester test failure?
  
  (Asked by: username_0 on 2020-03-11)
  
  I'm building a packer pipeline and having an issue in getting the failure of a powershell provisioner step to fail the packer job itself. This is important as without failing the Packer job, the AMI would be published, despite the test failure.
  
  How I'm proceeding:
  
  1. Run provisioning setup steps
  2. Copy Pester Script to Remote machine
  3. Invoke inline powershell statement to `Invoke-Pester`
  4. Download the test results from the Pester remote run
  5. Next provisioning step parses the file to count errors and throws error upon issue count > 0
  
  However, even with issue count being > 0 it is not causing the pipeline to fail. Additionally some errors thrown in other provisioner steps also fail to cause the Packer job to stop. I've set `$ErrorActionPreference = 'Stop'` on one of them and it didn't seem to make any difference.
  
  Here's part of the provisioning workflow for packer.
  
  ```
  ...     {
              "type": "file",
              "source": "{{ template_dir }}/tests/windows-server.tests.ps1",
              "destination": "{{ user `TEMP_DIRECTORY` }}/"
          },
          {
              "type": "powershell",
              "environment_vars": [
                  "TEMP_DIRECTORY={{ user `TEMP_DIRECTORY` }}/"
              ],
              "inline": [
                  "if(-not (Get-InstalledModule Pester -MinimumVersion 4.10.1)){ Install-Module Pester -Scope AllUsers -AllowClobber -Force -verbose} ",
                  "Import-Module Pester -MinimumVersion 4.10.1 -Force -DisableNameChecking",
                  "$null = New-Item -Path $ENV:TEMP_DIRECTORY -ItemType Directory -Force -ErrorAction SilentlyContinue",
                  "$testresult = Invoke-Pester -Script (Join-Path $ENV:TEMP_DIRECTORY 'windows-server.tests.ps1') -OutputFile (Join-Path $ENV:TEMP_DIRECTORY 'TEST-pester-results.xml') -OutputFormat 'NUnitXML' -PassThru"
              ]
          },
          {
              "type": "file",
              "direction": "download",
              "source": "{{ user `TEMP_DIRECTORY` }}/TEST-pester-results.xml",
              "destination": "{{ template_dir }}/artifacts/TEST-pester-results.xml"
          }, ...
  
  ```
  
  Once this part is done it's followed by this step which is some logic from this blog post:
  
  ```
    {
              "environment_vars": [
                  "TEMP_DIRECTORY={{ user `TEMP_DIRECTORY` }}/"
              ],
              "script": "./scripts/Get-TestResults.ps1",
              "type": "powershell"
          },
  
  ```
  
  The `Get-TestResults.ps1` has the following function thanks to this article: [Testing Packer Images with Pester](https://samcogan.com/testing-packer-images-with-pester) written originally by [Sam Cogan](https://stackoverflow.com/users/8768/sam-cogan) and modified slightly by me.
  
  ```
  [cmdletbinding()]
  param()
  $TestFile = Join-Path $ENV:TEMP_DIRECTORY 'TEST-pester-results.xml'
  
  if (Test-Path -Path $TestFile -PathType Leaf)
  {
      [xml]$testResults = Get-Content -Path $TestFile -Raw
      $totalIssues=[int]$($testResults.'test-results'.errors) + [int]$($testResults.'test-results'.failures) + [int]$($testResults.'test-results'.invalid)
      exit $totalIssues
  }
  else
  {
      Write-Error " Failed to find `$TestFile: $TestFile"
      Write-Warning "$(Get-ChildItem $ENV:TEMP_DIRECTORY -Recurse | Format-Table -autosize -wrap | Out-String)"
      Write-Error " Failed to find `$TestFile: $TestFile"
      exit 1  #not a good exit :-)
  
  }
  
  ```
  
  **Tags:** azure-devops, packer
  
  > **Comments:**
  > **username_0**: I found one syntax issue when reworking through this, as the default Packer behavior per PowerShell's default behavior is `$ErrorActionPreference = 'continue'` . I set manually now at the top of all my scripts and also fixed a syntax issue on `Get-TestResults` and will see if it works correctly this time. Fingers crossed   
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2020-03-11. Score: 4
  
  After resolving some syntax issues, I found the true cause of failing to throw the error.
  In my prior usage I was doing this through Inspec provisioner, which handled the exit codes.
  
  If you are using Pester and having to do the workaround I described above, then to ensure error's in a step are thrown you need to throw an exit code other than 0.
  
  The two steps I took that seem to work fine (I like some emoji fire in my logs )
  
  ```
  $ErrorActionPreference = 'Stop'
  
  try 
  {
  # Do code here
  }
  catch
  {
     Write-Error " Failed to do something important `$TestFile: $TestFile"
    exit 1  # packer will recognize failure at this point
  }
  
  ```
  
  Note that you will want to make sure your Azure DevOps Pipeline has the following settings to publish test results regardless of failing:
  
  ```yaml
  # ℹ  Using Invoke-Build to call Packer. You can do this with a packer extension or any other way you prefer
  - task: PowerShell@2
    displayName: Run Packer Configuration
    inputs:
        filePath: build/build.ps1
        arguments: '-Task PackerBuild -Configuration $(Configuration)'
        errorActionPreference: 'Continue'
        pwsh: true
    continueOnError: true #I want to publish the test results regardless
  
  - task: PublishTestResults@2
    displayName: Publish Pester Tests
    inputs:
        testResultsFormat: 'NUnit'
        testResultsFiles: '**/TEST-*.xml'
    condition: succeededOrFailed()
  
  ```
  
  
  ---
  
  