reports/3_wara_reports_generator.ps1

#Requires -Version 7

<#
.SYNOPSIS
Well-Architected Reliability Assessment Report Generator Script
 
.DESCRIPTION
The script "3_wara_reports_generator" processes the Excel file created by the "2_wara_data_analyzer" script and generates the final PowerPoint and Word reports for the Well-Architected Reliability Assessment.
 
.PARAMETER Help
Switch to display help information.
 
.PARAMETER CustomerName
Name of the customer for whom the report is being generated.
 
.PARAMETER WorkloadName
Name of the workload being assessed.
 
.PARAMETER ExcelFile
Path to the Excel file created by the "2_wara_data_analyzer" script.
 
.PARAMETER Heavy
Switch to enable heavy processing mode. When enabled, this mode introduces additional delays using Start-Sleep at various points in the script to handle heavy environments more gracefully. This can help in scenarios where the system resources are limited or the operations being performed are resource-intensive, ensuring the script doesn't overwhelm the system.
 
.PARAMETER PPTTemplateFile
Path to the PowerPoint template file.
 
.EXAMPLE
.\3_wara_reports_generator.ps1 -ExcelFile 'C:\WARA_Script\WARA Action Plan 2024-03-07_16_06.xlsx' -CustomerName 'ABC Customer' -WorkloadName 'SAP On Azure' -Heavy -PPTTemplateFile 'C:\Templates\Template.pptx' -WordTemplateFile 'C:\Templates\Template.docx'
 
.LINK
https://github.com/Azure/Azure-Proactive-Resiliency-Library-v2
#>


Param(
  [switch] $Help,
  #[switch] $csvExport,
  [switch] $includeLow,
  [string] $CustomerName,
  [string] $WorkloadName,
  [Parameter(mandatory = $true)]
  [string] $ExpertAnalysisFile,
  [string] $AssessmentFindingsFile,
  [string] $PPTTemplateFile
)

# Checking the operating system running this script.
if (-not $IsWindows) {
  Write-Host 'This script only supports Windows operating systems currently. Please try to run with Windows operating systems.'
  Exit
  }
# TODO: Remove if not needed
<# $CurrentPath = Get-Location
$CurrentPath = $CurrentPath.Path #>

if (!$PPTTemplateFile) {
  write-host ("$PSScriptRoot/Mandatory - Executive Summary presentation - Template.pptx")
  if ((Test-Path -Path ("$PSScriptRoot/Mandatory - Executive Summary presentation - Template.pptx") -PathType Leaf) -eq $true) {
    $PPTTemplateFile = ("$PSScriptRoot/Mandatory - Executive Summary presentation - Template.pptx")
  }
  else {
    Write-Host "This script requires specific Microsoft PowerPoint template, which are available in the Azure Proactive Resiliency Library. You can download the templates from this GitHub repository:"
    Write-Host "https://github.com/Azure/Azure-Proactive-Resiliency-Library-v2/tree/main/tools" -ForegroundColor Yellow
    Exit
  }
}

if (!$AssessmentFindingsFile) {
  write-host ("$PSScriptRoot/Assessment-Findings-Report-v1.xlsx")
  if ((Test-Path -Path ("$PSScriptRoot/Assessment-Findings-Report-v1.xlsx") -PathType Leaf) -eq $true) {
    $AssessmentFindingsFile = ("$PSScriptRoot/Assessment-Findings-Report-v1.xlsx")
  }
  else {
    Write-Host "This script requires specific Microsoft Excel template, which are available in the Azure Proactive Resiliency Library. You can download the templates from this GitHub repository:"
    Write-Host "https://github.com/Azure/Azure-Proactive-Resiliency-Library-v2/tree/main/tools" -ForegroundColor Yellow
    Exit
  }
}

if (!$ExpertAnalysisFile) {
  Write-Host "The Expert-Analysis Excel file is missing. Please provide the path to the Expert-Analysis Excel file." -ForegroundColor Yellow
  Exit
}


if (!$CustomerName) {
  $CustomerName = '[Customer Name]'
}

if (!$WorkloadName) {
  $WorkloadName = '[Workload Name]'
}

$TableStyle = 'Light19'

$Runtime = Measure-Command -Expression {


  ######################## REGULAR Functions ##########################

  function Test-ReviewedRecommendations {
    Param($ExcelFile)

    $ExcelContent = Import-Excel -Path $ExcelFile -WorksheetName '4.ImpactedResourcesAnalysis' -StartRow 12

    if ( ($ExcelContent | Where-Object { $_.Impact -ne 'Low' -and $_.'REQUIRED ACTIONS / REVIEW STATUS' -ne 'Reviewed'}).count -ge 1)
      {
        Write-Host ""
        Write-Host "There are still some recommendations that need to be reviewed." -ForegroundColor Yellow
        Write-Host "Please review all the recommendations in the Expert-Analysis file before running the report generator." -ForegroundColor Yellow
        Write-Host ""
        Exit
      }

  }

  function New-AssessmentFindingsFile {
    Param(
      [string]$AssessmentFindingsFile
      )

    $workingFolderPath = Get-Location
    $workingFolderPath = $workingFolderPath.Path
    $ExcelPkg = Open-ExcelPackage -Path $AssessmentFindingsFile
    $NewAssessmentFindings = ($workingFolderPath + '\Assessment-Findings-Report-v1-' + (Get-Date -Format 'yyyy-MM-dd-HH-mm') + '.xlsx')
    Close-ExcelPackage -ExcelPackage $ExcelPkg -SaveAs $NewAssessmentFindings

    return $NewAssessmentFindings
  }

  function New-PPTFile {
    Param(
      [string]$PPTTemplateFile
      )

    $workingFolderPath = Get-Location
    $workingFolderPath = $workingFolderPath.Path
    $NewPPTFile = ($workingFolderPath + '\Executive Summary Presentation - ' + $CustomerName + ' - ' + (get-date -Format "yyyy-MM-dd-HH-mm") + '.pptx')

    return $NewPPTFile
  }

  function Test-Requirement {
    # Install required modules
    Write-Host "Validating " -NoNewline
    Write-Host "ImportExcel" -ForegroundColor Cyan -NoNewline
    Write-Host " Module.."
    $ImportExcel = Get-Module -Name ImportExcel -ListAvailable -ErrorAction silentlycontinue
    if ($null -eq $ImportExcel) {
      Write-Host "Installing ImportExcel Module" -ForegroundColor Yellow
      Install-Module -Name ImportExcel -Force -SkipPublisherCheck
    }
  }

  function Set-LocalFile {
    # Define script path as the default path to save files
      $workingFolderPath = $PSScriptRoot
      Set-Location -path $workingFolderPath;
      $clonePath = "$workingFolderPath\Azure-Proactive-Resiliency-Library"
      Write-Debug "Checking the version of the script"
      $RepoVersion = Get-Content -Path "$clonePath\tools\Version.json" -ErrorAction SilentlyContinue | ConvertFrom-Json
      if ($Version -ne $RepoVersion.Generator) {
        Write-Host "This version of the script is outdated. " -BackgroundColor DarkRed
        Write-Host "Please use a more recent version of the script." -BackgroundColor DarkRed
      }
      else {
        Write-Host "This version of the script is current version. " -BackgroundColor DarkGreen
      }

  }

  function Get-ExcelImpactedResources {
    Param($ExcelFile)

    $ExcelContent = Import-Excel -Path $ExcelFile -WorksheetName '4.ImpactedResourcesAnalysis' -StartRow 12
    #$ImpactedResources = $ExcelContent

    return $ExcelContent
  }

  function Get-ExcelWorkloadInventory {
    Param($ExcelFile)

    $ExcelContent = Import-Excel -Path $ExcelFile -WorksheetName '2.WorkloadInventory' -StartRow 12

    return $ExcelContent

  }

  function Get-ExcelPlatformIssues {
    Param($ExcelFile)

    try {
      $PlatformIssues = Import-Excel -Path $ExcelFile -WorksheetName '5.PlatformIssuesAnalysis' -StartRow 12
    }
    catch {
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Platform Issues not found in the Excel File..')
    }

    return $PlatformIssues

  }

  function Get-ExcelSupportTicket {
    Param($ExcelFile)

    try {
      $SupportTickets = Import-Excel -Path $ExcelFile -WorksheetName "6.SupportRequestsAnalysis" -AsText 'Ticket ID' -StartRow 12
    }
    catch {
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Support Tickets not found in the Excel File..')
    }

    return $SupportTickets
  }

  function Get-ExcelRetirement {
    Param($ExcelFile)

    try {
      $Retirements = Import-Excel -Path $ExcelFile -WorksheetName "4.ImpactedResourcesAnalysis" -StartRow 12
      $Retirements = $Retirements | Where-Object {$_.Source -eq 'Azure Service Health - Service Retirements'}
    }
    catch {
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Service Retirements not found in the Excel File..')
    }

    return $Retirements

  }

  function Build-SummaryActionPlan {
    Param($ImpactedResources,$includeLow)

    if ($includeLow.IsPresent)
      {
        $Recommendations = $ImpactedResources | Where-Object {$_.impact -in ('High','Medium','Low')}
      }
    else
      {
        $Recommendations = $ImpactedResources | Where-Object {$_.impact -in ('High','Medium')}
      }

    $RecomCount = ($ImpactedResources.recommendationId | Select-Object -Unique).count
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Creating CSV file for: '+ $RecomCount +' recommendations')

    $CXSummaryArray = Foreach ($Recommendation in $Recommendations)
      {
        $tmp = [PSCustomObject]@{
          'Recommendation Guid'       = $Recommendation.Guid
          'Recommendation Title'      = $Recommendation.'Recommendation Title'
          'Priority'                  = $Recommendation.Impact
          'Description'               = $Description.'Long Description'
          'Resource ID'               = $Recommendation.id
        }
        $tmp
      }

    return $CXSummaryArray

  }

  ######################## PPT Functions ##########################

  ############# Slide 1
  function Remove-PPTSlide1 {
    Param($Presentation,$CustomerName,$WorkloadName)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Removing Slide 1..')

    ($Presentation.Slides | Where-Object { $_.SlideIndex -eq 1 }).Delete()

    $Slide1 = $Presentation.Slides | Where-Object { $_.SlideIndex -eq 1 }

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Slide 1 - Adding Customer name: ' + $CustomerName + '. And Workload name: ' + $WorkloadName)
    ($Slide1.Shapes | Where-Object { $_.Id -eq 5 }).TextFrame.TextRange.Text = ($CustomerName + ' - ' + $WorkloadName)
  }

  ############# SLide 12
  function Build-PPTSlide12 {
    Param($Presentation,$AUTOMESSAGE,$WorkloadName,$ResourcesTypes)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 12 - Workload Summary..')

    $SlideWorkloadSummary = $Presentation.Slides | Where-Object { $_.SlideIndex -eq 12 }

    $TargetShape = ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 9 })
    $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

    $TargetShape = ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 8 })
    $TargetShape.Delete()

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 12 - Adding Workload name: ' + $WorkloadName)
    ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 3 }).TextFrame.TextRange.Text = ('During the engagement, the Workload ' + $WorkloadName + ' has been reviewed. The solution is hosted in two Azure regions, and runs mainly IaaS resources, with some PaaS resources, which includes but is not limited to:')

    $loop = 1
    foreach ($ResourcesType in $ResourcesTypes) {
      $LogResName = $ResourcesType.Name
      $LogResCount = $ResourcesType.'Count'
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 12 - Adding Resource Type: ' + $LogResName + '. Count: ' + $LogResCount)
      if ($loop -eq 1) {
        $ResourceTemp = ($ResourcesType.Name + ' (' + $ResourcesType.'Count' + ')')
        ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 6 }).Table.Columns(1).Width = 685
        ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 6 }).Table.Rows(1).Cells(1).Shape.TextFrame.TextRange.Text = $ResourceTemp
        ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 6 }).Table.Rows(1).Height = 20
      }
      else {
        $ResourceTemp = ($ResourcesType.Name + ' (' + $ResourcesType.'Count' + ')')
        ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 6 }).Table.Rows.Add() | Out-Null
        ($SlideWorkloadSummary.Shapes | Where-Object { $_.Id -eq 6 }).Table.Rows($loop).Cells(1).Shape.TextFrame.TextRange.Text = $ResourceTemp
      }
      $loop ++
    }
  }

  ############# Slide 16
  function Build-PPTSlide16 {
    Param($Presentation,$AUTOMESSAGE,$ImpactedResources)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 16 - Health and Risk Dashboard..')

    $SlideHealthAndRisk = $Presentation.Slides | Where-Object { $_.SlideIndex -eq 16 }

    $TargetShape = ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 41 })
    $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

    $ServiceHighImpact = $ImpactedResources | Where-Object { $_.Impact -eq 'High' -and $_.Category -eq 'Azure Service' } | Group-Object -Property 'Recommendation Title' | Sort-Object -Property "Count" -Descending
    $WAFHighImpact = $ImpactedResources | Where-Object { $_.Impact -eq 'High' -and $_.Category -eq 'Well Architected' } | Group-Object -Property 'Recommendation Title' | Sort-Object -Property "Count" -Descending

    $count = 1
    foreach ($Impact in $ServiceHighImpact) {
      $LogImpactName = $Impact.Name
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 16 - Adding Service High Impact Name: ' + $LogImpactName)
      if ($count -lt 5) {
          ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($count).text = $Impact.Name
        $count ++
      }
    }

    while (($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs().count -gt 5) {
      ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(6).Delete()
    }

    if ($WAFHighImpact.count -ne 0) {
      $count = 1
      foreach ($Impact in $WAFHighImpact) {
        $LogWAFImpactName = $Impact.Name
        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 16 - Adding WAF High Impact: ' + $LogWAFImpactName)
        if ($count -lt 5) {
          ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 12 }).TextFrame.TextRange.Paragraphs($count).text = $Impact.Name
          $count ++
        }
      }
    }
    else {
      ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 12 }).TextFrame.TextRange.Text = ' '
    }

    while (($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 12 }).TextFrame.TextRange.Paragraphs().count -gt 5) {
      ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 12 }).TextFrame.TextRange.Paragraphs(6).Delete()
    }

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 16 - Adding general values...')
    #Total Recomendations
    ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 44 }).GroupItems[3].TextFrame.TextRange.Text = [string]($ImpactedResources | Select-Object -Property Guid -Unique).count
    #High Impact
    ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 44 }).GroupItems[4].TextFrame.TextRange.Text = [string]($ImpactedResources | Where-Object { $_.Impact -eq 'High' } | Select-Object -Property Guid -Unique).count
    #Medium Impact
    ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 44 }).GroupItems[5].TextFrame.TextRange.Text = [string]($ImpactedResources | Where-Object { $_.Impact -eq 'Medium' } | Select-Object -Property Guid -Unique).count
    #Low Impact
    ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 44 }).GroupItems[6].TextFrame.TextRange.Text = [string]($ImpactedResources | Where-Object { $_.Impact -eq 'Low' } | Select-Object -Property Guid -Unique).count
    #Impacted Resources
    ($SlideHealthAndRisk.Shapes | Where-Object { $_.Id -eq 44 }).GroupItems[7].TextFrame.TextRange.Text = [string]($ImpactedResources | Select-Object -Property id -Unique).count
  }

  ############# Slide 23
  function Build-PPTSlide23 {
    Param($Presentation,$AUTOMESSAGE,$ImpactedResources)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 23 - High Impact Issues..')

    $HighImpact = $ImpactedResources | Where-Object { $_.Impact -eq 'High' } | Group-Object -Property 'Recommendation Title','Resource Type' | Sort-Object -Property "Count" -Descending

    $FirstSlide = 23
    $TableID = 6
    $CurrentSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }
    $CoreSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }

    $TargetShape = ($CurrentSlide.Shapes | Where-Object { $_.Id -eq 41 })
    $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 23 - Cleaning Table..')
    $row = 2
    while ($row -lt 6) {
      $cell = 1
      while ($cell -lt 5) {
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells($cell).Shape.TextFrame.TextRange.Text = ''
        $Cell ++
      }
      $row ++
    }

    $Counter = 1
    $RecomNumber = 1
    $row = 2
    foreach ($Impact in $HighImpact) {
      $LogHighImpact = $Impact.Values[0]
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 23 - Adding High Impact: ' + $LogHighImpact )
      if ($Counter -lt 14) {
        #Number
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(1).Shape.TextFrame.TextRange.Text = [string]$RecomNumber
        #Recommendation
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(2).Shape.TextFrame.TextRange.Text = $Impact.Values[0]
        #Service
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(3).Shape.TextFrame.TextRange.Text = $Impact.Values[1]
        #Impacted Resources
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(4).Shape.TextFrame.TextRange.Text = [string]$Impact.'Count'
        $counter ++
        $RecomNumber ++
        $row ++
      }
      else {
        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 23 - Adding new Slide..')
        $Counter = 1
        $CustomLayout = $CurrentSlide.CustomLayout
        $FirstSlide ++
        $Presentation.Slides.addSlide($FirstSlide, $customLayout) | Out-Null

        $NextSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }
        ($CoreSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Copy()
        Start-Sleep -Milliseconds 100
        ($NextSlide.Shapes | Where-Object { $_.Id -eq 2 }).TextFrame.TextRange.Paste() | Out-Null
        Start-Sleep -Milliseconds 100
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Copy()
        Start-Sleep -Milliseconds 100
        $NextSlide.Shapes.Paste() | Out-Null
        Start-Sleep -Milliseconds 100
        $TableID = 3
        ($CoreSlide.Shapes | Where-Object { $_.Id -eq 41 }).Copy()
        Start-Sleep -Milliseconds 100
        $NextSlide.Shapes.Paste() | Out-Null
        Start-Sleep -Milliseconds 100

        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 23 - Cleaning table of new slide..')
        $rowTemp = 2
        while ($rowTemp -lt 15) {
          $cell = 1
          while ($cell -lt 5) {
            ($NextSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($rowTemp).Cells($cell).Shape.TextFrame.TextRange.Text = ''
            $Cell ++
          }
          $rowTemp ++
        }

        $CurrentSlide = $NextSlide

        $row = 2
        #Number
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(1).Shape.TextFrame.TextRange.Text = [string]$RecomNumber
        #Recommendation
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(2).Shape.TextFrame.TextRange.Text = $Impact.Values[0]
        #Service
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(3).Shape.TextFrame.TextRange.Text = $Impact.Values[1]
        #Impacted Resources
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(4).Shape.TextFrame.TextRange.Text = [string]$Impact.'Count'
        $Counter ++
        $RecomNumber ++
        $row ++
      }
    }

  }

  ############# Slide 24
  function Build-PPTSlide24 {
    Param($Presentation,$AUTOMESSAGE,$ImpactedResources)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 24 - Medium Impact Issues..')

    $MediumImpact = $ImpactedResources | Where-Object { $_.Impact -eq 'Medium' } | Group-Object -Property 'Recommendation Title','Resource Type' | Sort-Object -Property "Count" -Descending

    $FirstSlide = 24
    $TableID = 6
    $CurrentSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }
    $CoreSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }

    $TargetShape = ($CurrentSlide.Shapes | Where-Object { $_.Id -eq 41 })
    $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 24 - Cleaning Table..')
    $row = 2
    while ($row -lt 6) {
      $cell = 1
      while ($cell -lt 5) {
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells($cell).Shape.TextFrame.TextRange.Text = ''
        $Cell ++
      }
      $row ++
    }

    $Counter = 1
    $RecomNumber = 1
    $row = 2
    foreach ($Impact in $MediumImpact) {
      $LogMediumImpact = $Impact.Values[0]
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 24 - Adding Medium Impact: ' + $LogMediumImpact)
      if ($Counter -lt 14) {
        #Number
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(1).Shape.TextFrame.TextRange.Text = [string]$RecomNumber
        #Recommendation
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(2).Shape.TextFrame.TextRange.Text = $Impact.Values[0]
        #Service
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(3).Shape.TextFrame.TextRange.Text = $Impact.Values[1]
        #Impacted Resources
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(4).Shape.TextFrame.TextRange.Text = [string]$Impact.'Count'
        $counter ++
        $RecomNumber ++
        $row ++
      }
      else {
        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 24 - Creating new slide..')
        $Counter = 1
        $CustomLayout = $CurrentSlide.CustomLayout
        $FirstSlide ++
        $Presentation.Slides.addSlide($FirstSlide, $customLayout) | Out-Null

        $NextSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }
        ($CoreSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Copy()
        Start-Sleep -Milliseconds 100
        ($NextSlide.Shapes | Where-Object { $_.Id -eq 2 }).TextFrame.TextRange.Paste() | Out-Null
        Start-Sleep -Milliseconds 100
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Copy()
        Start-Sleep -Milliseconds 100
        $NextSlide.Shapes.Paste() | Out-Null
        Start-Sleep -Milliseconds 100
        $TableID = 3
        ($CoreSlide.Shapes | Where-Object { $_.Id -eq 41 }).Copy()
        Start-Sleep -Milliseconds 100
        $NextSlide.Shapes.Paste() | Out-Null
        Start-Sleep -Milliseconds 100

        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 24 - Cleaning Table of new slide..')
        $rowTemp = 2
        while ($rowTemp -lt 15) {
          $cell = 1
          while ($cell -lt 5) {
            ($NextSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($rowTemp).Cells($cell).Shape.TextFrame.TextRange.Text = ''
            $Cell ++
          }
          $rowTemp ++
        }

        $CurrentSlide = $NextSlide

        $row = 2
        #Number
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(1).Shape.TextFrame.TextRange.Text = [string]$RecomNumber
        #Recommendation
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(2).Shape.TextFrame.TextRange.Text = $Impact.Values[0]
        #Service
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(3).Shape.TextFrame.TextRange.Text = $Impact.Values[1]
        #Impacted Resources
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(4).Shape.TextFrame.TextRange.Text = [string]$Impact.'Count'
        $Counter ++
        $RecomNumber ++
        $row ++
      }
    }

  }

  ############# Slide 25
  function Build-PPTSlide25 {
    Param($Presentation,$AUTOMESSAGE,$ImpactedResources)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 25 - Low Impact Issues..')

    $LowImpact = $ImpactedResources | Where-Object { $_.Impact -eq 'Low' } | Group-Object -Property 'Recommendation Title','Resource Type' | Sort-Object -Property "Count" -Descending

    $FirstSlide = 25
    $TableID = 6
    $CurrentSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }
    $CoreSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }

    $TargetShape = ($CurrentSlide.Shapes | Where-Object { $_.Id -eq 41 })
    $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 25 - Cleaning Table..')
    $row = 2
    while ($row -lt 6) {
      $cell = 1
      while ($cell -lt 5) {
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells($cell).Shape.TextFrame.TextRange.Text = ''
        $Cell ++
      }
      $row ++
    }

    $Counter = 1
    $RecomNumber = 1
    $row = 2
    foreach ($Impact in $LowImpact) {
      $LogLowImpact = $Impact.Values[0]
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 25 - Adding Low Impact: ' + $LogLowImpact)
      if ($Counter -lt 14) {
        #Number
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(1).Shape.TextFrame.TextRange.Text = [string]$RecomNumber
        #Recommendation
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(2).Shape.TextFrame.TextRange.Text = $Impact.Values[0]
        #Service
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(3).Shape.TextFrame.TextRange.Text = $Impact.Values[1]
        #Impacted Resources
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(4).Shape.TextFrame.TextRange.Text = [string]$Impact.'Count'
        $counter ++
        $RecomNumber ++
        $row ++
      }
      else {
        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 25 - Creating new Slide..')
        $Counter = 1
        $CustomLayout = $CurrentSlide.CustomLayout
        $FirstSlide ++
        $Presentation.Slides.addSlide($FirstSlide, $customLayout) | Out-Null

        $NextSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $FirstSlide }
        ($CoreSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Copy()
        Start-Sleep -Milliseconds 100
        ($NextSlide.Shapes | Where-Object { $_.Id -eq 2 }).TextFrame.TextRange.Paste() | Out-Null
        Start-Sleep -Milliseconds 100
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Copy()
        Start-Sleep -Milliseconds 100
        $NextSlide.Shapes.Paste() | Out-Null
        Start-Sleep -Milliseconds 100
        $TableID = 3
        ($CoreSlide.Shapes | Where-Object { $_.Id -eq 41 }).Copy()
        Start-Sleep -Milliseconds 100
        $NextSlide.Shapes.Paste() | Out-Null
        Start-Sleep -Milliseconds 100

        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 25 - Cleaning Table of new slide..')
        $rowTemp = 2
        while ($rowTemp -lt 15) {
          $cell = 1
          while ($cell -lt 5) {
            ($NextSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($rowTemp).Cells($cell).Shape.TextFrame.TextRange.Text = ''
            $Cell ++
          }
          $rowTemp ++
        }

        $CurrentSlide = $NextSlide

        $row = 2
        #Number
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(1).Shape.TextFrame.TextRange.Text = [string]$RecomNumber
        #Recommendation
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(2).Shape.TextFrame.TextRange.Text = $Impact.Values[0]
        #Service
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(3).Shape.TextFrame.TextRange.Text = $Impact.Values[1]
        #Impacted Resources
        ($CurrentSlide.Shapes | Where-Object { $_.Id -eq $TableID }).Table.Rows($row).Cells(4).Shape.TextFrame.TextRange.Text = [string]$Impact.'Count'
        $Counter ++
        $RecomNumber ++
        $row ++
      }
    }

  }

  ############# Slide 28
  function Build-PPTSlide28 {
    Param($Presentation,$AUTOMESSAGE,$PlatformIssues)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 28 - Recent Microsoft Outages..')

    $Loop = 1
    $CurrentSlide = 28

    if (![string]::IsNullOrEmpty($PlatformIssues)) {
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 28 - Outages found..')
      foreach ($Outage in $PlatformIssues) {
        if ($Loop -eq 1) {
          $OutageName = ($Outage.'Tracking ID' + ' - ' + $Outage.title)
          Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 28 - Adding Outage: ' + $OutageName)

          $OutageService = $Outage.'Impacted Service'

          $SlidePlatformIssues = $Presentation.Slides | Where-Object { $_.SlideIndex -eq 28 }

          $TargetShape = ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 4 })
          $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(1).Text = $OutageName
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(2).Text = "What happened:"
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(3).Text = $Outage.'What happened'
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(2).Copy()
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(4).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(4).Text = "Impacted Service:"
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(3).Copy()
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(5).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(5).Text = $OutageService
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(4).Copy()
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(6).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(6).Text = "How can customers make incidents like this less impactful:"
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(5).Copy()
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(7).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(7).Text = $Outage.'How can customers make incidents like this less impactful'

          while (($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs().count -gt 7) {
            ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(8).Delete()
          }
        }
        else {
          Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 28 - Creating new Slide..')
          ############### NEXT 9 SLIDES

          $OutageName = ($Outage.'Tracking ID' + ' - ' + $Outage.title)
          Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 28 - Adding Outage: ' + $OutageName)

          $OutageService = $Outage.'Impacted Service'
          $CustomLayout = $SlidePlatformIssues.CustomLayout
          $Presentation.Slides.addSlide($CurrentSlide, $customLayout) | Out-Null

          $NextSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $CurrentSlide }

          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 6 }).TextFrame.TextRange.Copy()
          Start-Sleep -Milliseconds 100

          ($NextSlide.Shapes | Where-Object { $_.Id -eq 2 }).TextFrame.TextRange.Paste() | Out-Null
          Start-Sleep -Milliseconds 100

          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 4 }).Copy()
          Start-Sleep -Milliseconds 100

          $NextSlide.Shapes.Paste() | Out-Null
          Start-Sleep -Milliseconds 100

          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 7 }).Copy()
          Start-Sleep -Milliseconds 100

          $NextSlide.Shapes.Paste() | Out-Null
          Start-Sleep -Milliseconds 100

          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(1).Text = $OutageName
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(2).Text = "What happened:"
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(3).Text = $Outage.'What happened'
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(2).Copy()
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(4).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(4).Text = "Impacted Service:"
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(3).Copy()
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(5).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(5).Text = $OutageService
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(4).Copy()
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(6).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(6).Text = "How can customers make incidents like this less impactful:"
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(5).Copy()
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(7).Paste() | Out-Null
          Start-Sleep -Milliseconds 100
          ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(7).Text = $Outage.'How can customers make incidents like this less impactful'

          ($SlidePlatformIssues.Shapes | Where-Object { $_.Id -eq 31 }).Copy()

          $NextSlide.Shapes.Paste() | Out-Null

          while (($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs().count -gt 7) {
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 4 }).TextFrame.TextRange.Paragraphs(8).Delete()
          }
        }
        $Loop ++
        $CurrentSlide ++
      }
    }
  }

  ############# Slide 29
  function Build-PPTSlide29 {
    Param($Presentation,$AUTOMESSAGE,$SupportTickets)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 29 - Sev-A Support Requests..')

    $Loop = 1
    $CurrentSlide = 29
    $Slide = 1

    if (![string]::IsNullOrEmpty($SupportTickets)) {
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 29 - Support Tickets found..')
      foreach ($Tickets in $SupportTickets) {
        $TicketName = ($Tickets.'Ticket ID' + ' - ' + $Tickets.Title)
        Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 29 - Adding Ticket: ' + $TicketName)
        $TicketStatus = $Tickets.'Status'
        $TicketDate = $Tickets.'Creation Date'

        if ($Slide -eq 1) {
          if ($Loop -eq 1) {
            $SlideSupportRequests = $Presentation.Slides | Where-Object { $_.SlideIndex -eq 29 }
            $TargetShape = ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 4 })
            $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE

            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(1).Text = $TicketName
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(2).Text = "Status: $TicketStatus"
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(3).Text = "Creation Date: $TicketDate"
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(3).Copy()
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(4).Paste() | Out-Null
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(4).Text = "Recommendation: "

            while (($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs().count -gt 4) {
              ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(5).Delete()
            }
            $ParagraphLoop = 5
            $Loop ++
          }
          else {
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(1).Copy()
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = $TicketName
            $ParagraphLoop ++
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(2).Copy()
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = "Status: $TicketStatus"
            $ParagraphLoop ++
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(3).Copy()
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = "Creation Date: $TicketDate"
            $ParagraphLoop ++
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(4).Copy()
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = "Recommendation: "
            $ParagraphLoop ++

            if ($Loop -eq 4) {
              $Loop = 1
              $Slide ++
              $CurrentSlide ++
            }
            else {
              $Loop ++
            }
            Start-Sleep -Milliseconds 500
          }
        }
        else {
          if ($Loop -eq 1) {
            Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 29 - Adding new Slide..')
            $CustomLayout = $SlideSupportRequests.CustomLayout
            $Presentation.Slides.addSlide($CurrentSlide, $customLayout) | Out-Null

            $NextSlide = $Presentation.Slides | Where-Object { $_.SlideIndex -eq $CurrentSlide }

            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 6 }).TextFrame.TextRange.Copy()
            Start-Sleep -Milliseconds 200

            ($NextSlide.Shapes | Where-Object { $_.Id -eq 2 }).TextFrame.TextRange.Paste() | Out-Null
            Start-Sleep -Milliseconds 100

            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 4 }).Copy()
            Start-Sleep -Milliseconds 200

            $NextSlide.Shapes.Paste() | Out-Null
            Start-Sleep -Milliseconds 100

            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 2 }).Copy()
            Start-Sleep -Milliseconds 200

            $NextSlide.Shapes.Paste() | Out-Null
            Start-Sleep -Milliseconds 100

            ($SlideSupportRequests.Shapes | Where-Object { $_.Id -eq 7 }).Copy()
            Start-Sleep -Milliseconds 200

            $NextSlide.Shapes.Paste() | Out-Null
            Start-Sleep -Milliseconds 100

            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(1).Text = $TicketName
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(2).Text = "Status: $TicketStatus"
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(3).Text = "Creation Date: $TicketDate"
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(4).Text = "Recommendation: "

            while (($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs().count -gt 4) {
              ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(5).Delete()
            }
            $ParagraphLoop = 5
            $Loop ++
          }
          else {
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(1).Copy()
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = $TicketName
            $ParagraphLoop ++
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(2).Copy()
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = "Status: $TicketStatus"
            $ParagraphLoop ++
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(3).Copy()
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = "Creation Date: $TicketDate"
            $ParagraphLoop ++
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs(4).Copy()
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($NextSlide.Shapes | Where-Object { $_.Id -eq 9 }).TextFrame.TextRange.Paragraphs($ParagraphLoop).Text = "Recommendation: "
            $ParagraphLoop ++

            if ($Loop -eq 4) {
              $Loop = 1
              $Slide ++
              $CurrentSlide ++
            }
            else {
              $Loop ++
            }
          }
        }
        Start-Sleep -Milliseconds 500
      }
    }
  }

  ############# Slide 30
  function Build-PPTSlide30 {
    Param($Presentation,$AUTOMESSAGE,$Retirements)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 30 - Service Retirement Notifications..')

    $Loop = 1

    if (![string]::IsNullOrEmpty($Retirements)) {
      Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 30 - Service Retirement found..')
      $SlideRetirements = $Presentation.Slides | Where-Object { $_.SlideIndex -eq 30 }

      $TargetShape = ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 4 })
      $TargetShape.TextFrame.TextRange.Text = $AUTOMESSAGE
      #$TargetShape.Delete()

      ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(1).Text = '.'

      while (($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs().count -gt 2) {
        ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(2).Delete()
      }

      foreach ($Retirement in $Retirements) {

        if ($Loop -lt 15) {
          if ($Loop -eq 1) {
            $RetireName = ($Retirement.'Retirement TrackingId' + ' - ' + $Retirement.'Recommendation Title')
            Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Editing Slide 30 - Adding Retirement: ' + $RetireName)

            ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(1).Text = $RetireName
            $Loop ++
          }
          else {
            $RetireName = ($Retirement.'Retirement TrackingId' + ' : ' + $Retirement.'Recommendation Title')

            ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.InsertAfter(".") | Out-Null
            Start-Sleep -Milliseconds 100
            ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs(1).Copy()
            Start-Sleep -Milliseconds 100
            ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($Loop).Paste() | Out-Null
            Start-Sleep -Milliseconds 100
            ($SlideRetirements.Shapes | Where-Object { $_.Id -eq 7 }).TextFrame.TextRange.Paragraphs($Loop).Text = $RetireName
            $Loop ++
          }
        }
      }
    }
  }

  ######################## Assessment Findings Functions ##########################

  function Initialize-ExcelImpactedResources {
    Param($ImpactedResources)

    $ImpactedResourcesFormatted = @()

    ForEach ($Resource in $ImpactedResources) {
      $obj = @{
        'Impacted?' = 'Yes';
        'Resource Type' = $Resource.'Resource Type';
        'subscriptionId' = $Resource.subscriptionId;
        'resourceGroup' = $Resource.resourceGroup;
        'location' = $Resource.location;
        'name' = $Resource.name;
        'id' = $Resource.id;
        'custom1' = $Resource.custom1;
        'custom2' = $Resource.custom2;
        'custom3' = $Resource.custom3;
        'custom4' = $Resource.custom4;
        'custom5' = $Resource.custom5;
        'Recommendation Title' = $Resource.'Recommendation Title';
        'Impact' = $Resource.Impact;
        'Recommendation Control' = $Resource.'Recommendation Control';
        'Potential Benefit' = $Resource.'Potential Benefit';
        'Learn More Link' = $Resource.'Learn More Link';
        'Long Description' = $Resource.'Long Description';
        'Guid' = $Resource.Guid;
        'Category' = $Resource.Category;
        'Source' = $Resource.'Source';
        'WAF Pillar' = $Resource.'WAF Pillar';
        'Platform Issue TrackingId' = $Resource.'Platform Issue TrackingId';
        'Retirement TrackingId' = $Resource.'Retirement TrackingId';
        'Support Request Number' = $Resource.'Support Request Number';
        'Notes' = $Resource.Notes;
        'checkName' = $Resource.checkName
      }
      $ImpactedResourcesFormatted += $obj
    }

    # Returns the array with all the recommendations already formatted to be exported to Excel
    return $ImpactedResourcesFormatted

  }

  function Export-ExcelImpactedResources {
    Param($ImpactedResourcesFormatted)

    $Style = @()
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range A:F
    $Style += New-ExcelStyle -HorizontalAlignment Left -Range G:G
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range G12:G12
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range H:L
    $Style += New-ExcelStyle -HorizontalAlignment Center -WrapText -Range M:M
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range N:N
    $Style += New-ExcelStyle -HorizontalAlignment Center -WrapText -Range O:O
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range P:Q
    $Style += New-ExcelStyle -HorizontalAlignment Center -WrapText -Range R:R
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range S:AA

    $ImpactedResourcesSheet = New-Object System.Collections.Generic.List[System.Object]
    $ImpactedResourcesSheet.Add('Impacted?')
    $ImpactedResourcesSheet.Add('Resource Type')
    $ImpactedResourcesSheet.Add('subscriptionId')
    $ImpactedResourcesSheet.Add('resourceGroup')
    $ImpactedResourcesSheet.Add('location')
    $ImpactedResourcesSheet.Add('name')
    $ImpactedResourcesSheet.Add('id')
    $ImpactedResourcesSheet.Add('custom1')
    $ImpactedResourcesSheet.Add('custom2')
    $ImpactedResourcesSheet.Add('custom3')
    $ImpactedResourcesSheet.Add('custom4')
    $ImpactedResourcesSheet.Add('custom5')
    $ImpactedResourcesSheet.Add('Recommendation Title')
    $ImpactedResourcesSheet.Add('Impact')
    $ImpactedResourcesSheet.Add('Recommendation Control')
    $ImpactedResourcesSheet.Add('Potential Benefit')
    $ImpactedResourcesSheet.Add('Learn More Link')
    $ImpactedResourcesSheet.Add('Long Description')
    $ImpactedResourcesSheet.Add('Guid')
    $ImpactedResourcesSheet.Add('Category')
    $ImpactedResourcesSheet.Add('Source')
    $ImpactedResourcesSheet.Add('WAF Pillar')
    $ImpactedResourcesSheet.Add('Platform Issue TrackingId')
    $ImpactedResourcesSheet.Add('Retirement TrackingId')
    $ImpactedResourcesSheet.Add('Support Request Number')
    $ImpactedResourcesSheet.Add('Notes')
    $ImpactedResourcesSheet.Add('checkName')

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Exporting Impacted Resources to Excel')
    $ImpactedResourcesFormatted | ForEach-Object { [PSCustomObject]$_ } | Select-Object $ImpactedResourcesSheet |
      Export-Excel -Path $NewAssessmentFindingsFile -WorksheetName '3.ImpactedResources' -TableName 'impactedresources' -TableStyle $TableStyle -Style $Style -StartRow 12

  }

  function Initialize-ExcelRecommendations {
    Param($ImpactedResources)

    $RecommendationsFormatted = @()

    $GroupedResources = $ImpactedResources | Group-Object -Property 'Guid' | Sort-Object -Property 'Count' -Descending

    ForEach ($Resource in $GroupedResources) {

      $Recommendation = $ImpactedResources | Where-Object { $_.Guid -eq $Resource.Name } | Select-Object -First 1

      $obj = @{
        'Impact' = $Recommendation.Impact;
        'Description' = $Recommendation.'Recommendation Title';
        'Potential Benefit' = $Recommendation.'Potential Benefit';
        'Impacted Resources' = $Resource.Count;
        'Resource Type' = $Recommendation.'Resource Type';
        'Recommendation Control' = $Recommendation.'Recommendation Control';
        'Long Description' = $Recommendation.'Long Description';
        'Category' = $Recommendation.Category;
        'Learn More Link' = $Recommendation.'Learn More Link';
        'Guid' = $Recommendation.Guid;
        'Notes' = $Recommendation.Notes;
      }
      $RecommendationsFormatted += $obj
    }

    # Returns the array with all the recommendations already formatted to be exported to Excel
    return $RecommendationsFormatted

  }

  function Export-ExcelRecommendations {
    Param($RecommendationsFormatted)

    $Style = @()
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range A:A
    $Style += New-ExcelStyle -HorizontalAlignment Left -Range B:C
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range B11:C11
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range D:D
    $Style += New-ExcelStyle -HorizontalAlignment Left -Range E:E
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range E11:E11
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range F:F
    $Style += New-ExcelStyle -HorizontalAlignment Left -WrapText -Range G:G
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range G11:G11
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range H:H
    $Style += New-ExcelStyle -HorizontalAlignment Left -Range I:I
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range I11:I11
    $Style += New-ExcelStyle -HorizontalAlignment Center -Range J:K
    $Style += New-ExcelStyle -Range A11:K11 -FontColor White

    $RecommendationSheet = New-Object System.Collections.Generic.List[System.Object]
    $RecommendationSheet.Add('Impact')
    $RecommendationSheet.Add('Description')
    $RecommendationSheet.Add('Potential Benefit')
    $RecommendationSheet.Add('Impacted Resources')
    $RecommendationSheet.Add('Resource Type')
    $RecommendationSheet.Add('Recommendation Control')
    $RecommendationSheet.Add('Long Description')
    $RecommendationSheet.Add('Category')
    $RecommendationSheet.Add('Learn More Link')
    $RecommendationSheet.Add('Guid')
    $RecommendationSheet.Add('Notes')

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Exporting Recommendations to Excel')
    $RecommendationsFormatted | ForEach-Object { [PSCustomObject]$_ } | Select-Object $RecommendationSheet |
      Export-Excel -Path $NewAssessmentFindingsFile -WorksheetName '2.Recommendations' -TableName 'recommendationT' -TableStyle $TableStyle -Style $Style -StartRow 11

  }

  function Export-ExcelWorkloadInventory {
    Param($ExcelWorkloadInventory)

    $Style = @()
    $Style += New-ExcelStyle -HorizontalAlignment Center

    $WorkloadSheet = New-Object System.Collections.Generic.List[System.Object]
    $WorkloadSheet.Add('id')
    $WorkloadSheet.Add('name')
    $WorkloadSheet.Add('type')
    $WorkloadSheet.Add('tenantId')
    $WorkloadSheet.Add('kind')
    $WorkloadSheet.Add('location')
    $WorkloadSheet.Add('resourceGroup')
    $WorkloadSheet.Add('subscriptionId')
    $WorkloadSheet.Add('managedBy')
    $WorkloadSheet.Add('sku')
    $WorkloadSheet.Add('plan')
    $WorkloadSheet.Add('zones')

    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Exporting Workload Inventory to Excel')
    $ExcelWorkloadInventory | ForEach-Object { [PSCustomObject]$_ } | Select-Object $WorkloadSheet |
      Export-Excel -Path $NewAssessmentFindingsFile -WorksheetName '6.WorkloadInventory' -TableName 'WorkloadResources' -TableStyle $TableStyle -Style $Style -StartRow 12

  }

  function Build-ExcelPivotTable {
    Param($NewAssessmentFindingsFile)

    # Open the Excel file to add the Pivot Tables and Charts
    $Excel = Open-ExcelPackage -Path $NewAssessmentFindingsFile

    $Address = $Excel.'2.Recommendations'.Tables[0].Address.Address

    $PTParams = @{
      PivotTableName    = 'P0'
      Address           = $Excel.'7.PivotTable'.cells['A3']
      SourceWorkSheet   = $Excel."2.Recommendations"
      SourceRange       = $Address
      PivotRows         = @('Resource Type')
      PivotColumns      = @('Impact')
      PivotData         = @{'Resource Type' = 'Count' }
      PivotTableStyle   = 'Medium9'
      Activate          = $true
      PivotFilter       = 'Category'
      ShowPercent       = $false
      IncludePivotChart = $false
    }
    Add-PivotTable @PTParams

    $PTParams = @{
      PivotTableName    = 'P1'
      Address           = $Excel.'7.PivotTable'.cells['H3']
      SourceWorkSheet   = $Excel."2.Recommendations"
      SourceRange       = $Address
      PivotRows         = @('Recommendation Control')
      PivotColumns      = @('Impact')
      PivotData         = @{'Resource Type' = 'Count' }
      PivotTableStyle   = 'Medium9'
      Activate          = $true
      PivotFilter       = 'Resource Type'
      ShowPercent       = $false
      IncludePivotChart = $false
    }
    Add-PivotTable @PTParams

    $PTParams = @{
      PivotTableName    = 'P2'
      Address           = $Excel.'7.PivotTable'.cells['O3']
      SourceWorkSheet   = $Excel."2.Recommendations"
      SourceRange       = $Address
      PivotRows         = @('Impact')
      PivotData         = @{'Impacted Resources' = 'Sum' }
      PivotTableStyle   = 'Medium9'
      Activate          = $true
      ShowPercent       = $false
      IncludePivotChart = $false
    }
    Add-PivotTable @PTParams

    $PTParams = @{
      PivotTableName    = 'P3'
      Address           = $Excel.'7.PivotTable'.cells['S3']
      SourceWorkSheet   = $Excel."2.Recommendations"
      SourceRange       = $Address
      PivotRows         = @('Impact')
      PivotData         = @{'Guid' = 'Count' }
      PivotTableStyle   = 'Medium10'
      Activate          = $true
      ShowPercent       = $false
      IncludePivotChart = $false
    }
    Add-PivotTable @PTParams

    Close-ExcelPackage $Excel

  }

  #Call the functions
  $Version = "2.1.5"
  Write-Host "Version: " -NoNewline
  Write-Host $Version -ForegroundColor DarkBlue -NoNewline
  Write-Host " "

  $CoreFile = get-item -Path $ExpertAnalysisFile
  $CoreFile = $CoreFile.FullName

  Test-ReviewedRecommendations -ExcelFile $CoreFile

  Write-Debug (' ---------------------------------- STARTING REPORT GENERATOR SCRIPT --------------------------------------- ')
  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting Report Generator Script..')
  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Script Version: ' + $Version)
  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Excel File: ' + $ExcelFile)
  $ImportExcel = Get-Module -Name ImportExcel -ListAvailable -ErrorAction silentlycontinue
  foreach ($IExcel in $ImportExcel) {
    $IExcelPath = $IExcel.Path
    $IExcelVer = [string]$IExcel.Version
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - ImportExcel Module Path: ' + $IExcelPath)
    Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - ImportExcel Module Version: ' + $IExcelVer)
  }

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "10% Complete." -PercentComplete 10
  Test-Requirement
  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "15% Complete." -PercentComplete 15
  #Set-LocalFile
  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "20% Complete." -PercentComplete 20

  $ExcelImpactedResources = Get-ExcelImpactedResources -ExcelFile $CoreFile

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "25% Complete." -PercentComplete 25

  $ExcelPlatformIssues = Get-ExcelPlatformIssues -ExcelFile $CoreFile

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "30% Complete." -PercentComplete 30

  $ExcelSupportTickets = Get-ExcelSupportTicket -ExcelFile $CoreFile

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "35% Complete." -PercentComplete 35

  $ExcelWorkloadInventory = Get-ExcelWorkloadInventory -ExcelFile $CoreFile

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "40% Complete." -PercentComplete 40

  $ExcelRetirements = Get-ExcelRetirement -ExcelFile $CoreFile

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "45% Complete." -PercentComplete 45


  $PPTFinalFile = New-PPTFile -PPTTemplateFile $PPTTemplateFile
  Write-Host "PowerPoint" -ForegroundColor DarkRed -NoNewline
  Write-Host " and " -NoNewline
  Write-Host "Excel" -ForegroundColor DarkGreen -NoNewline
  Write-Host " "
  Write-Host "Editing " -NoNewline
  $NewAssessmentFindingsFile = New-AssessmentFindingsFile -AssessmentFindingsFile $AssessmentFindingsFile


  $AUTOMESSAGE = 'AUTOMATICALLY MODIFIED (Please Review)'

  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Getting Resource Types..')

  $TempImpactedResources = $ExcelImpactedResources | Select-Object -Property 'Resource Type','id' -Unique

  $ResourcesTypes = $TempImpactedResources | Group-Object -Property 'Resource Type' | Sort-Object -Property 'Count' -Descending | Select-Object -First 10


  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting PowerPoint..')
  #Openning PPT
  $Application = New-Object -ComObject PowerPoint.Application
  $Presentation = $Application.Presentations.Open($PPTTemplateFile, $null, $null, $null)

  Remove-PPTSlide1 -Presentation $Presentation -CustomerName $CustomerName -WorkloadName $WorkloadName
  Build-PPTSlide12 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -WorkloadName $WorkloadName -ResourcesType $ResourcesTypes
  Build-PPTSlide16 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources

  Build-PPTSlide30 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -Retirements $ExcelRetirements
  Build-PPTSlide29 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -SupportTickets $ExcelSupportTickets
  Build-PPTSlide28 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -PlatformIssues $ExcelPlatformIssues

  Build-PPTSlide25 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
  Build-PPTSlide24 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
  Build-PPTSlide23 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources

  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Closing PowerPoint..')
  $Presentation.SaveAs($PPTFinalFile)
  $Presentation.Close()
  $Application.Quit()

  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting to Process Assessment Findings..')

  $ImpactedResourcesFormatted = Initialize-ExcelImpactedResources -ImpactedResources $ExcelImpactedResources
  Export-ExcelImpactedResources -ImpactedResourcesFormatted $ImpactedResourcesFormatted

  $RecommendationsFormatted = Initialize-ExcelRecommendations -ImpactedResources $ExcelImpactedResources
  Export-ExcelRecommendations -RecommendationsFormatted $RecommendationsFormatted

  Export-ExcelWorkloadInventory -ExcelWorkloadInventory $ExcelWorkloadInventory

  Build-ExcelPivotTable -NewAssessmentFindingsFile $NewAssessmentFindingsFile

  if($csvExport.IsPresent)
    {
      $WorkloadRecommendationTemplate = Build-SummaryActionPlan -ImpactedResources $ExcelImpactedResources -includeLow $includeLow

      $CSVFile = ($PSScriptRoot + '\Impacted Resources and Recommendations Template ' + (get-date -Format "yyyy-MM-dd-HH-mm") + '.csv')

      $WorkloadRecommendationTemplate | Export-Csv -Path $CSVFile
    }

  Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Trying to kill PowerPoint process.')
  Get-Process -Name "POWERPNT" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } | Stop-Process

  Write-Progress -Id 1 -activity "Processing Office Apps" -Status "90% Complete." -PercentComplete 90
}

Write-Progress -Id 1 -activity "Processing Office Apps" -Status "100% Complete." -Completed
$TotalTime = $Runtime.Totalminutes.ToString('#######.##')

################ Finishing

Write-Host "---------------------------------------------------------------------"
Write-Host ('Execution Complete. Total Runtime was: ') -NoNewline
Write-Host $TotalTime -NoNewline -ForegroundColor Cyan
Write-Host (' Minutes')
Write-Host 'PowerPoint File Saved as: ' -NoNewline
Write-Host $PPTFinalFile -ForegroundColor Cyan
Write-Host 'Assessment Findings File Saved as: ' -NoNewline
Write-Host $NewAssessmentFindingsFile -ForegroundColor Cyan

if ($csvExport.IsPresent)
  {
    Write-Host 'CSV File Saved as: ' -NoNewline
    Write-Host $CSVFile -ForegroundColor Cyan
  }

Write-Host "---------------------------------------------------------------------"