Last active
June 4, 2025 19:00
-
-
Save griffeth-barker/30d781904c9a9579ce360303c4ed9e93 to your computer and use it in GitHub Desktop.
Import a PowerShell module directly from GitHub/GitLab without having to install it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Import-ModuleFromGitx { | |
<# | |
.SYNOPSIS | |
Imports a PowerShell module from a GitHub repository. | |
.DESCRIPTION | |
This function lets you import a PowerShell module directly from a GitHub repository without needing to install the module. | |
The module is downloaded from the specified GitHub repository URI, extracted, and imported into your current PowerShell session. | |
.PARAMETER Uri | |
The URI of the GitHub repository. This can be obtained by clicking the green "Code" button on the repository page and copying the HTTPS URL. | |
Type : String | |
Required : True | |
ValueFromPipeline : True | |
.PARAMETER OutputDir | |
The directory where the module will be downloaded and imported. | |
Type : String | |
Required : False | |
Default Value : $pwd | |
.EXAMPLE | |
# Import a PowerShell module from a GitHub or GitLab repository | |
Import-ModuleFromGitx -Uri "https://github.com/username/repository.git" | |
Import-ModuleFromGitx -Uri "https://gitlab.com/workspace/repository.git" | |
.EXAMPLE | |
# Import a PowerShell module from a GitHub or GitLab repository and specify an output directory other than the present working directory | |
Import-ModuleFromGitx -Uri "https://github.com/username/repository.git" -OutputDir "$env:USERPROFILE\Downloads" | |
Import-ModuleFromGitx -Uri "https://gitlab.com/workspace/repository.git" -OutputDir "$env:USERPROFILE\Downloads" | |
.NOTES | |
It is possible to use this function to get around restrictions in your environment that prevent you from installing modules directly from the PowerShell Gallery or other sources. | |
You should comply with all regulations, company policies, licensing agreements, and other requirements/restrictions. Use at your own risk. | |
Does NOT support privately hosted versions of GitLab. | |
.LINK | |
https://gist.github.com/griffeth-barker/30d781904c9a9579ce360303c4ed9e93 | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory = $true, ValueFromPipeline = $true)] | |
[string]$Uri, | |
[Parameter(Mandatory = $false)] | |
[string]$OutputDir = "$pwd" | |
) | |
begin { | |
function constructGitHubUri($Url) { | |
if ($Uri -match "^https://github\.com/([^/]+)/([^/]+)(?:/)?$") { | |
$user = $matches[1] | |
$repo = $matches[2] -replace "\.git$", "" | |
return "https://github.com/$user/$repo/archive/refs/heads/main.zip" | |
} | |
else { | |
Write-Error "Invalid GitHub repository URL format. Should be 'https://github.com/username/repository.git' where username and repository are the GitHub valid user and repository names." | |
exit 1 | |
} | |
} | |
function constructGitLabUri($Url) { | |
if ($Uri -match "^https://gitlab\.com/([^/]+)/([^/]+)(?:/)?$") { | |
$workspace = $matches[1] | |
$repo = $matches[2] -replace "\.git$", "" | |
return "https://gitlab.com/$workspace/$repo/-/archive/main/$repo-main.zip" | |
} | |
else { | |
Write-Error "Invalid GitLab repository URL format. Should be 'https://gitlab.com/workspace/repository.git' where username and repository are the GitLab valid user and repository names." | |
exit 1 | |
} | |
} | |
} | |
process { | |
switch ($Uri.Split('/')[2]) { | |
"github.com" { | |
Write-Debug "Detected GitHub repository; using constructGitHubUri function" | |
$downloadUrl = constructGitHubUri -url $Uri | |
} | |
"gitlab.com" { | |
Write-Debug "Detected GitLab repository; using constructGitLabUri function" | |
$downloadUrl = constructGitLabUri -url $Uri | |
} | |
default { | |
Write-Error "Unsupported repository type. Only GitHub and GitLab repositories are supported at this time." | |
exit 1 | |
} | |
} | |
try { | |
Write-Verbose "Creating temporary directory for download..." | |
Write-Debug "Creating '$env:TEMP\repo_$(New-Guid).zip'" | |
$tempZipPath = "$env:TEMP\repo_$(New-Guid).zip" | |
if (-not (Test-Path $OutputDir)) { | |
New-Item -ItemType Directory -Path $OutputDir | Out-Null | |
} | |
Write-Verbose "Downloading repository..." | |
Write-Debug "Using URI: $Uri" | |
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempZipPath -ErrorAction Stop | |
Write-Debug "File saved to $tempZipPath" | |
Write-Debug "Extracting to $OutputDir" | |
Expand-Archive -Path $tempZipPath -DestinationPath $OutputDir -Force -ErrorAction Stop | |
Write-Debug "Removing $tempZipPath" | |
Remove-Item $tempZipPath -Force | |
Write-Verbose "Importing module..." | |
Write-Debug "Importing module from $OutputDir" | |
Import-Module -Name (Get-ChildItem -Path $OutputDir -Recurse -Filter *.psm1 | Select-Object -First 1).FullName | |
} | |
catch { | |
Write-Error $_.Exception.Message | |
} | |
} | |
end { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment