forked from szymonos/ps-modules
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodule_manage.ps1
executable file
·176 lines (163 loc) · 6.49 KB
/
module_manage.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
#!/usr/bin/pwsh -nop
#Requires -Version 7.0
#Requires -Module Microsoft.PowerShell.PSResourceGet
<#
.SYNOPSIS
Manage PowerShell modules.
.DESCRIPTION
Script for installing, removing or scaffolding new PowerShell modules.
If script is running elevated, it automatically install/delete module in AllUsers scope.
.PARAMETER Module
Module name.
.PARAMETER CleanUp
Switch, whether to clean up module previous versions in destination folder.
.PARAMETER RemoveRequirements
Switch, whether to remove requirements from the manifest file to speed up module loading.
.PARAMETER Force
Force reinstalling module even if current version is already installed.
.PARAMETER Delete
Switch, whether to delete an existing module.
.PARAMETER Create
Switch, whether to scaffold a new module manifest.
.EXAMPLE
# *module
$Module = 'aliases-git'
$Module = 'aliases-kubectl'
$Module = 'do-az'
$Module = 'do-common'
$Module = 'do-linux'
$Module = 'do-win'
# *install
./module_manage.ps1 $Module -CleanUp -Verbose
./module_manage.ps1 $Module -CleanUp -Verbose -Scope CurrentUser
./module_manage.ps1 $Module -CleanUp -Verbose -Force
./module_manage.ps1 $Module -CleanUp -RemoveRequirements -Verbose
@('aliases-git', 'aliases-kubectl') | ./module_manage.ps1 -CleanUp -Verbose
# *delete module
./module_manage.ps1 $Module -Delete -Verbose
# *scaffold module manifest
./module_manage.ps1 -Module 'do-test' -Create -Verbose
#>
[CmdletBinding(DefaultParameterSetName = 'Install')]
param (
[Parameter(Mandatory, ValueFromPipeline, Position = 0)]
[string]$Module,
[Parameter(ParameterSetName = 'Install')]
[switch]$CleanUp,
[Parameter(ParameterSetName = 'Install')]
[switch]$RemoveRequirements,
[Parameter(ParameterSetName = 'Install')]
[ValidateSet('AllUsers', 'CurrentUser')]
[string]$Scope,
[Parameter(ParameterSetName = 'Install')]
[switch]$Force,
[Parameter(ParameterSetName = 'Delete')]
[switch]$Delete,
[Parameter(ParameterSetName = 'Create')]
[switch]$Create
)
begin {
$ErrorActionPreference = 'Stop'
# set location to workspace folder
Push-Location $PSScriptRoot
# load do-common module
Import-Module (Resolve-Path 'modules/do-common')
}
process {
switch -Regex ($PsCmdlet.ParameterSetName) {
'Install|Create' {
# calculate source paths
$srcModulePath = [IO.Path]::Combine('modules', $Module)
$srcModuleManifest = [IO.Path]::Combine($srcModulePath, "$Module.psd1")
}
Install {
# *install modules
# calculate destination path determined on the Scope
$isAdmin = Test-IsAdmin
if ($Scope) {
if (-not $isAdmin -and $Scope -eq 'AllUsers') {
Write-Error "Cannot install `"$Module`" module to the AllUsers scope. Run the script as Admin."
}
} else {
$Scope = $isAdmin ? 'AllUsers' : 'CurrentUser'
}
$psModPathSplit = $env:PSModulePath.Split([IO.Path]::PathSeparator)
$psModPath = switch ($Scope) {
AllUsers {
$psModPathSplit[1]
}
CurrentUser {
$psModPathSplit[0]
}
}
$dstModulePath = [IO.Path]::Combine($psModPath, $Module)
# check if module exists
if (-not (Test-Path $srcModuleManifest)) {
Write-Warning "Module doesn't exist ($Module)."
exit
}
# get module manifest
try {
$manifest = Test-ModuleManifest $srcModuleManifest -ErrorAction Stop
} catch [IO.DirectoryNotFoundException] {
# install missing required modules
$manifest = Test-ModuleManifest $srcModuleManifest -ErrorAction SilentlyContinue
foreach ($mod in $manifest.RequiredModules.Name) {
if (-not (Get-Module -ListAvailable $mod)) {
Install-PSResource $mod -WarningAction SilentlyContinue
}
}
} catch {
Write-Verbose $_.Exception.GetType().FullName
Write-Error $_
break
}
$installPath = [IO.Path]::Combine($dstModulePath, $manifest.Version)
# create/cleanup destination directory
if (-not $Force -and ($manifest.Version -eq (Get-Module $Module -ListAvailable).Version)) {
Write-Verbose "Current module version already installed in the $Scope scope ($Module v$($manifest.Version))."
} else {
# clean-up old module versions
if ($CleanUp -and (Test-Path $dstModulePath -PathType Container)) {
Remove-Item ([IO.Path]::Combine($dstModulePath, '*')) -Recurse -Force
}
New-Item -ItemType Directory -Force -Path $installPath | Out-Null
# copy module files
Copy-Item -Path ([IO.Path]::Combine($manifest.ModuleBase, '*')) -Destination $installPath -Recurse
# remove requirements from module manifest to speed up module loading time
if ($RemoveRequirements) {
$dstModuleManifest = [IO.Path]::Combine($installPath, "$Module.psd1")
[IO.File]::WriteAllText($dstModuleManifest, [IO.File]::ReadAllText($dstModuleManifest) -replace '(?s)RequiredModules.*?\)\n')
}
Write-Verbose "Module $Module v$($manifest.Version) installed in the $Scope scope."
}
continue
}
Create {
# *scaffold new module manifest
if (-not (Test-Path -Path $srcModulePath -PathType Container)) {
New-Item -Path $srcModulePath -ItemType Directory | Out-Null
}
New-ModuleManifest -Path $srcModuleManifest
Write-Verbose "Created module manifest in $($srcModuleManifest.Replace($HOME, '~'))"
continue
}
Delete {
# *delete modules
$modules = Get-Module $Module -ListAvailable
if ($modules) {
Write-Verbose "uninstalling module ($Module)"
foreach ($mod in $modules) {
Write-Verbose " - $($mod.Version)"
Remove-Item -Path $mod.ModuleBase -Force -Recurse -ErrorAction SilentlyContinue
}
} else {
Write-Verbose "Module do not exists ($Module)."
}
continue
}
}
}
end {
Pop-Location
}