Skip to content

Instantly share code, notes, and snippets.

@griffeth-barker
Last active June 4, 2025 19:00
Show Gist options
  • Save griffeth-barker/30d781904c9a9579ce360303c4ed9e93 to your computer and use it in GitHub Desktop.
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.
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