Install-DTXModule.ps1
<#PSScriptInfo .VERSION 0.0.1 .GUID 2fdc79e7-5369-49b4-9adf-29629023bfd1 .AUTHOR DTX Platform Team .COMPANYNAME .COPYRIGHT .TAGS .LICENSEURI .PROJECTURI .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION Installs a PowerShell module from S3. #> param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string]$Version, [Parameter(Mandatory = $true)] [string]$BucketName, [Parameter(Mandatory = $true)] [string]$BucketRegion, [Parameter(Mandatory = $true)] [string]$ObjectKey, [switch]$SkipTestImport ) Begin { function Install-ModuleForWindows { param ( [string]$Name, [string]$Version, [string]$BucketName, [string]$BucketRegion, [string]$ObjectKey ) # The command is ran inside another PowerShell core process to avoid issues with the current process # More specifically the AWS PowerShell module needed to install the module might not be compatible # with the requirements of the module we are trying to install. pwsh -Command { try { $WarningPreference = "SilentlyContinue" $ProgressPreference = "SilentlyContinue" # Access the passed in arguments $receivedBucketName = $args[0] $receivedBucketRegion = $args[1] $receivedObjectKey = $args[2] $receivedModuleName = $args[3] $receivedModuleVersion = $args[4] # Check if the module is already installed if (Get-Module -Name $receivedModuleName -ListAvailable) { # Check if the candidate version is already installed if (Get-Module -Name $receivedModuleName -ListAvailable | Where-Object { $_.Version -eq $receivedModuleVersion }) { # If the module version is already installed, skip the installation Write-Host "Module $($receivedModuleName) version $($receivedModuleVersion) is already installed." Write-Host "No action required." exit 0 } } Write-Host "Installing $($receivedModuleName) version $($receivedModuleVersion)..." # Import the pre-requisites $preReqModule = "AWSPowerShell.NetCore" if (-not (Get-Module -Name $preReqModule -ListAvailable)) { Install-Module -Name $preReqModule -Force } Import-Module -Name $preReqModule -Force # Download the module from S3 Write-Host "Downloading $($receivedModuleName) version $($receivedModuleVersion) from S3 object $($receivedObjectKey) in bucket $($receivedBucketName)." $tempFile = Read-S3Object -BucketName $receivedBucketName -Region $receivedBucketRegion -Key $receivedObjectKey -File ([System.IO.Path]::GetTempFileName()) $tempPath = [System.IO.Path]::GetTempPath() Expand-Archive -Path $tempFile.FullName -DestinationPath $tempPath -Force # Get the path to the module version $tempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $receivedModuleName $newTempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $receivedModuleVersion # Rename the folder to the module version so dtx.cloud.management > 0.6.1 if (Test-Path -Path $newTempModuleVersionPath) { Remove-Item -Path $newTempModuleVersionPath -Recurse -Force } Rename-Item -Path $tempModuleVersionPath -NewName $newTempModuleVersionPath -Force $modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "PowerShell" -AdditionalChildPath "Modules", $receivedModuleName $modulePathInclVersion = Join-Path -Path $modulePath -ChildPath $receivedModuleVersion # Check if the module exist if (Test-Path -Path $modulePath) { # Check if the module version is already installed Write-Host "Checking if $($modulePathInclVersion) exists..." if (Test-Path -Path $modulePathInclVersion) { # If we reached this point, we do not expect the version dir for this module to exist. # We need to remove it before proceeding Remove-Item -Path $modulePathInclVersion -Recurse -Force } } else { # If the module doesn't exist, create its path Write-Host "Creating $($modulePath)..." [void]$(New-Item -ItemType Directory -Path $modulePath -Force) } # Move the module to the modules folder Write-Host "Installing $($receivedModuleName) version $($receivedModuleVersion)..." Move-Item -Path $newTempModuleVersionPath -Destination $modulePath -Force Write-Host "Module installed successfully." } catch { Write-Error $_.Exception.Message exit 1 } } -Args $BucketName, $BucketRegion, $ObjectKey, $Name, $Version if ($LASTEXITCODE -ne 0) { Write-Error $_.Exception.Message throw "Failed to install module." } } function Install-ModuleForNonWindows { param ( [string]$Name, [string]$Version, [string]$BucketName, [string]$BucketRegion, [string]$ObjectKey ) # The command is ran inside another PowerShell core process to avoid issues with the current process # More specifically the AWS PowerShell module needed to install the module might not be compatible # with the requirements of the module we are trying to install. try { $WarningPreference = "SilentlyContinue" $ProgressPreference = "SilentlyContinue" # Check if the module is already installed if (Get-Module -Name $Name -ListAvailable) { # Check if the candidate version is already installed if (Get-Module -Name $Name -ListAvailable | Where-Object { $_.Version -eq $Version }) { # If the module version is already installed, skip the installation Write-Host "Module $($Name) version $($Version) is already installed." Write-Host "No action required." exit 0 } } Write-Host "Installing $($Name) version $($Version)..." # Import the pre-requisites $preReqModule = "AWSPowerShell.NetCore" if (-not (Get-Module -Name $preReqModule -ListAvailable)) { Install-Module -Name $preReqModule -Force } Import-Module -Name $preReqModule -Force # Download the module from S3 Write-Host "Downloading $($Name) version $($Version) from S3 object $($ObjectKey) in bucket $($BucketName)." $tempFile = Read-S3Object -BucketName $BucketName -Region $BucketRegion -Key $ObjectKey -File ([System.IO.Path]::GetTempFileName()) $tempPath = [System.IO.Path]::GetTempPath() Expand-Archive -Path $tempFile.FullName -DestinationPath $tempPath -Force # Get the path to the module version $tempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $Name $newTempModuleVersionPath = Join-Path -Path $tempPath -ChildPath $Version # Rename the folder to the module version so dtx.cloud.management > 0.6.1 if (Test-Path -Path $newTempModuleVersionPath) { Remove-Item -Path $newTempModuleVersionPath -Recurse -Force } Rename-Item -Path $tempModuleVersionPath -NewName $newTempModuleVersionPath -Force $modulePath = Join-Path -Path "/usr/local/share" -ChildPath "powershell" -AdditionalChildPath "Modules", $Name $modulePathInclVersion = Join-Path -Path $modulePath -ChildPath $Version # Check if the module exist if (Test-Path -Path $modulePath) { # Check if the module version is already installed Write-Host "Checking if $($modulePathInclVersion) exists..." if (Test-Path -Path $modulePathInclVersion) { # If we reached this point, we do not expect the version dir for this module to exist. # We need to remove it before proceeding Remove-Item -Path $modulePathInclVersion -Recurse -Force } } else { # If the module doesn't exist, create its path Write-Host "Creating $($modulePath)..." [void]$(New-Item -ItemType Directory -Path $modulePath -Force) } # Move the module to the modules folder Write-Host "Installing $($Name) version $($Version)..." Move-Item -Path $newTempModuleVersionPath -Destination $modulePath -Force Write-Host "Module installed successfully." } catch { Write-Error $_.Exception.Message throw "Failed to install module." } } function Test-ModuleIsInstalled { param ( [string]$Name, [string]$Version ) try { Write-Host "Testing if $($Name) version $($Version) is installed successfully..." Import-Module -Name $Name -RequiredVersion $Version -Force Write-Host "Test passed." } catch { Write-Error "Test failed." Write-Error $_.Exception.Message } } } Process { try { $params = @{ Name = $Name Version = $Version BucketName = $BucketName BucketRegion = $BucketRegion ObjectKey = $ObjectKey } if ($IsWindows) { Install-ModuleForWindows @params } elseif ($IsLinux -or $MacOS) { Install-ModuleForNonWindows @params } else { throw "Unsupported operating system." } if (-not $SkipTestImport) { Test-ModuleIsInstalled @params } } catch { Write-Error $_.Exception.Message throw "Failed to install module." } } |