Skip to content

Instantly share code, notes, and snippets.

@markwragg
Last active August 30, 2017 07:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markwragg/fc0d9471bae2b5db2b195acba1394edc to your computer and use it in GitHub Desktop.
Save markwragg/fc0d9471bae2b5db2b195acba1394edc to your computer and use it in GitHub Desktop.
PowerShell script to install a module from a source control system. For use where package management is not an option.
[cmdletbinding()]
Param()
<#
.SYNOPSIS
Installs a module.
#>
Function Install-Module {
[cmdletbinding(SupportsShouldProcess)]
Param (
#Name of the module to update
[Parameter(Mandatory,Position=0)]
[String]$Name,
#Name of the project in Source Control that hosts the module. If ommitted assumed the same as -Module.
[Parameter(Position=1)]
[String]$Project = $Name,
#The URL of the Source Control account that owns the module
[System.Uri]$Source = 'https://github.com/markwragg',
#Use to trigger Import-Module immediately after the module has been updated.
[Switch]$Import,
#Use to force a module update even where project folder already exists or there are no detected differences.
[Switch]$Force,
#Use to list the available commands at the end of installation
[Switch]$ShowCommands
)
If ($Pscmdlet.ShouldProcess($Name)) {
Try {
If (-not $Project) { Throw 'You must specify -Project' }
If (-not $Source) { Throw 'You must specify -Source' }
If ($Source.host) {
Test-Connection $Source.Host -Count 1 -ErrorAction Stop | Out-Null
} Else {
Throw '-Source must be a valid URL including the http[s]:// prefix'
}
$PSUserModule = $Env:PSModulePath -split ";" | Where-Object {$_ -match $env:USERNAME}
$NewModulePath = Join-Path -Path $PSUserModule -ChildPath $Name
$DownloadPath = "$env:TEMP\$Project"
If (-not (Test-Path -Path $DownloadPath) -or $Force) {
$DownloadFolder = New-Item -Path $env:TEMP -Name $Project -ItemType Directory
} Else {
Throw "Download location $DownloadPath already exists, $Name update aborted. Use -Force to overwrite."
}
Try {
$WebClient = New-Object System.Net.WebClient
$Shell = New-Object -Com Shell.Application
Write-Verbose "Downloading $Name from $Source/$Project"
$WebClient.DownloadFile("$Source/$Project/repository/archive.zip?ref=master","$DownloadPath.zip")
$Shell.namespace("$DownloadPath").CopyHere($Shell.namespace("$DownloadPath.zip").Items(),20)
Copy-Item -Path "$DownloadPath\*\$Name" -Destination $PSUserModule -Force -Recurse
Write-Verbose "$Name has been installed"
If ($Import) {
$env:CI = $true
Import-Module $(Join-Path -Path $NewModulePath -ChildPath "$Name.psd1") -Force
Write-Verbose "$Name has been imported"
}
Write-Host "$Name module is installed and ready to use" -Foreground Green
If ($ShowCommands) {
Write-Host "USAGE:"
Write-Host "`tPS> Import-Module $Name`n"
Write-Host "COMMANDS:"
(Get-Command -Module $Name).Name | ForEach-Object { Write-Host "`t$_" } -End { Write-Host "" }
}
} Catch {
Write-Error "Could not install $Name module : $($_.Exception.Message)"
} Finally {
If (Test-Path $DownloadFolder) { Remove-Item $DownloadFolder -Recurse -Force }
}
} Catch {
Write-Error "Could not install $Name module : $($_.Exception.Message)"
}
}
}
Try {
Install-Module -Name 'SomePreReqModule' -Import -Force
Install-Module -Name 'SomeModule' -Project 'SomeProject' -ShowCommands -Import -Force
} Catch {
Write-Error $_
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment