Skip to content

Commit 5022814

Browse files
committed
Reduce PowerShell Lambda INIT time by omitting unwanted files from packaged modules (#2358)
1 parent 3786871 commit 5022814

6 files changed

Lines changed: 367 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## Release 2026-05-30
2+
3+
### AWSLambdaPSCore PowerShell Module (5.0.2)
4+
* Reduce Lambda cold start INIT times by stripping files that are not used at runtime (PowerShell help XML and .pdb debug symbols) from AWS-authored modules (AWSPowerShell.NetCore and AWS.Tools.*) during packaging
5+
16
## Release 2026-05-28
27

38
### Amazon.Lambda.RuntimeSupport (2.1.1)

PowerShell/Module/AWSLambdaPSCore.psd1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'AWSLambdaPSCore.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '5.0.1.0'
15+
ModuleVersion = '5.0.2.0'
1616

1717
# Supported PSEditions
1818
CompatiblePSEditions = 'Core'

PowerShell/Module/Private/_Constants.ps1

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,33 @@ if (!($AwsPowerShellTargetFramework))
3131
if (!($AwsPowerShellLambdaRuntime))
3232
{
3333
New-Variable -Name AwsPowerShellLambdaRuntime -Value 'dotnet10' -Option Constant
34+
}
35+
36+
if (!($AwsModuleStripFilters))
37+
{
38+
# File patterns inside AWS-authored PowerShell modules that have no purpose at
39+
# Lambda runtime (no interactive shell, no Get-Help, no debugger). Stripping
40+
# them reduces package size and INIT (cold-start) duration. LICENSE / NOTICE
41+
# files are intentionally retained.
42+
#
43+
# The '*.xml' pattern matches case-insensitively, covering:
44+
# - <Module>.dll-Help.xml — PowerShell MAML help
45+
# - <Module>.XML — .NET XMLDoc compiler output (IntelliSense data)
46+
# - PSGetModuleInfo.xml — PowerShellGet install metadata
47+
# Format.ps1xml / Types.ps1xml are NOT matched because their extension is
48+
# .ps1xml (not .xml) and the wildcard requires a literal '.xml' suffix.
49+
New-Variable -Name AwsModuleStripFilters -Value @(
50+
'*.xml',
51+
'*.pdb'
52+
) -Option Constant
53+
}
54+
55+
if (!($AwsAuthoredModuleNamePatterns))
56+
{
57+
# Only AWS-authored modules under Modules/ are stripped; third-party / community
58+
# modules are left untouched.
59+
New-Variable -Name AwsAuthoredModuleNamePatterns -Value @(
60+
'AWSPowerShell.NetCore',
61+
'AWS.Tools.*'
62+
) -Option Constant
3463
}

PowerShell/Module/Private/_DeploymentFunctions.ps1

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,57 @@ function _formatArray
479479
return $sb.ToString()
480480
}
481481

482+
function _stripAwsModuleFiles
483+
{
484+
param
485+
(
486+
[Parameter(Mandatory = $true)]
487+
[string]$ModulesRoot,
488+
489+
[Parameter(Mandatory = $true)]
490+
[string[]]$Filters,
491+
492+
[Parameter(Mandatory = $true)]
493+
[string[]]$ModuleNamePatterns
494+
)
495+
496+
if (!(Test-Path -Path $ModulesRoot))
497+
{
498+
return
499+
}
500+
501+
foreach ($moduleDir in (Get-ChildItem -Path $ModulesRoot -Directory))
502+
{
503+
$matchesAws = $false
504+
foreach ($pattern in $ModuleNamePatterns)
505+
{
506+
if ($moduleDir.Name -like $pattern)
507+
{
508+
$matchesAws = $true
509+
break
510+
}
511+
}
512+
513+
if (-not $matchesAws)
514+
{
515+
continue
516+
}
517+
518+
$removed = Get-ChildItem -Path $moduleDir.FullName -Recurse -File -Include $Filters -ErrorAction SilentlyContinue
519+
foreach ($file in $removed)
520+
{
521+
Write-Verbose ('Removing AWS module file: {0}' -f $file.FullName)
522+
Remove-Item -LiteralPath $file.FullName -Force -ErrorAction SilentlyContinue
523+
}
524+
525+
$count = ($removed | Measure-Object).Count
526+
if ($count -gt 0)
527+
{
528+
Write-Verbose ('Stripped {0} unwanted file(s) from AWS module {1}' -f $count, $moduleDir.Name)
529+
}
530+
}
531+
}
532+
482533
function _prepareDependentPowerShellModules
483534
{
484535
param
@@ -567,6 +618,11 @@ function _prepareDependentPowerShellModules
567618
}
568619
## Add verbosity that no RequiredModules found
569620
else {Write-Verbose "No RequiredModules found for script '$Script'"}
621+
622+
_stripAwsModuleFiles `
623+
-ModulesRoot $SavedModulesDirectory `
624+
-Filters $AwsModuleStripFilters `
625+
-ModuleNamePatterns $AwsAuthoredModuleNamePatterns
570626
}
571627

572628
function _findLocalModule

PowerShell/Tests/Get-AWSPowerShelLambdaTemplate.Tests.ps1

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,33 @@ Import-Module $moduleManifestPath
77
InModuleScope -ModuleName $module -ScriptBlock {
88
Describe -Name 'Get-AWSPowerShellLambdaTemplate' -Fixture {
99

10-
function LoadFakeData
11-
{
12-
ConvertTo-Json -InputObject @{
13-
manifestVersion = 1
14-
blueprints = @(
15-
@{
16-
name = 'Basic'
17-
description = 'Bare bones script'
18-
content = @(
19-
@{
20-
source = 'basic.ps1.txt'
21-
output = '{basename}.ps1'
22-
filetype = 'lambdaFunction'
23-
},
24-
@{
25-
source = 'readme.txt'
26-
output = 'readme.txt'
27-
}
28-
)
29-
}
30-
)
10+
BeforeAll {
11+
function LoadFakeData
12+
{
13+
ConvertTo-Json -InputObject @{
14+
manifestVersion = 1
15+
blueprints = @(
16+
@{
17+
name = 'Basic'
18+
description = 'Bare bones script'
19+
content = @(
20+
@{
21+
source = 'basic.ps1.txt'
22+
output = '{basename}.ps1'
23+
filetype = 'lambdaFunction'
24+
},
25+
@{
26+
source = 'readme.txt'
27+
output = 'readme.txt'
28+
}
29+
)
30+
}
31+
)
32+
}
3133
}
34+
Mock -CommandName '_getHostedBlueprintsContent' -MockWith {LoadFakeData}
35+
Mock -CommandName '_getLocalBlueprintsContent' -MockWith {LoadFakeData}
3236
}
33-
Mock -CommandName '_getHostedBlueprintsContent' -MockWith {LoadFakeData}
34-
Mock -CommandName '_getLocalBlueprintsContent' -MockWith {LoadFakeData}
3537

3638
Context -Name 'Online Templates' -Fixture {
3739
It -Name 'Retrieves Blueprints from online sources by default' -Test {

0 commit comments

Comments
 (0)