Skip to content

v1.0.5 public release#20

Merged
rebelinux merged 19 commits intomainfrom
dev
Apr 2, 2026
Merged

v1.0.5 public release#20
rebelinux merged 19 commits intomainfrom
dev

Conversation

@rebelinux
Copy link
Copy Markdown
Collaborator

[1.0.5] - 2026-03-24

🧰 Added

  • Add Format-HtmlCell cmdlet to the module to format HTML table cells with specified background color, text color, and font size
  • Add Set-ImageOpacity cmdlet to the module to set the opacity of an image file
  • Add new parameters to Add-NodeImage cmdlet to set image opacity for node images
  • Add WaterMark support to SVG output format
    • Use the DiaConvertImageToPDF c# net4.8 package to add watermark support to SVG output format

🔃 Changed

  • Update module version to v1.0.5
  • Update edge length validation range, and help message to reflect the new range of 0 to 50 in Add-NodeEdge function
  • Update Pester workflow to run tests and upload results with code coverage support
  • Optimize aspect ratio calculation in Get-BestImageAspectRatio function

🔧 Fixed

  • Fix pester tests failing in Windows Pwsh 5.1+

rebelinux and others added 19 commits March 19, 2026 12:09
…ration

- Add Add-HtmlTableCell private function that builds Graphviz HTML <TR><TD>
  markup from Hashtable, OrderedDictionary, PSCustomObject, or string array input
- Accept all formatting parameters: FontName, FontSize, FontColor, FontBold,
  FontItalic, FontUnderline, FontStrikeThrough, Align, ColSpan, CellPadding,
  CellBorder, CellBackgroundColor, Port, IconDebug/DraftMode
- Export Add-HtmlTableCell in module manifest (FunctionsToExport)
- Add 26 Pester tests covering all input types, formatting options, and
  composability with Format-HtmlTable
- Add Example18.ps1 demonstrating all four input type variations
- Add .github/copilot-instructions.md for future Copilot sessions
- Mark Todo.md items complete

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Created tests for Add-NodeSpacer, Add-NodeText, Add-RightLShapeLine, Add-RightTShapeLine, Add-TShapeLine, Add-VerticalLine, Export-AbrDiagram, Get-AbrNodeIP, Get-ImagePercent, Get-RandomColorInHex, Get-RandomPastelColorInHex, Remove-SpecialCharacter, Split-ArrayElement, Test-AbrImage, and Test-AbrLogo.
- Each test file includes BeforeAll setup to initialize necessary scripts and variables.
- Tests cover various scenarios including valid inputs, expected outputs, and error handling.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 2, 2026 23:45
Copy link
Copy Markdown

@github-advanced-security github-advanced-security AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PSScriptAnalyzer found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 2, 2026

PSScriptAnalyzer results:

Errors: [0], Warnings: [53], Information: [6]


RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 44
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 45
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 46
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 50
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 57
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 72
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 75
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 108
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 113
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 129
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 130
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 132
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 137
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 138
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 143
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 144
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 145
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 146
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 147
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 148
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 149
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 150
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 154
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 156
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 157
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 163
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 164
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 165
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 173
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 176
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 177
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 178
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 179
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 184
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 185
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 190
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 194
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 198
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Invoke-Tests.ps1
Line       : 201
Message    : File 'Invoke-Tests.ps1' uses Write-Host. Avoid using Write-Host 
             because it might not work in all hosts, does not work when there 
             is no host, and (prior to PS 5.0) cannot be suppressed, captured, 
             or redirected. Instead, use Write-Output, Write-Verbose, or 
             Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : _InitializeTests.ps1
Line       : 27
Message    : File '_InitializeTests.ps1' uses Write-Host. Avoid using 
             Write-Host because it might not work in all hosts, does not work 
             when there is no host, and (prior to PS 5.0) cannot be suppressed, 
             captured, or redirected. Instead, use Write-Output, Write-Verbose, 
             or Write-Information.

RuleName   : PSAvoidUsingInvokeExpression
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 780
Message    : Invoke-Expression is used. Please remove Invoke-Expression from 
             script and find other options instead.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 487
Message    : File 'Write-AbrPSObject.ps1' uses Write-Host. Avoid using 
             Write-Host because it might not work in all hosts, does not work 
             when there is no host, and (prior to PS 5.0) cannot be suppressed, 
             captured, or redirected. Instead, use Write-Output, Write-Verbose, 
             or Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 489
Message    : File 'Write-AbrPSObject.ps1' uses Write-Host. Avoid using 
             Write-Host because it might not work in all hosts, does not work 
             when there is no host, and (prior to PS 5.0) cannot be suppressed, 
             captured, or redirected. Instead, use Write-Output, Write-Verbose, 
             or Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 577
Message    : File 'Write-AbrPSObject.ps1' uses Write-Host. Avoid using 
             Write-Host because it might not work in all hosts, does not work 
             when there is no host, and (prior to PS 5.0) cannot be suppressed, 
             captured, or redirected. Instead, use Write-Output, Write-Verbose, 
             or Write-Information.

RuleName   : PSAvoidUsingWriteHost
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 861
Message    : File 'Write-AbrPSObject.ps1' uses Write-Host. Avoid using 
             Write-Host because it might not work in all hosts, does not work 
             when there is no host, and (prior to PS 5.0) cannot be suppressed, 
             captured, or redirected. Instead, use Write-Output, Write-Verbose, 
             or Write-Information.

RuleName   : PSPossibleIncorrectComparisonWithNull
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 616
Message    : $null should be on the left side of equality comparisons.

RuleName   : PSPossibleIncorrectComparisonWithNull
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 620
Message    : $null should be on the left side of equality comparisons.

RuleName   : PSUseBOMForUnicodeEncodedFile
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 
Message    : Missing BOM encoding for non-ASCII encoded file 
             'Write-AbrPSObject.ps1'

RuleName   : PSUseProcessBlockForPipelineCommand
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 431
Message    : Command accepts pipeline input but has not defined a process block.

RuleName   : PSUseProcessBlockForPipelineCommand
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 431
Message    : Command accepts pipeline input but has not defined a process block.

RuleName   : PSUseProcessBlockForPipelineCommand
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 476
Message    : Command accepts pipeline input but has not defined a process block.

RuleName   : PSUseProcessBlockForPipelineCommand
Severity   : Warning
ScriptName : Write-AbrPSObject.ps1
Line       : 476
Message    : Command accepts pipeline input but has not defined a process block.

RuleName   : PSUseBOMForUnicodeEncodedFile
Severity   : Warning
ScriptName : Add-TShapeLine.ps1
Line       : 
Message    : Missing BOM encoding for non-ASCII encoded file 
             'Add-TShapeLine.ps1'

RuleName   : PSUseOutputTypeCorrectly
Severity   : Information
ScriptName : Split-ArrayElement.ps1
Line       : 50
Message    : The cmdlet 'Split-ArrayElement' returns an object of type 
             'System.Object[]' but this type is not declared in the OutputType 
             attribute.

RuleName   : PSAvoidUsingPositionalParameters
Severity   : Information
ScriptName : Format-HtmlCell.ps1
Line       : 308
Message    : Cmdlet 'buildImgTD' has positional parameter. Please use named 
             parameters instead of positional parameters when calling a command.

RuleName   : PSAvoidUsingPositionalParameters
Severity   : Information
ScriptName : Format-HtmlCell.ps1
Line       : 318
Message    : Cmdlet 'buildTD' has positional parameter. Please use named 
             parameters instead of positional parameters when calling a command.

RuleName   : PSAvoidUsingPositionalParameters
Severity   : Information
ScriptName : Format-HtmlCell.ps1
Line       : 326
Message    : Cmdlet 'buildTD' has positional parameter. Please use named 
             parameters instead of positional parameters when calling a command.

RuleName   : PSAvoidUsingPositionalParameters
Severity   : Information
ScriptName : Format-HtmlCell.ps1
Line       : 334
Message    : Cmdlet 'buildTD' has positional parameter. Please use named 
             parameters instead of positional parameters when calling a command.

RuleName   : PSAvoidUsingPositionalParameters
Severity   : Information
ScriptName : Format-HtmlCell.ps1
Line       : 342
Message    : Cmdlet 'buildTD' has positional parameter. Please use named 
             parameters instead of positional parameters when calling a command.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR packages the v1.0.5 public release of AsBuiltReport.Diagram, adding new HTML-cell formatting capabilities, image opacity handling (via new C# cmdlets), SVG watermark support (net48 helper assembly), and significantly expanding the Pester test suite/CI runner.

Changes:

  • Added Format-HtmlCell and expanded node image handling to support per-icon opacity.
  • Introduced/updated C# cmdlets and image-processing helpers for opacity and SVG watermarking across net8/net48 assemblies.
  • Added a large set of Pester tests and updated the CI workflow to run tests via Tests/Invoke-Tests.ps1 and upload NUnit XML results.

Reviewed changes

Copilot reviewed 27 out of 60 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
Todo.md Marks completed items for HTML cell builder work.
CHANGELOG.md Adds v1.0.5 release notes.
.gitignore Stops ignoring VS Code launch config (tracks it in repo).
.github/workflows/Pester.yml Switches test execution to Tests/Invoke-Tests.ps1 and uploads NUnit XML artifacts.
.github/copilot-instructions.md Adds repo-specific Copilot/build/test conventions documentation.
.vscode/tasks.json Updates build/debug task names/paths for renamed csproj outputs.
.vscode/launch.json Adds VS Code launch configs for debugging cmdlet assemblies.
Tests/_InitializeTests.ps1 Updates Graphviz/assembly paths and adds Test-AbrBase64 helper.
Tests/Invoke-Tests.ps1 New test runner script (module installs + Pester config + optional coverage).
Tests/Export-AbrDiagram.Tests.ps1 Adjusts base64 assertion to validate base64 rather than exact string match.
Tests/Test-AbrLogo.Tests.ps1 Adds tests for logo validation/copy logic.
Tests/Test-AbrImage.Tests.ps1 Adds tests for image-extension validation.
Tests/Split-ArrayElement.Tests.ps1 Adds tests for array splitting helper.
Tests/Remove-SpecialCharacter.Tests.ps1 Adds tests for special-character stripping helper.
Tests/Get-RandomPastelColorInHex.Tests.ps1 Adds tests for random pastel hex output.
Tests/Get-RandomColorInHex.Tests.ps1 Adds tests for random hex output.
Tests/Get-ImagePercent.Tests.ps1 Adds tests for percent-based image sizing and validation errors.
Tests/Get-AbrNodeIP.Tests.ps1 Adds tests for hostname→IP resolution behavior.
Tests/Format-HtmlCell.Tests.ps1 Adds comprehensive tests for new Format-HtmlCell.
Tests/Add-VerticalLine.Tests.ps1 Adds tests for vertical-line graph helper.
Tests/Add-TShapeLine.Tests.ps1 Adds tests for T-shape graph helper.
Tests/Add-RightTShapeLine.Tests.ps1 Adds tests for right-T graph helper.
Tests/Add-RightLShapeLine.Tests.ps1 Adds tests for right-L graph helper.
Tests/Add-LShapeLine.Tests.ps1 Adds tests for L-shape graph helper.
Tests/Add-LeftTShapeLine.Tests.ps1 Adds tests for left-T graph helper.
Tests/Add-LeftLShapeLine.Tests.ps1 Adds tests for left-L graph helper.
Tests/Add-InvertedTShapeLine.Tests.ps1 Adds tests for inverted-T graph helper.
Tests/Add-InvertedLShapeLine.Tests.ps1 Adds tests for inverted-L graph helper.
Tests/Add-CrossShapeLine.Tests.ps1 Adds tests for cross-shape graph helper.
Tests/Add-HorizontalLine.Tests.ps1 Adds tests for horizontal-line graph helper.
Tests/Add-NodeText.Tests.ps1 Adds tests for node text HTML label generation.
Tests/Add-NodeSpacer.Tests.ps1 Adds tests for spacer/dummy node helper.
Tests/Add-NodeShape.Tests.ps1 Adds tests for node shape helper and GraphvizAttributes behavior.
Tests/Add-NodeImage.Tests.ps1 Extends tests for Add-NodeImage including opacity behavior.
Tests/Add-NodeIcon.Tests.ps1 Adds tests for icon+rows node helper and debug rendering.
Tests/Add-NodeEdge.Tests.ps1 Adds extensive tests for edge helper including HTML labels/head/tail labels.
Tests/Add-HtmlTable.Tests.ps1 Adds tests for HTML table helper (single/multi-column).
Tests/Add-HtmlSubGraph.Tests.ps1 Adds tests for HTML subgraph/table composition.
Tests/Add-HtmlSignatureTable.Tests.ps1 Adds tests for signature table helper.
Tests/Add-HtmlNodeTable.Tests.ps1 Adds tests for node-table builder incl. subgraph emulation.
Tests/Add-HtmlLabel.Tests.ps1 Adds tests for label rendering with/without icon and sizing modes.
Tests/Add-AbrWatermarkToImage.Tests.ps1 Adds tests for watermarking output and error cases.
Sources/Diagrammer/AbrDiagrammer.csproj Bumps assembly version and updates Newtonsoft.Json reference.
Sources/Diagrammer/ImageProcessor.cs Adds ImageSharp-based SetImageOpacity helper.
Sources/Diagrammer/PowershellCmdlets/SetImageOpacityPwsh.cs Adds Set-ImageOpacity cmdlet for net8 assembly.
Sources/DiaConvertImageToPDF/AbrDiaConvertImageToPDF.csproj Adds System.Drawing/System.Xml.Linq references.
Sources/DiaConvertImageToPDF/ImageProcessor.cs Adds SVG watermarking and System.Drawing-based opacity helper.
Sources/DiaConvertImageToPDF/PowershellCmdlets/AddWatermarkToSvgPwsh.cs Adds Add-WatermarkToSvg cmdlet for net48 assembly.
Sources/DiaConvertImageToPDF/PowershellCmdlets/SetImageOpacityPwsh.cs Adds Set-ImageOpacity cmdlet for net48 assembly.
Sources/DiaConvertImageToPDF/Todo.md Adds internal todo note for SVG watermark support in net48 project.
AsBuiltReport.Diagram/AsBuiltReport.Diagram.psd1 Bumps module version to 1.0.5 and exports Format-HtmlCell.
AsBuiltReport.Diagram/Src/Private/Format-HtmlCell.ps1 Introduces Format-HtmlCell implementation.
AsBuiltReport.Diagram/Src/Private/Add-NodeImage.ps1 Adds -ImageOpacityPercent and temp-file opacity processing.
AsBuiltReport.Diagram/Src/Private/Add-NodeEdge.ps1 Expands edge length validation range (0–50).
AsBuiltReport.Diagram/Src/Private/ConvertTo-Dot.ps1 Forces Export-PSGraph failures to throw via -ErrorAction Stop.
AsBuiltReport.Diagram/Src/Private/ConvertTo-Svg.ps1 Updates SVG watermark call to pass opacity value directly.
AsBuiltReport.Diagram/Src/Private/Get-BestImageAspectRatio.ps1 Reworks aspect ratio calculation logic.
AsBuiltReport.Diagram/Src/Private/Resize-Image.ps1 Changes smoothing behavior/parameter shape.

Comment on lines 124 to +133
$originalWidth = $Image.Width
$originalHeight = $Image.Height
$aspectRatio = $originalWidth / $originalHeight

# Determine new dimensions based on constraints
if ($MaxWidth -and $originalWidth -gt $MaxWidth) {
$newWidth = $MaxWidth
$newHeight = [int]($newWidth / $aspectRatio)
} elseif ($MaxHeight -and $originalHeight -gt $MaxHeight) {
$newHeight = $MaxHeight
$newWidth = [int]($newHeight * $aspectRatio)
} else {
$newWidth = $originalWidth
$newHeight = $originalHeight
}
$ratioX = $MaxWidth / $OriginalWidth
$ratioY = $MaxHeight / $OriginalHeight
$ratio = [Math]::Min($ratioX, $ratioY)

$ImagePrty = @{
'Width' = $newWidth
'Height' = $newHeight
'Width' = [int]($OriginalWidth * $ratio)
'Height' = [int]($OriginalHeight * $ratio)
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new aspect-ratio calculation always scales using $ratio = Min($MaxWidth/$originalWidth, $MaxHeight/$originalHeight). When either -MaxWidth or -MaxHeight is omitted, the missing value becomes $null/0 and the ratio becomes 0, returning Width/Height = 0. It also upscales images when the ratio > 1 (previous logic preserved original size). Update the logic to treat unspecified constraints as 1, and clamp the final ratio to a maximum of 1 (and/or preserve original when already within bounds).

Copilot uses AI. Check for mistakes.
Comment thread .vscode/launch.json
Comment on lines +18 to +24
"args": [
"-NoExit",
"-NoProfile",
"-Command",
"import-module ./Sources/Diagrammer/bin/Debug/net8.0/AbrDiagrammer.dll",
],
"cwd": "${workspaceFolder}",
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This launch configuration JSON is invalid because of trailing commas (e.g., after the last string in the args array and after the last configuration object). VS Code will fail to load the file until those trailing commas are removed.

Copilot uses AI. Check for mistakes.
Comment thread .vscode/tasks.json
Comment on lines 9 to 15
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
},
{
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tasks.json is not valid JSON due to trailing commas after properties/objects (e.g., after "problemMatcher": [] blocks). Remove the trailing commas so VS Code can parse the tasks file.

Copilot uses AI. Check for mistakes.
Comment on lines 60 to 66
[Parameter(Mandatory = $False)][Switch]$MaintainRatio,
[Parameter(Mandatory = $False, ParameterSetName = 'Absolute')][Int]$Height,
[Parameter(Mandatory = $False, ParameterSetName = 'Absolute')][Int]$Width,
[Parameter(Mandatory = $False, ParameterSetName = 'Percent')][Double]$Percentage,
[Parameter(Mandatory = $False)][System.Drawing.Drawing2D.SmoothingMode]$SmoothingMode = 'HighQuality',
[Parameter(Mandatory = $False)][Switch]$SmoothingMode,
[Parameter(Mandatory = $False)][String]$NameModifier = 'resized'
)
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment-based help says SmoothingMode "Default is HighQuality", but the parameter was changed to a [switch] and HighQuality is only applied when the switch is present. Either keep the previous behavior (apply HighQuality by default) or update the parameter/help to reflect the new semantics (e.g., rename to -UseHighQualitySmoothing).

Copilot uses AI. Check for mistakes.
Comment on lines +163 to +173
# Apply opacity to a temp file when requested
$IconSrc = $ICON
if ($ImageOpacityPercent -lt 100) {
if (-not $IconPath) {
throw 'IconPath is required when ImageOpacityPercent is less than 100.'
}
$sourcePath = Join-Path -Path $IconPath -ChildPath $ICON
$ext = [System.IO.Path]::GetExtension($ICON)
$tempFileName = [System.IO.Path]::GetRandomFileName()
$IconSrc = [System.IO.Path]::ChangeExtension((Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $tempFileName), $ext)
Set-ImageOpacity -SourceImageFilePath $sourcePath -OutputImageFilePath $IconSrc -Opacity $ImageOpacityPercent | Out-Null
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When ImageOpacityPercent < 100, this creates a randomly named temp file for every call and never deletes it. Over time this can clutter the temp directory. Consider either (1) caching/reusing opacity-adjusted files (keyed by source+opacity), (2) writing into the diagram output folder and cleaning up after export, or (3) tracking created temp paths and deleting them once the diagram render completes.

Copilot uses AI. Check for mistakes.
Comment on lines +172 to +173
$IconSrc = [System.IO.Path]::ChangeExtension((Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $tempFileName), $ext)
Set-ImageOpacity -SourceImageFilePath $sourcePath -OutputImageFilePath $IconSrc -Opacity $ImageOpacityPercent | Out-Null
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set-ImageOpacity's success result is ignored. If the cmdlet fails (returns false or throws), the function will still emit HTML referencing $IconSrc, which may not exist and will break rendering. Capture the return value and/or use -ErrorAction Stop and then validate the output file exists before using $IconSrc.

Suggested change
$IconSrc = [System.IO.Path]::ChangeExtension((Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $tempFileName), $ext)
Set-ImageOpacity -SourceImageFilePath $sourcePath -OutputImageFilePath $IconSrc -Opacity $ImageOpacityPercent | Out-Null
$tempIconSrc = [System.IO.Path]::ChangeExtension((Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $tempFileName), $ext)
try {
$opacityResult = Set-ImageOpacity -SourceImageFilePath $sourcePath -OutputImageFilePath $tempIconSrc -Opacity $ImageOpacityPercent -ErrorAction Stop
} catch {
throw "Failed to apply opacity to image '$sourcePath'. $($_.Exception.Message)"
}
if (($null -ne $opacityResult -and $opacityResult -eq $false) -or -not (Test-Path -LiteralPath $tempIconSrc -PathType Leaf)) {
throw "Failed to generate opacity-adjusted image '$tempIconSrc' from source '$sourcePath'."
}
$IconSrc = $tempIconSrc

Copilot uses AI. Check for mistakes.
Comment on lines +292 to +294
catch (Exception ex)
{
Console.WriteLine($"Error setting image opacity: {ex.Message}");
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helper logs failures via Console.WriteLine, which can leak unexpected text into PowerShell output/CI logs and is hard to control. Prefer propagating the exception (or returning false without writing) and let the cmdlet surface errors via WriteError/WriteVerbose so callers can handle failures predictably.

Suggested change
catch (Exception ex)
{
Console.WriteLine($"Error setting image opacity: {ex.Message}");
catch (Exception)
{

Copilot uses AI. Check for mistakes.
Comment thread Tests/Invoke-Tests.ps1
Comment on lines +1 to +8
<#
.SYNOPSIS
Invoke Pester tests for AsBuiltReport.Microsoft.AD module

.DESCRIPTION
This script runs Pester tests with optional code coverage analysis.
It's designed to work with CI/CD pipelines and local development.

Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment-based help references a different module ("AsBuiltReport.Microsoft.AD"). Update the synopsis/description to match this repo/module (AsBuiltReport.Diagram) to avoid confusion for contributors running tests locally or in CI.

Copilot uses AI. Check for mistakes.
Comment thread Todo.md
Comment on lines +8 to +11
- [x] Add function to dinamically build Table cells based on input use Format-HTMLTable as example
- [x] Add pester to test this funtionality
- [x] Add documentation for this funtionality
- [x] Add example for this funtionality
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling: "dinamically" should be "dynamically" (and "funtionality" -> "functionality") in this checklist item.

Copilot uses AI. Check for mistakes.
@rebelinux
Copy link
Copy Markdown
Collaborator Author

@copilot apply changes based on the comments in this thread

@rebelinux rebelinux merged commit 71866b2 into main Apr 2, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants