From 4031b898ebc53ef3ed92d2ff8c0d1d738d54ef13 Mon Sep 17 00:00:00 2001 From: Sam Erde <20478745+SamErde@users.noreply.github.com> Date: Wed, 6 May 2026 05:17:27 -0400 Subject: [PATCH 1/4] Optimize ESC3 scan array accumulation to avoid intermediate copy Replace two-step [array]\ = ...; [array]\ += ... pattern with a single array concatenation expression in both the ESC3 case and the All case of Invoke-Scans. This eliminates the unnecessary intermediate array allocation and copy that occurs when += is used to append a second scan result array to the first. No behavior change: the resulting \ array contains exactly the same elements in the same order (ESC3C1 results followed by ESC3C2 results). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Private/Invoke-Scans.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Private/Invoke-Scans.ps1 b/Private/Invoke-Scans.ps1 index a1af997..9f929a8 100644 --- a/Private/Invoke-Scans.ps1 +++ b/Private/Invoke-Scans.ps1 @@ -88,8 +88,8 @@ function Invoke-Scans { } ESC3 { Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' - [array]$ESC3 = Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers - [array]$ESC3 += Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + [array]$ESC3 = @(Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) + + @(Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) } ESC4 { Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' @@ -147,8 +147,8 @@ function Invoke-Scans { Write-Host 'Identifying AD CS templates with dangerous ESC2 configurations...' [array]$ESC2 = Find-ESC2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' - [array]$ESC3 = Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers - [array]$ESC3 += Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + [array]$ESC3 = @(Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) + + @(Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' [array]$ESC4 = Find-ESC4 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes -Mode $Mode -UnsafeUsers $UnsafeUsers Write-Host 'Identifying AD CS objects with poor access control (ESC5)...' From fb09787a4ff10f514b3551c6e2c601e2c3964165 Mon Sep 17 00:00:00 2001 From: Sam Erde <20478745+SamErde@users.noreply.github.com> Date: Wed, 6 May 2026 05:34:05 -0400 Subject: [PATCH 2/4] Use single ESC3 array materialization Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Private/Invoke-Scans.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Private/Invoke-Scans.ps1 b/Private/Invoke-Scans.ps1 index 9f929a8..1303032 100644 --- a/Private/Invoke-Scans.ps1 +++ b/Private/Invoke-Scans.ps1 @@ -88,8 +88,10 @@ function Invoke-Scans { } ESC3 { Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' - [array]$ESC3 = @(Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) + - @(Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) + [array]$ESC3 = @( + Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + ) } ESC4 { Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' From 49cd74339295eaa4a297710567d270a50cca2f0b Mon Sep 17 00:00:00 2001 From: Sam Erde <20478745+SamErde@users.noreply.github.com> Date: Wed, 6 May 2026 05:34:44 -0400 Subject: [PATCH 3/4] fix: use single array subexpression for ESC3 accumulation Replace @(A) + @(B) with @(A; B) multi-statement form to avoid creating 3 intermediate arrays. The @() + @() pattern materializes both arrays separately and then allocates a third via the + operator. The single-subexpression form @(stmt1; stmt2) collects all pipeline output in one pass using PowerShell's internal List-based collector, reducing from 3 allocations to 1. Addresses GitHub Copilot code review on PR #275. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Private/Invoke-Scans.ps1 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Private/Invoke-Scans.ps1 b/Private/Invoke-Scans.ps1 index 1303032..95786d3 100644 --- a/Private/Invoke-Scans.ps1 +++ b/Private/Invoke-Scans.ps1 @@ -149,8 +149,10 @@ function Invoke-Scans { Write-Host 'Identifying AD CS templates with dangerous ESC2 configurations...' [array]$ESC2 = Find-ESC2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' - [array]$ESC3 = @(Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) + - @(Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers) + [array]$ESC3 = @( + Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + ) Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' [array]$ESC4 = Find-ESC4 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes -Mode $Mode -UnsafeUsers $UnsafeUsers Write-Host 'Identifying AD CS objects with poor access control (ESC5)...' From a90022c47a13f03f7f500ecd5d455e73823538a1 Mon Sep 17 00:00:00 2001 From: Sam Erde <20478745+SamErde@users.noreply.github.com> Date: Wed, 6 May 2026 05:35:39 -0400 Subject: [PATCH 4/4] Update generated ESC3 accumulation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Invoke-Locksmith.ps1 | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Invoke-Locksmith.ps1 b/Invoke-Locksmith.ps1 index 9c2b6db..5f49d5e 100644 --- a/Invoke-Locksmith.ps1 +++ b/Invoke-Locksmith.ps1 @@ -1,4 +1,4 @@ -[CmdletBinding(HelpUri = 'https://jakehildreth.github.io/Locksmith/Invoke-Locksmith')] +[CmdletBinding(HelpUri = 'https://jakehildreth.github.io/Locksmith/Invoke-Locksmith')] param ( # The mode to run Locksmith in. Defaults to 0. [Parameter(Mandatory = $false)] @@ -2849,8 +2849,10 @@ function Invoke-Scans { } ESC3 { Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' - [array]$ESC3 = Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers - [array]$ESC3 += Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + [array]$ESC3 = @( + Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + ) } ESC4 { Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' @@ -2908,8 +2910,10 @@ function Invoke-Scans { Write-Host 'Identifying AD CS templates with dangerous ESC2 configurations...' [array]$ESC2 = Find-ESC2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers Write-Host 'Identifying AD CS templates with dangerous ESC3 configurations...' - [array]$ESC3 = Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers - [array]$ESC3 += Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + [array]$ESC3 = @( + Find-ESC3C1 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + Find-ESC3C2 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -UnsafeUsers $UnsafeUsers + ) Write-Host 'Identifying AD CS templates with poor access control (ESC4)...' [array]$ESC4 = Find-ESC4 -ADCSObjects $ADCSObjects -SafeUsers $SafeUsers -DangerousRights $DangerousRights -SafeOwners $SafeOwners -SafeObjectTypes $SafeObjectTypes -Mode $Mode -UnsafeUsers $UnsafeUsers Write-Host 'Identifying AD CS objects with poor access control (ESC5)...'