Skip to content

Commit 4bafe09

Browse files
committed
Add ImportBase64Module
1 parent 81bd815 commit 4bafe09

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

Source/Private/ImportBase64Module.ps1

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# The comment-based help for this function is outside the function to avoid packing it
2+
# Normally, I put it inside, but I do not want this in packed scripts
3+
4+
<#
5+
.SYNOPSIS
6+
Expands Base64+GZip strings and loads the result as an assembly or module
7+
.DESCRIPTION
8+
Converts Base64 encoded string to bytes and decompresses (gzip) it.
9+
If the result is a valid assembly, it is loaded.
10+
Otherwise, it is imported as a module.
11+
.PARAMETER Base64Content
12+
A Base64 encoded and deflated assembly or script
13+
.LINK
14+
CompressToBase64
15+
#>
16+
function ImportBase64Module {
17+
[CmdletBinding(DefaultParameterSetName = "ByteArray")]
18+
param(
19+
[Parameter(Mandatory, ValueFromPipeline)]
20+
[string]$Base64Content
21+
)
22+
process {
23+
$Out = [System.IO.MemoryStream]::new()
24+
$In = [System.IO.MemoryStream][System.Convert]::FromBase64String($Base64Content)
25+
$zip = [System.IO.Compression.DeflateStream]::new($In, [System.IO.Compression.CompressionMode]::Decompress)
26+
$zip.CopyTo($Out)
27+
trap [System.IO.InvalidDataException] {
28+
Write-Debug "Base64Content not Compressed. Skipping Deflate."
29+
$In.CopyTo($Out)
30+
continue
31+
}
32+
$null = $Out.Seek(0, "Begin")
33+
$null = [System.Reflection.Assembly]::Load($Out.ToArray())
34+
trap [BadImageFormatException] {
35+
Write-Debug "Base64Content not an Assembly. Trying New-Module and ScriptBlock.Create."
36+
$null = $Out.Seek(0, "Begin")
37+
# Use StreamReader to handle possible BOM
38+
$Source = [System.IO.StreamReader]::new($Out, $true).ReadToEnd()
39+
$null = New-Module ([ScriptBlock]::Create($Source)) -Verbose:$false | Import-Module -Scope Global -Verbose:$false
40+
continue
41+
}
42+
}
43+
}
+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Describe "ImportBase64Module" {
2+
BeforeAll {
3+
$PSDefaultParameterValues = @{
4+
"Mock:ModuleName" = "ModuleBuilder"
5+
"Assert-MockCalled:ModuleName" = "ModuleBuilder"
6+
}
7+
8+
$Source = Convert-Path (Join-Path $PSScriptRoot ../Integration/Source1/Public/Set-Source.ps1)
9+
10+
$CommandUnderTest, $Base64 = InModuleScope ModuleBuilder {
11+
Get-Command ImportBase64Module
12+
CompressToBase64 (Join-Path $PSScriptRoot ../Integration/Source1/Public/Set-Source.ps1) -Debug
13+
}
14+
15+
$Plain = Get-Content $Source -Raw
16+
17+
}
18+
19+
It "Calls New-Module with the decompressed script" {
20+
Mock New-Module
21+
& $CommandUnderTest $Base64
22+
23+
Assert-MockCalled New-Module -ParameterFilter {
24+
"$ScriptBlock" -eq $Plain
25+
}
26+
}
27+
28+
It "Calls Import-Module with the new module" {
29+
Mock Import-Module
30+
& $CommandUnderTest $Base64
31+
Assert-MockCalled Import-Module -ParameterFilter {
32+
$ModuleInfo[0].Definition -eq $Plain
33+
}
34+
}
35+
36+
# TODO: Test assemblies
37+
}

0 commit comments

Comments
 (0)