Noveris.ModuleMgmt.psm1

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
<#
#>


########
# Global settings
$InformationPreference = "Continue"
$ErrorActionPreference = "Stop"
Set-StrictMode -Version 2

<#
#>

Function Select-ModuleVersionMatches
{
    [OutputType("System.String")]
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Version,

        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [int]$Major = -1,

        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [int]$Minor = -1,

        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [int]$Patch = -1,

        [Parameter(Mandatory=$false)]
        [switch]$StrictParse = $false
    )

    process
    {
        try {
            Write-Verbose "Parsing version $Version"
            $parsed = [Version]::Parse($Version)

            if ($Major -ge 0 -and $parsed.Major -ne $Major)
            {
                return
            }

            if ($Minor -ge 0 -and $parsed.Minor -ne $Minor)
            {
                return
            }

            if ($Patch -ge 0 -and $parsed.Build -ne $Patch)
            {
                return
            }

            $Version
        } catch {
            if ($StrictParse)
            {
                Write-Error "Failed to parse version string: $Version"
            } else {
                Write-Warning "Failed to parse version string: $Version"
            }
        }
    }
}

<#
#>

Function Install-PSModuleWithSpec
{
    [CmdletBinding()]
    param(
        [Parameter(mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [int]$Major = -1,

        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [int]$Minor = -1,

        [Parameter(Mandatory=$false)]
        [ValidateNotNull()]
        [int]$Patch = -1,

        [Parameter(mandatory=$false)]
        [switch]$Offline = $false,

        [Parameter(Mandatory=$false)]
        [ValidateSet("CurrentUser", "AllUsers")]
        [string]$Scope = "CurrentUser"
    )

    process
    {
        # If not offline, install the latest version that matches the spec, if it doesn't exist locally
        if (!$Offline)
        {
            # Get the modules available online and filter by version spec
            $target = Find-Module -AllVersions -Name $Name |
                ForEach-Object { $_.Version.ToString() } |
                Select-ModuleVersionMatches -Major $Major -Minor $Minor -Patch $Patch |
                Select-Object -First 1
            Write-Verbose "Find module result: $target"

            # Get the local modules
            $installed = Get-Module -ListAvailable -Name $Name | ForEach-Object { $_.Version.ToString() }
            Write-Verbose ("Found local modules: " + ($installed -join ","))

            # If we found a match online, check if it is installed locally
            if (![string]::IsNullOrEmpty($target) -and ($null -eq $installed -or $installed -notcontains $target))
            {
                Write-Verbose "Installing module $Name version $target"
                Install-Module -Name $Name -RequiredVersion $target -Force -SkipPublisherCheck -Scope $Scope
            }
        }

        # Get the local modules and filter by spec
        $target = Get-Module -ListAvailable -Name $Name |
            ForEach-Object { $_.Version.ToString() } |
            Select-ModuleVersionMatches -Major $Major -Minor $Minor -Patch $Patch |
            Select-Object -First 1

        if ($null -eq $target)
        {
            Write-Error "Could not find suitable installed version for $Name"
        } else {
            # Return matching target version
            Write-Verbose "Found local module to import: $target"
            $target
        }
    }
}