Public/New-SelfContainedPackage.ps1
function New-SelfContainedPackage { <# .SYNOPSIS Create self-contained package .DESCRIPTION Bundle package with embedded dependencies .PARAMETER Package The package parameter corresponds to the path to the package to bundle. .NOTES File name: New-SelfContainedPackage.ps1 Author: Florian Carrier Creation date: 2021-07-06 Last modified: 2021-07-28 #> [CmdletBinding ( SupportsShouldProcess = $true )] Param ( [Parameter ( Position = 1, Mandatory = $true, HelpMessage = "Path to the package to bundle" )] [ValidateNotNullOrEmpty ()] [Alias ("Package")] [System.String] $Path, [Parameter ( Position = 2, Mandatory = $false, HelpMessage = "Path to the location where to create the package" )] [ValidateNotNullOrEmpty ()] [System.String] $Destination, [Parameter ( Position = 3, Mandatory = $false, HelpMessage = "List of modules to add to bundle" )] [ValidateNotNullOrEmpty ()] [System.String[]] $Modules, [Parameter ( Position = 4, Mandatory = $false, HelpMessage = "List of files or directories to ignore" )] [ValidateNotNullOrEmpty ()] [System.String[]] $Ignore ) Begin { # Get global preference vrariables Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState # Variables $PackageName = Split-Path -Path $Path -Leaf $PackagePath = Resolve-Path -Path $Path if ($PSBoundParameters.ContainsKey('Destination')) { if (Test-Path -Path $Destination -PathType "Leaf") { $Extension = [System.IO.Path]::GetExtension($Destination) if ($Extension -ne ".zip") { Write-Log -Type "WARN" -Message "$Extension is not a supported archive file format. .zip is the only supported archive file format." $Destination = $Destination.Replace($Extension, ".zip") } $CompressedPackage = $Destination $Destination = Split-Path -Path $Destination -Parent $StagingPath = Join-Path -Path $Destination -ChildPath $PackageName } else { $StagingPath = Join-Path -Path $Destination -ChildPath $PackageName $CompressedPackage = [System.String]::Concat($StagingPath, ".zip") } } else { $Destination = Split-Path -Path $PackagePath -Parent $ISOTimeStamp = Get-Date -Format "yyyyMMdd_HHmmss" $UniquePackageName = [System.String]::Concat($PackageName, "_", $ISOTimeStamp) $StagingPath = Join-Path -Path $Destination -ChildPath $UniquePackageName $CompressedPackage = [System.String]::Concat($PackagePath, ".zip") } } Process { Write-Log -Type "INFO" -Message "Creating self-contained ""$PackageName"" package" # Stage package if (Test-Path -Path $PackagePath) { if (Test-Path -Path $StagingPath) { Write-Log -Type "WARN" -Message "Removing existing staging directory ""$StagingPath""" Remove-Object -Path $StagingPath } Copy-Object -Path $PackagePath -Destination $Destination -Exclude $Ignore -Force } else { Write-Log -Type "ERROR" -Message "Path not found $PackagePath" -ErrorCode 1 } # # List all required modules foreach ($Module in $Modules) { $ModuleDirectory = Join-Path -Path $StagingPath -ChildPath "lib" Write-Log -Type "INFO" -Message "Retrieving module ""$Module""" $Load = $false :loop foreach ($Repository in ($env:PSModulePath -split ";")) { Write-Log -Type "DEBUG" -Message $Repository $ModulePath = Join-Path -Path $Repository -ChildPath $Module Write-Log -Type "DEBUG" -Message $ModulePath if (Test-Path -Path $ModulePath) { Copy-Object -Path $ModulePath -Destination $ModuleDirectory -Exclude $Ignore -Force $Load = $true break loop } } if ($Load -eq $false) { Write-Log -Type "WARN" -Message "module $Module could not be found" } } # # Compress package if (Test-Path -Path $StagingPath) { Write-Log -Type "INFO" -Message "Compressing package" Write-Log -Type "DEBUG" -Message $CompressedPackage if (Test-Path -Path $CompressedPackage) { Write-Log -Type "WARN" -Message "Overwriting existing package" } Compress-Archive -Path "$StagingPath\*" -DestinationPath $CompressedPackage -CompressionLevel "Fastest" -Force } else { Write-Log -Type "ERROR" -Message "Path not found $StagingPath" Write-Log -Type "ERROR" -Message "Script packaging failed" -ErrorCode 1 } # Delete staging package Write-Log -Type "INFO" -Message "Deleting staged package folder" Write-Log -Type "DEBUG" -Message $StagingPath Remove-Object -Path $StagingPath # # End Write-Log -Type "CHECK" -Message """$PackageName"" self-contained package complete" } } |