Skip to content

Commit 7c5c0e1

Browse files
authored
feat: Add better exception experience to Start-WARAReport (#180)
* Change ErrorActionPreference to Stop * Move parameter checks to after function definitions * Add function to make exception message * Wrap main script flow using try-catch * Remvoe exit statement after Write-Error * Wrap Office app part using try-finally * Change try/catch to trap * Respect old indent * Simplify parameter validation
1 parent 440b3b4 commit 7c5c0e1

1 file changed

Lines changed: 117 additions & 88 deletions

File tree

src/modules/wara/reports/3_wara_reports_generator.ps1

Lines changed: 117 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -34,77 +34,103 @@ https://github.com/Azure/Azure-Proactive-Resiliency-Library-v2
3434

3535
Param(
3636
[switch] $Help,
37+
3738
#[switch] $csvExport,
39+
3840
[switch] $includeLow,
39-
[string] $CustomerName,
40-
[string] $WorkloadName,
41-
[Parameter(mandatory = $true)]
41+
42+
[Parameter(Mandatory = $false)]
43+
[string] $CustomerName = '[Customer Name]',
44+
45+
[Parameter(Mandatory = $false)]
46+
[string] $WorkloadName = '[Workload Name]',
47+
48+
[Parameter(Mandatory = $true)]
4249
[Alias('ExcelFile')]
4350
[string] $ExpertAnalysisFile,
44-
[string] $AssessmentFindingsFile,
45-
[string] $PPTTemplateFile
51+
52+
[Parameter(Mandatory = $false)]
53+
[string] $AssessmentFindingsFile = (Join-Path -Path $PSScriptRoot -ChildPath 'Assessment-Findings-Report-v1.xlsx'),
54+
55+
[Parameter(Mandatory = $false)]
56+
[string] $PPTTemplateFile = (Join-Path -Path $PSScriptRoot -ChildPath 'Mandatory - Executive Summary presentation - Template.pptx')
4657
)
4758

48-
# Checking the operating system running this script.
49-
if (-not $IsWindows) {
50-
Write-Host 'This script only supports Windows operating systems currently. Please try to run with Windows operating systems.'
51-
Exit
52-
}
59+
$ErrorActionPreference = 'Stop'
60+
61+
trap {
62+
$ex = $_.Exception
63+
$horizontalLineLength = 40
64+
65+
$builder = New-Object -TypeName 'System.Text.StringBuilder'
66+
[void] $builder.AppendLine('')
67+
[void] $builder.AppendLine($ex.Message)
68+
[void] $builder.AppendLine('')
69+
70+
[void] $builder.AppendLine('*' * $horizontalLineLength)
71+
[void] $builder.AppendLine('Exception : ' + $ex.GetType().FullName)
72+
[void] $builder.AppendLine('FullyQualifiedErrorId : ' + $_.FullyQualifiedErrorId)
73+
[void] $builder.AppendLine('ErrorDetailsMessage : ' + $_.ErrorDetails.Message)
74+
[void] $builder.AppendLine('CategoryInfo : ' + $_.CategoryInfo.ToString())
75+
[void] $builder.AppendLine('StackTrace in PowerShell :')
76+
[void] $builder.AppendLine($_.ScriptStackTrace)
77+
78+
[void] $builder.AppendLine('')
79+
[void] $builder.AppendLine('---- Exception Details ----')
80+
[void] $builder.AppendLine('Exception : ' + $ex.GetType().FullName)
81+
[void] $builder.AppendLine('Message : ' + $ex.Message)
82+
[void] $builder.AppendLine('Source : ' + $ex.Source)
83+
[void] $builder.AppendLine('HResult : ' + $ex.HResult)
84+
[void] $builder.AppendLine('StackTrace :')
85+
[void] $builder.AppendLine($ex.StackTrace)
86+
87+
$depth = 1
88+
while ($ex.InnerException) {
89+
$ex = $ex.InnerException
90+
[void] $builder.AppendLine('')
91+
[void] $builder.AppendLine('---- Inner Exception Details {0} ----' -f $depth)
92+
[void] $builder.AppendLine('Exception : ' + $ex.GetType().FullName)
93+
[void] $builder.AppendLine('Message : ' + $ex.Message)
94+
[void] $builder.AppendLine('Source : ' + $ex.Source)
95+
[void] $builder.AppendLine('HResult : ' + $ex.HResult)
96+
[void] $builder.AppendLine('StackTrace :')
97+
[void] $builder.AppendLine($ex.StackTrace)
98+
$depth++
99+
}
53100

54-
# Check if Clipboard History is enabled
55-
$clipboardHistory = Get-ItemProperty -Path "HKCU:\Software\Microsoft\Clipboard" -Name "EnableClipboardHistory" -ErrorAction SilentlyContinue
101+
[void] $builder.AppendLine('*' * $horizontalLineLength)
102+
$builder.ToString() | Write-Host -ForegroundColor Yellow
56103

57-
if ($clipboardHistory.EnableClipboardHistory -eq 1) {
58-
Throw "Clipboard History is enabled. Please disable Clipboard History before running this script."
59-
} else {
60-
Write-Debug "Clipboard History is disabled."
104+
break
61105
}
62106

63-
# TODO: Remove if not needed
64-
<# $CurrentPath = Get-Location
65-
$CurrentPath = $CurrentPath.Path #>
66-
if ($PSBoundParameters.ContainsKey('PPTTemplateFile')) {
67-
# Resolve-Path throw exception if the path does not exist.
68-
$pptTemplateFilePath = (Resolve-Path -LiteralPath $PPTTemplateFile).Path
69-
if (-not (Test-Path -PathType Leaf -LiteralPath $pptTemplateFilePath)) {
70-
# The specified path is not a file, it may be a folder.
71-
Write-Error -Message ('The specified PowerPoint template file "{0}" is not a file. Please provide the path to the PowerPoint template file.' -f $pptTemplateFilePath)
72-
Exit # TODO: This can be deleted after adding exception handling.
73-
}
74-
}
75-
else {
76-
$pptTemplateFilePath = Join-Path -Path $PSScriptRoot -ChildPath 'Mandatory - Executive Summary presentation - Template.pptx'
77-
if (-not (Test-Path -PathType Leaf -LiteralPath $pptTemplateFilePath)) {
78-
Write-Error -Message ('The default PowerPoint template file "{0}" does not exist. Please contact the WARA team via GitHub or Microsoft Teams.' -f $pptTemplateFilePath) # TODO
79-
Exit # TODO: This can be deleted after adding exception handling.
80-
}
107+
# Checking the operating system running this script.
108+
if (-not $IsWindows) {
109+
throw 'This script only supports Windows operating systems currently. Please try to run with Windows operating systems.'
81110
}
82-
Write-Host ('PowerPoint Template File: {0}' -f $pptTemplateFilePath)
83111

84-
if (!$AssessmentFindingsFile) {
85-
write-host ("$PSScriptRoot/Assessment-Findings-Report-v1.xlsx")
86-
if ((Test-Path -Path ("$PSScriptRoot/Assessment-Findings-Report-v1.xlsx") -PathType Leaf) -eq $true) {
87-
$AssessmentFindingsFile = ("$PSScriptRoot/Assessment-Findings-Report-v1.xlsx")
88-
}
89-
else {
90-
Write-Error "Assessment Findings file is missing. Please provide the path to the Assessment Findings file."
91-
Exit
92-
}
93-
}
112+
# Check if Clipboard History is enabled
113+
$clipboardHistory = Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Clipboard' -Name 'EnableClipboardHistory' -ErrorAction SilentlyContinue
94114

95-
if (!$ExpertAnalysisFile) {
96-
Write-Host "The Expert-Analysis Excel file is missing. Please provide the path to the Expert-Analysis Excel file." -ForegroundColor Yellow
97-
Exit
115+
if ($clipboardHistory.EnableClipboardHistory -eq 1) {
116+
throw 'Clipboard History is enabled. Please disable Clipboard History before running this script. See more details at https://aka.ms/waratools/faq'
117+
} else {
118+
Write-Debug 'Clipboard History is disabled.'
98119
}
99120

100-
101-
if (!$CustomerName) {
102-
$CustomerName = '[Customer Name]'
121+
# Verify the PPTTemplateFile parameter
122+
$pptTemplateFilePath = (Resolve-Path -LiteralPath $PPTTemplateFile).Path
123+
if (-not (Test-Path -PathType Leaf -LiteralPath $pptTemplateFilePath)) {
124+
throw 'The specified PowerPoint template file "{0}" is not a file. Please provide the path to the PowerPoint template file.' -f $pptTemplateFilePath
103125
}
126+
Write-Host ('PowerPoint Template File: {0}' -f $pptTemplateFilePath)
104127

105-
if (!$WorkloadName) {
106-
$WorkloadName = '[Workload Name]'
128+
# Verify the AssessmentFindingsFile parameter
129+
$assessmentFindingsFilePath = (Resolve-Path -LiteralPath $AssessmentFindingsFile).Path
130+
if (-not (Test-Path -PathType Leaf -LiteralPath $assessmentFindingsFilePath)) {
131+
throw 'The specified Assessment Findings file "{0}" is not a file. Please provide the path to the Assessment Findings file.' -f $assessmentFindingsFilePath
107132
}
133+
Write-Host ('Assessment Findings File: {0}' -f $assessmentFindingsFilePath)
108134

109135
$TableStyle = 'Light19'
110136

@@ -1344,7 +1370,7 @@ Write-Host " and " -NoNewline
13441370
Write-Host "Excel" -ForegroundColor DarkGreen -NoNewline
13451371
Write-Host " "
13461372
Write-Host "Editing " -NoNewline
1347-
$NewAssessmentFindingsFile = New-AssessmentFindingsFile -AssessmentFindingsFile $AssessmentFindingsFile
1373+
$NewAssessmentFindingsFile = New-AssessmentFindingsFile -AssessmentFindingsFile $assessmentFindingsFilePath
13481374

13491375

13501376
$AUTOMESSAGE = 'AUTOMATICALLY MODIFIED (Please Review)'
@@ -1369,83 +1395,86 @@ $ExcelFileLive = Build-ExcelPivotTable -NewAssessmentFindingsFile $NewAssessment
13691395

13701396
Build-ExcelPivotChart -Excel $ExcelFileLive
13711397

1372-
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting PowerPoint..')
1373-
# Openning PPT
1374-
try
1398+
try {
1399+
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting PowerPoint..')
1400+
# Openning PPT
1401+
try
13751402
{
13761403
$Application = New-Object -ComObject PowerPoint.Application
13771404
$Presentation = $Application.Presentations.Open($pptTemplateFilePath, $null, $null, $null)
13781405
}
1379-
catch
1406+
catch
13801407
{
13811408
Write-Host ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + "- Error: " + $_.Exception.Message)
13821409
Get-Process -Name "POWERPNT" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } | Stop-Process -Force
13831410
}
13841411

1385-
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting Excel..')
1386-
# Openning Excel
1387-
try
1412+
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Starting Excel..')
1413+
# Openning Excel
1414+
try
13881415
{
13891416
$ExcelApplication = New-Object -ComObject Excel.Application
13901417
Start-Sleep -Milliseconds 500
13911418
$ExcelWorkbooks = $ExcelApplication.Workbooks.Open($NewAssessmentFindingsFile)
13921419
}
1393-
catch
1420+
catch
13941421
{
13951422
Write-Host ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + "- Error: " + $_.Exception.Message)
13961423
Get-Process -Name "excel" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } | Stop-Process -Force
13971424
}
13981425

13991426

1400-
Remove-PPTSlide1 -Presentation $Presentation -CustomerName $CustomerName -WorkloadName $WorkloadName
1401-
Build-PPTSlide12 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -WorkloadName $WorkloadName -ResourcesType $ResourcesTypes
1402-
Build-PPTSlide16 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
1427+
Remove-PPTSlide1 -Presentation $Presentation -CustomerName $CustomerName -WorkloadName $WorkloadName
1428+
Build-PPTSlide12 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -WorkloadName $WorkloadName -ResourcesType $ResourcesTypes
1429+
Build-PPTSlide16 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
14031430

1404-
while ([string]::IsNullOrEmpty($ExcelWorkbooks)) {
1405-
Start-Sleep 1
1406-
}
1431+
while ([string]::IsNullOrEmpty($ExcelWorkbooks)) {
1432+
Start-Sleep 1
1433+
}
14071434

1408-
Build-PPTSlide17 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ExcelWorkbooks $ExcelWorkbooks
1435+
Build-PPTSlide17 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ExcelWorkbooks $ExcelWorkbooks
14091436

1410-
Build-PPTSlide30 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -Retirements $ExcelRetirements
1437+
Build-PPTSlide30 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -Retirements $ExcelRetirements
14111438

1412-
Build-PPTSlide29 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -SupportTickets $ExcelSupportTickets
1439+
Build-PPTSlide29 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -SupportTickets $ExcelSupportTickets
14131440

1414-
Build-PPTSlide28 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -PlatformIssues $ExcelPlatformIssues
1441+
Build-PPTSlide28 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -PlatformIssues $ExcelPlatformIssues
14151442

1416-
Build-PPTSlide25 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
1417-
Build-PPTSlide24 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
1418-
Build-PPTSlide23 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
1443+
Build-PPTSlide25 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
1444+
Build-PPTSlide24 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
1445+
Build-PPTSlide23 -Presentation $Presentation -AUTOMESSAGE $AUTOMESSAGE -ImpactedResources $ExcelImpactedResources
14191446

1420-
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Closing Excel..')
1421-
$ExcelWorkbooks.Save()
1422-
$ExcelWorkbooks.Close()
1423-
$ExcelApplication.Quit()
1447+
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Closing Excel..')
1448+
$ExcelWorkbooks.Save()
1449+
$ExcelWorkbooks.Close()
1450+
$ExcelApplication.Quit()
14241451

1425-
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Closing PowerPoint..')
1426-
$Presentation.SaveAs($PPTFinalFile)
1427-
$Presentation.Close()
1428-
$Application.Quit()
1452+
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Closing PowerPoint..')
1453+
$Presentation.SaveAs($PPTFinalFile)
1454+
$Presentation.Close()
1455+
$Application.Quit()
14291456

1430-
#if ($csvExport.IsPresent) {
1457+
#if ($csvExport.IsPresent) {
14311458
$WorkloadRecommendationTemplate = Build-SummaryActionPlan -ImpactedResources $ExcelImpactedResources -includeLow $includeLow
14321459

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

14351462
$WorkloadRecommendationTemplate | Export-Csv -Path $CSVFile
1436-
#}
1437-
1438-
if (Get-Process -Name "POWERPNT" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' })
1463+
#}
1464+
}
1465+
finally {
1466+
if (Get-Process -Name "POWERPNT" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' })
14391467
{
14401468
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Trying to kill PowerPoint process.')
14411469
Get-Process -Name "POWERPNT" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } | Stop-Process -Force
14421470
}
14431471

1444-
if (Get-Process -Name "excel" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } )
1472+
if (Get-Process -Name "excel" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } )
14451473
{
14461474
Write-Debug ((get-date -Format 'yyyy-MM-dd HH:mm:ss') + ' - Trying to kill Excel process.')
14471475
Get-Process -Name "excel" -ErrorAction Ignore | Where-Object { $_.CommandLine -like '*/automation*' } | Stop-Process -Force
14481476
}
1477+
}
14491478

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

0 commit comments

Comments
 (0)