PSRequiredModules.psm1
<#
.SYNOPSIS Get-RequiredModules .DESCRIPTION Read PSRequiredModules data from PowerShell module manifest. .PARAMETER ModuleFilePath Module file path expect a module file ending with .psd1 or .psm1 (to retrieve automatically associated .psd1) .EXAMPLE PS C:\> Get-RequiredModules -ModuleFilePath 'C:\MyModule\MyModule.psd1' .INPUTS System.String .OUTPUTS System.Boolean .NOTES Author: JDMSFT Date: 17/03/21 #> Function Get-RequiredModules { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ModuleFilePath ) Try { If ($ModuleFilePath -like '*.psm1' -or $ModuleFilePath -like '*.psd1') { $ManifestData = Import-LocalizedData -BaseDirectory (Split-Path $ModuleFilePath) -FileName (Split-Path $ModuleFilePath -Leaf) $ManifestData.PrivateData.PSRequiredModules } Else { Write-Warning "Please specify a valid module file path (ending with .psm1/.psd1)" } } Catch { Write-Output "[ERROR] $($_)`n[ERROR] [$($_.InvocationInfo.ScriptLineNumber)] $($_.InvocationInfo.ScriptName) >> $($_.InvocationInfo.Line.TrimStart())" } } <# .SYNOPSIS Import-RequiredModules .DESCRIPTION Read PSRequiredModules data from PowerShell module manifest. .PARAMETER ModuleFilePath Module file path expect a module file ending with .psd1 or .psm1 (to retrieve automatically associated .psd1) .PARAMETER AutoInstall Automatically install missing module from PowerShell environments .PARAMETER Details Return full state details isntead returning a boolean (usefull to troubleshoot) .EXAMPLE PS C:\> Import-RequiredModules -ModuleFilePath 'C:\MyModule\MyModule.psd1' Return if all required modules are imported in the PowerShell session. .EXAMPLE PS C:\> Import-RequiredModules -ModuleFilePath 'C:\MyModule\MyModule.psd1' -AutoInstall Install missing modules and return if all required modules are imported in the PowerShell session. .EXAMPLE PS C:\> Import-RequiredModules -ModuleFilePath 'C:\MyModule\MyModule.psd1' -Details Return all required modules states for the current PowerShell session instead returnin a boolean. .INPUTS System.String .OUTPUTS System.Boolean,Hastable .NOTES Author: JDMSFT Date: 17/03/21 #> Function Import-RequiredModules { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$ModuleFilePath, [switch]$AutoInstall, [switch]$Details ) Try { If ($ModuleFilePath -like '*.psm1' -or $ModuleFilePath -like '*.psd1') { $ModuleObject = @() $ManifestData = Import-LocalizedData -BaseDirectory (Split-Path $ModuleFilePath) -FileName (Split-Path $ModuleFilePath -Leaf) $ManifestData.PrivateData.PSRequiredModules.Keys | ForEach { $IsImported = $false $IsInstalled = $false $IsDownloadable = $null $Action = $null $State = $null # Get required version / prerelease $RequiredModuleName = $_ $RequiredModuleVersionSemVer = $ManifestData.PrivateData.PSRequiredModules.$_ If ($RequiredModuleVersionSemVer -like '*-*') { $PreReleaseVersion = $true $RequiredModuleVersion = ($RequiredModuleVersionSemVer -split '-')[0] $RequiredModulePrerelease = ($RequiredModuleVersionSemVer -split '-')[1] } Else { $PreReleaseVersion = $false $RequiredModuleVersion = $RequiredModuleVersionSemVer } # Checking for imported module version ... $MatchVersion = $false $RequiredModuleImportedMatches = Get-Module $RequiredModuleName If ($PreReleaseVersion) { Write-Verbose "Checking for imported module $RequiredModuleName v$RequiredModuleVersionSemVer... (prerelease)" $RequiredModuleImportedMatches | ForEach { If ($_.Version -eq $RequiredModuleVersion -and $_.PrivateData.PSData.Prerelease -eq $RequiredModulePrerelease) { Write-Verbose "Module $RequiredModuleName v$RequiredModuleVersionSemVer already imported !" $MatchVersion = $true $RequiredModule = $_ $IsImported = $true $IsInstalled = $true $State = 'OK' } } } Else { Write-Verbose "Checking for imported module $RequiredModuleName v$RequiredModuleVersionSemVer... (not prerelease)" $RequiredModuleImportedMatches | ForEach { If ($_.Version -eq $RequiredModuleVersion) { Write-Verbose "Module $RequiredModuleName v$RequiredModuleVersionSemVer already imported !" $MatchVersion = $true $RequiredModule = $_ $IsImported = $true $IsInstalled = $true $State = 'OK' } } } # Checking for installed module version ... $RequiredModuleInstalledMatches = Get-Module $RequiredModuleName -ListAvailable If ($MatchVersion -ne $true) { If ($PreReleaseVersion) { Write-Verbose "Checking for installed module $RequiredModuleName v$RequiredModuleVersionSemVer... (prerelease)" $RequiredModuleInstalledMatches | ForEach { If ($_.Version -eq $RequiredModuleVersion -and $_.PrivateData.PSData.Prerelease -eq $RequiredModulePrerelease) { Write-Verbose "Module $RequiredModuleName v$RequiredModuleVersionSemVer already installed !" $MatchVersion = $true $RequiredModule = $_ $IsInstalled = $true } } } Else { Write-Verbose "Checking for installed module $RequiredModuleName v$RequiredModuleVersionSemVer... (not prerelease)" $RequiredModuleInstalledMatches | ForEach { If ($_.Version -eq $RequiredModuleVersion) { Write-Verbose "Module $RequiredModuleName v$RequiredModuleVersionSemVer already installed !" $MatchVersion = $true $RequiredModule = $_ $IsInstalled = $true } } } # Module installed, importing ... If ($MatchVersion -eq $true) { Write-Verbose "Importing module $RequiredModuleName v$RequiredModuleVersionSemVer..." Import-Module $RequiredModule -Global $IsImported = $true $Action = 'AutoImport' If (Get-Module $RequiredModuleName) { $State = 'OK' } Else { $State = 'KO' } } # Module not installed, installing and importing ... Else { Write-Verbose "Module $RequiredModuleName v$RequiredModuleVersionSemVer not found." If (Find-Module -Name $RequiredModuleName -RequiredVersion $RequiredModuleVersionSemVer -Repository PSGallery -AllowPrerelease -ea SilentlyContinue) { $IsDownloadable = $true } Else { $IsDownloadable = $false } If ($AutoInstall) { If ($IsDownloadable) { $Action = 'AutoInstall' Install-Module -Name $RequiredModuleName -RequiredVersion $RequiredModuleVersionSemVer -Repository PSGallery -AllowPrerelease If (Get-InstalledModule -Name $RequiredModuleName -RequiredVersion $RequiredModuleVersionSemVer -AllowPrerelease -ea SilentlyContinue) { $IsInstalled = $true Import-Module -Name $RequiredModuleName -RequiredVersion $RequiredModuleVersion -Global } } Else { Write-Verbose "$RequiredModuleName can't be downloaded." } If (Get-Module $RequiredModuleName) { $State = 'OK' } Else { $State = 'KO' } } Else { Write-Verbose "Auto-install module disabled. Please installl required module manually prior using this module : Isntall-Module -Name $ModuleName -RequiredVersion $RequiredModuleVersionSemVer" ; $State = 'KO' } } } Else { Write-Verbose "" } $ModuleObject += [PSCustomObject]@{Name = $RequiredModuleName; Version = $RequiredModuleVersionSemVer; IsPrerelease = $PreReleaseVersion ; IsImported = $IsImported ; IsInstalled = $IsInstalled ; IsDownloadable = $IsDownloadable ; Action = $Action ; State = $State } } If ($Details) { $ModuleObject } Else { $ModuleObject.State -notcontains 'KO' } } Else { Write-Warning "Please specify a valid module file path (ending with .psm1/.psd1)" } } Catch { Write-Output "[ERROR] $($_)`n[ERROR] [$($_.InvocationInfo.ScriptLineNumber)] $($_.InvocationInfo.ScriptName) >> $($_.InvocationInfo.Line.TrimStart())" } } |