forked from ugurkocde/IntuneAssignmentChecker
-
Notifications
You must be signed in to change notification settings - Fork 0
288 lines (242 loc) · 11.3 KB
/
psscriptanalyzer.yml
File metadata and controls
288 lines (242 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
name: PSScriptAnalyzer
on:
push:
branches: [ main ]
paths:
- '**.ps1'
- '.github/workflows/psscriptanalyzer.yml'
pull_request:
branches: [ main ]
paths:
- '**.ps1'
- '.github/workflows/psscriptanalyzer.yml'
workflow_dispatch:
jobs:
analyze:
name: PSScriptAnalyzer
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install PSScriptAnalyzer
shell: pwsh
run: |
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
Write-Host "PSScriptAnalyzer version: $(Get-Module -Name PSScriptAnalyzer -ListAvailable | Select-Object -ExpandProperty Version)"
- name: Run PSScriptAnalyzer
id: analysis
shell: pwsh
run: |
# Initialize counters
$errorCount = 0
$warningCount = 0
$infoCount = 0
Write-Host "============================================"
Write-Host "Running PSScriptAnalyzer on IntuneAssignmentChecker.ps1"
Write-Host "============================================"
Write-Host ""
# Run the analysis
$results = Invoke-ScriptAnalyzer -Path ./IntuneAssignmentChecker.ps1 -Settings ./.PSScriptAnalyzerSettings.psd1 -RecurseCustomRulePath
if ($results) {
# Group by severity
$grouped = $results | Group-Object -Property Severity
# Count by severity
foreach ($group in $grouped) {
switch ($group.Name) {
'Error' { $errorCount = $group.Count }
'Warning' { $warningCount = $group.Count }
'Information' { $infoCount = $group.Count }
}
}
Write-Host "📊 Analysis Summary"
Write-Host "==================="
Write-Host "❌ Errors: $errorCount"
Write-Host "⚠️ Warnings: $warningCount"
Write-Host "ℹ️ Information: $infoCount"
Write-Host ""
# Display errors first
$errors = $results | Where-Object { $_.Severity -eq 'Error' }
if ($errors) {
Write-Host "❌ ERRORS" -ForegroundColor Red
Write-Host "========" -ForegroundColor Red
foreach ($err in $errors) {
Write-Host "Line $($err.Line): [$($err.RuleName)] $($err.Message)" -ForegroundColor Red
}
Write-Host ""
}
# Display warnings
$warnings = $results | Where-Object { $_.Severity -eq 'Warning' }
if ($warnings) {
Write-Host "⚠️ WARNINGS" -ForegroundColor Yellow
Write-Host "==========" -ForegroundColor Yellow
# Group warnings by rule for better readability
$warningGroups = $warnings | Group-Object -Property RuleName | Sort-Object Count -Descending
foreach ($group in $warningGroups) {
Write-Host ""
Write-Host " Rule: $($group.Name) (Count: $($group.Count))" -ForegroundColor Cyan
# Show first 5 examples of each warning type
$examples = $group.Group | Select-Object -First 5
foreach ($warning in $examples) {
Write-Host " Line $($warning.Line): $($warning.Message)" -ForegroundColor Yellow
}
if ($group.Count -gt 5) {
Write-Host " ... and $($group.Count - 5) more instances" -ForegroundColor DarkGray
}
}
Write-Host ""
}
# Display information
$info = $results | Where-Object { $_.Severity -eq 'Information' }
if ($info -and $env:SHOW_INFO -eq 'true') {
Write-Host "ℹ️ INFORMATION" -ForegroundColor Blue
Write-Host "=============" -ForegroundColor Blue
foreach ($item in $info) {
Write-Host "Line $($item.Line): [$($item.RuleName)] $($item.Message)" -ForegroundColor Blue
}
Write-Host ""
}
# Export results for artifact
$results | ConvertTo-Json -Depth 5 | Out-File -FilePath analysis-results.json
# Set outputs for later steps
echo "error_count=$errorCount" >> $env:GITHUB_OUTPUT
echo "warning_count=$warningCount" >> $env:GITHUB_OUTPUT
echo "info_count=$infoCount" >> $env:GITHUB_OUTPUT
echo "has_errors=$($errorCount -gt 0)" >> $env:GITHUB_OUTPUT
# Exit with error if errors found (configurable)
if ($errorCount -gt 0 -and $env:FAIL_ON_ERROR -eq 'true') {
Write-Host "❌ Analysis failed due to errors" -ForegroundColor Red
exit 1
}
} else {
Write-Host "✅ No issues found! The script passes all PSScriptAnalyzer rules." -ForegroundColor Green
echo "error_count=0" >> $env:GITHUB_OUTPUT
echo "warning_count=0" >> $env:GITHUB_OUTPUT
echo "info_count=0" >> $env:GITHUB_OUTPUT
echo "has_errors=false" >> $env:GITHUB_OUTPUT
}
env:
FAIL_ON_ERROR: false # Set to true if you want the workflow to fail on errors
SHOW_INFO: false # Set to true to show information level issues
- name: Generate Detailed Report
if: always()
shell: pwsh
run: |
# Generate a detailed markdown report
$reportContent = @"
# PSScriptAnalyzer Report
**Script:** IntuneAssignmentChecker.ps1
**Date:** $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')
**Analyzer Version:** $(Get-Module -Name PSScriptAnalyzer -ListAvailable | Select-Object -ExpandProperty Version)
## Summary
| Severity | Count |
|----------|-------|
| ❌ Errors | ${{ steps.analysis.outputs.error_count }} |
| ⚠️ Warnings | ${{ steps.analysis.outputs.warning_count }} |
| ℹ️ Information | ${{ steps.analysis.outputs.info_count }} |
"@
if (Test-Path analysis-results.json) {
$results = Get-Content analysis-results.json | ConvertFrom-Json
if ($results) {
# Add detailed findings grouped by rule
$reportContent += "`n## Detailed Findings by Rule`n`n"
$grouped = $results | Group-Object -Property RuleName, Severity
foreach ($group in ($grouped | Sort-Object { $_.Group[0].Severity }, Name)) {
$severity = $group.Group[0].Severity
$icon = switch ($severity) {
'Error' { '❌' }
'Warning' { '⚠️' }
'Information' { 'ℹ️' }
default { '❓' }
}
$reportContent += "### $icon $($group.Name -replace ',.*') ($($group.Count) instances)`n`n"
# Show up to 10 examples
$examples = $group.Group | Select-Object -First 10
$reportContent += "| Line | Message |`n|------|---------|`n"
foreach ($item in $examples) {
$message = $item.Message -replace '\|', '\|' -replace '\n', ' '
if ($message.Length -gt 100) {
$message = $message.Substring(0, 97) + "..."
}
$reportContent += "| $($item.Line) | $message |`n"
}
if ($group.Count -gt 10) {
$reportContent += "`n*... and $($group.Count - 10) more instances*`n"
}
$reportContent += "`n"
}
} else {
$reportContent += "`n## ✅ No Issues Found`n`nThe script passes all PSScriptAnalyzer rules!`n"
}
}
# Write report to file
$reportContent | Out-File -FilePath analysis-report.md
# Also output to job summary
$reportContent >> $env:GITHUB_STEP_SUMMARY
- name: Upload Analysis Results
if: always()
uses: actions/upload-artifact@v4
with:
name: psscriptanalyzer-results
path: |
analysis-results.json
analysis-report.md
retention-days: 30
- name: Comment PR (if applicable)
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const fs = require('fs');
// Read the report
let report = '## PSScriptAnalyzer Results\n\n';
const errorCount = '${{ steps.analysis.outputs.error_count }}';
const warningCount = '${{ steps.analysis.outputs.warning_count }}';
if (errorCount === '0' && warningCount === '0') {
report += '✅ **All checks passed!** No issues found.';
} else {
report += `Found **${errorCount}** error(s) and **${warningCount}** warning(s).\n\n`;
report += 'See the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.';
}
// Find and update or create comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('PSScriptAnalyzer Results')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: report
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: report
});
}
- name: Set Status Check
if: always()
shell: pwsh
run: |
$hasErrors = "${{ steps.analysis.outputs.has_errors }}"
$errorCount = "${{ steps.analysis.outputs.error_count }}"
$warningCount = "${{ steps.analysis.outputs.warning_count }}"
if ($hasErrors -eq 'true') {
Write-Host "❌ Status: Failed - Found $errorCount error(s)" -ForegroundColor Red
# Uncomment the next line to fail the workflow on errors
# exit 1
} elseif ($warningCount -gt 0) {
Write-Host "⚠️ Status: Passed with warnings - Found $warningCount warning(s)" -ForegroundColor Yellow
} else {
Write-Host "✅ Status: Passed - No issues found" -ForegroundColor Green
}