-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.ps1
201 lines (181 loc) · 6.79 KB
/
install.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<# Rob Holme 11/07/2024
.SYNOPSIS
Copy the module files from the current folder to the PowerShell module home.
.DESCRIPTION
Copy the module files from the current folder to the PowerShell module home. Ignore dot folders (such as .git).
.PARAMETER Scope
Install the module to either the current user module path, the all users module path, or prompt the user to select a path from the PSModulePath environment variable.
.EXAMPLE
./Install.ps1 -Scope CurrentUser
.EXAMPLE
./Install.ps1 -Scope AllUsers
.EXAMPLE
./Install.ps1 -Scope PromptForModulePath
#>
[CmdletBinding()]
param (
[Parameter(
Position = 0,
Mandatory = $False,
ValueFromPipeline = $False,
ValueFromPipelineByPropertyName = $True
)]
[ValidateSet("CurrentUser", "AllUsers", "PromptForModulePath")]
[string] $Scope = "CurrentUser"
)
# Get the module version number from the module manifest file.
# Return $null if the module version can not be parsed.
function Get-ModuleVersion() {
$moduleManifestFile = Get-ModuleManifestFile
if ($null -ne $moduleManifestFile) {
$versionElement = Get-Content $moduleManifestFile | Select-String "ModuleVersion(\s){0,}=(\s){0,}('|"")\d{1,}(\.{1}\d{1,}){0,}"
if ($versionElement.Matches.Count -ne 1) {
Write-Error "ModuleVersion element not detected in manifest"
return $null
}
else {
# match version number string
$moduleVersionMatch = ([regex]::Match($versionElement, "\d{1,}(\.{1}\d{1,}){0,}"))
if ($moduleVersionMatch.Success) {
return $moduleVersionMatch[0].Value
}
else {
return $null
}
}
}
return $null
}
# Get the module manifest file
# Return $null if not found, or more than 1 manaifest file present in the current directory.
function Get-ModuleManifestFile {
try {
$moduleFile = Get-ChildItem *.psd1
}
catch {
Write-Error "Exception raised while detecting module file, exiting. Use -Debug switch to view exception"
Write-Debug $_.Exception
return $null
}
# Make sure only one module file is found, otherwise exit.
if ($moduleFile.Count -eq 1) {
return $moduleFile
}
else {
Write-Error "Single module manifest file expected, none or more than 1 found."
return $null
}
}
# Get the module path based on scope and platform
function Get-PSModulePath {
param (
[Parameter(
Position = 0,
Mandatory = $True,
ValueFromPipeline = $False,
ValueFromPipelineByPropertyName = $False
)]
[ValidateSet("CurrentUser", "AllUsers")]
[string] $moduleScope
)
if ([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Windows)) {
if ($IsCoreCLR) {
$powerShellType = "PowerShell"
}
else {
$powerShellType = "WindowsPowerShell"
}
$localUserDir = Join-Path ([Environment]::GetFolderPath([Environment+SpecialFolder]::MyDocuments)) $powerShellType
$allUsersDir = Join-Path ([Environment]::GetFolderPath([Environment+SpecialFolder]::ProgramFiles)) $powerShellType
}
else {
# Paths are the same for both Linux and macOS
$localUserDir = Join-Path (Get-HomeFolder) ".local/share/powershell"
$allUsersDir = "/usr/local/share/powershell"
}
if ($moduleScope -eq "AllUsers") {
return $allUsersDir
}
else {
return $localUserDir
}
}
# Prompt user to select the module path from existing paths in the PSModulePath environment variable
function Select-PSModulePath {
$allModules = $env:PSModulePath -Split ';'
for ($i = 1; $i -le $allModules.Count; $i++) {
Write-Host "`t($i) .... $($allModules[$i-1])"
}
# confirm the repsonse is valid, if not return null.
try {
[Int32]$selection = Read-Host -Prompt "Select install path for module (1 to $($allModules.Count))"
if (($selection -gt 0) -and ($selection -le $allModules.Count)) {
return $allModules[$selection - 1]
}
else {
Write-Warning "Selection is out of range. Select from 1 to $($allModules.Count)."
return $null
}
}
catch {
Write-Warning "Select a number corresponding to the host to connect to (from 1 to $($allModules.Count))."
return $null
}
}
# Helper function to get home directory
function Get-HomeFolder {
$envHome = [System.Environment]::GetEnvironmentVariable("HOME") ?? $null
if ($null -ne $envHome) {
return $envHome
}
# Return an empty string in this case so the process working directory will be used.
else {
return ""
}
}
function Get-ModuleName {
$moduleManifestFile = Get-ModuleManifestFile
if ($null -ne $moduleManifestFile) {
return $moduleManifestFile.BaseName
}
return $null
}
# Prompt user to select modile if "PromptForModulePath" provided as the -Scope parameter, otherwise use AllUsers or CurrentUser path based on the parameter
# Note: -Scope defaults to CurrentUser if no paramter value provided.
if($scope -eq "PromptForModulePath") {
$moduleRootPath = Select-PSModulePath
}
else {
$moduleRootPath = Join-Path -Path (Get-PSModulePath -moduleScope $Scope) -ChildPath "Modules"
}
$moduleVersion = Get-ModuleVersion
$moduleName = Get-ModuleName
Write-Verbose "Module name:`t`t $($moduleName)"
Write-Verbose "Module path:`t`t $($moduleRootPath)"
Write-Verbose "Module version:`t $($moduleVersion)"
if (($null -ne $moduleVersion) -and ($null -ne $moduleRootPath) -and ($null -ne $moduleName)) {
# construct the module path ($env:psmodulepath\modulename\version)
$destinationPath = Join-Path -Path $moduleRootPath -ChildPath $moduleName -AdditionalChildPath $moduleVersion
# create the folder if it does not already exist
if (!(Test-Path -Path $destinationPath)) {
Write-Verbose "Creating folder $destinationPath"
try {
New-Item $destinationPath -ItemType Directory -ErrorAction Stop| Out-Null
}
catch {
Write-Error "Unable to create directory $destinationPath. Use -Debug switch for details"
Write-Debug $_.Exception
exit
}
}
# copy all files, exclude dot folders (e.g. .git)
Write-Host "Installing module to $destinationPath"
try {
Copy-Item -Path (Join-Path -Path (Get-Location).Path -ChildPath '*') -Recurse -Destination $destinationPath.ToString() -Exclude '.*','images' -Force -ErrorAction Stop
}
catch {
Write-Error "Unable to copy files to $destinationPath. Use -Debug switch for details"
Write-Debug $_.Exception
exit
}
}