Public/Install-SpecModuleFromBlobStorage.ps1

function Install-SpecModuleFromBlobStorage {
    <#
.SYNOPSIS
Installs or updates a PowerShell module from Azure Blob Storage and imports it.
 
.DESCRIPTION
Checks whether the required module version is already installed. If not,
downloads and installs the module from Blob Storage, removes any loaded
instances, and imports the correct version into the current session.
 
.PARAMETER ModuleName
The name of the module to install or update.
 
.PARAMETER RequiredVersion
The module version to ensure is installed.
 
.PARAMETER StorageAccount
The Azure storage account name.
 
.PARAMETER ContainerName
The Blob Storage container name.
 
.PARAMETER SasKey
The SAS key to access the Blob Storage container.
 
.PARAMETER InstallPath
The directory path where the module should be installed. Defaults to
$env:ProgramFiles\WindowsPowerShell\Modules\$ModuleName.
 
.EXAMPLE
Install-SpecModuleFromBlobStorage -ModuleName 'MyModule' `
    -RequiredVersion '1.0.0' `
    -StorageAccount 'mystorage' `
    -ContainerName 'modules' `
    -SasKey '?sv=...' `
    -InstallPath 'C:\Modules\MyModule'
 
.OUTPUTS
Boolean $true if installation and import succeed.
 
.NOTES
Author: owen.heaume
Version: 1.0 - Initial release
#>


    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$ModuleName,

        [Parameter(Mandatory)]
        [string]$RequiredVersion,

        [Parameter(Mandatory)]
        [string]$StorageAccount,

        [Parameter(Mandatory)]
        [string]$ContainerName,

        [Parameter(Mandatory)]
        [string]$SasKey,

        [Parameter(Mandatory)]
        [string]$InstallPath = (Join-Path $env:ProgramFiles "WindowsPowerShell\Modules\$ModuleName")
    )

    Write-Verbose "Starting installation for '$ModuleName' v$RequiredVersion..."

    try {
        # 1. Construct Blob URLs
        $urls = Get-specBlobModuleUrls -ModuleName $ModuleName -RequiredVersion $RequiredVersion -StorageAccount $StorageAccount -ContainerName $ContainerName -SasKey $SasKey

        # 2. Check installed versions
        $installedModules = Get-specInstalledModuleVersion -ModuleName $ModuleName
        $installedRequired = $installedModules | ? { $_.Version -eq [version]$RequiredVersion }

        # 3. Install if needed
        if ($installedRequired) {
            Write-Verbose "Module '$ModuleName' v$RequiredVersion is already installed."
        } elseif ($installedModules) {
            $latestInstalled = $installedModules | Sort-Object Version -Descending | Select-Object -First 1
            Write-Verbose "Found version $($latestInstalled.Version), updating to required version $RequiredVersion..."

            Install-specModuleFromBlob -ModuleName $ModuleName -InstallPath $InstallPath -Psm1Url $urls.Psm1Url -Psd1Url $urls.Psd1Url
        } else {
            Write-Verbose "Module '$ModuleName' not installed. Installing v$RequiredVersion..."
            Install-specModuleFromBlob -ModuleName $ModuleName -InstallPath $InstallPath -Psm1Url $urls.Psm1Url -Psd1Url $urls.Psd1Url
        }

        # 4. Remove the module (if loaded)
        try {
            Remove-specModule2 -Name $ModuleName -ea Stop
            Write-Verbose "Removed old module '$ModuleName'."
        } catch {
            Write-Verbose "Could not remove '$ModuleName' (it may not have been loaded)."
        }

        # 5. Import the module
        try {
            Import-specModule2 -Name $ModuleName -Version $RequiredVersion -ea Stop
            Write-Verbose "Imported '$ModuleName' v$RequiredVersion successfully."
        } catch {
            Write-Error "Failed to import '$ModuleName': $($_.Exception.Message)"
            #throw
        }

        Write-Verbose "Installation process complete for '$ModuleName' v$RequiredVersion."
        return $true
    } catch {
        Write-Error "Failed to install or import module '$ModuleName': $($_.Exception.Message)"
    }
}