Public/Import-OriAzBopPsModule.ps1
<#
.SYNOPSIS Installs a PowerShell module from an online gallery and returns its dependency tree. .DESCRIPTION This cmdlet facilitates the installation of PowerShell modules from an online gallery. It performs the following actions: 1. Verifies if the required module is already loaded with the specified version or higher. 2. If not, it attempts to import the required version from installed modules. 3. If the module is still not loaded or missing (i.e., not installed), it proceeds to install it. 4. Checks prerequisites, such as the PowerShell version, PackageManager version, and others. 5. Installs any necessary tools as needed. 6. Registers the required repository if it isn't already registered. 7. Installs the specified module from the online gallery. 8. Loads the required version of the module. After completion, the cmdlet returns the dependency tree of the installed module. .PARAMETER DevOpsAccount Specifies the name of the DevOps account. The default value is 'oriflame'. .PARAMETER RegisterPsRepoFeedList A list of PowerShell repository feeds to register if needed. .PARAMETER RegisterNugetRepoFeedList A list of NuGet repository feeds to register if needed. .PARAMETER Name Specifies the name of the module(s) to install from the online gallery. The provided name(s) must match the exact module name(s) in the repository. .PARAMETER Repository The repository feed to use for retrieving PowerShell modules. Registers the repository if necessary. .PARAMETER Guid Specifies the exact GUID of the module. .PARAMETER MaximumVersion Specifies the maximum acceptable version of the module. .PARAMETER RequiredVersion Specifies the exact required version of the module. If not provided, the latest version will be installed and loaded. .PARAMETER Version Specifies the minimum acceptable version of the module. .PARAMETER Credential Credentials to use for accessing the repository, if required. .PARAMETER SkipImport Skips the `Import-Module` step when specified. .PARAMETER Prefix Adds a prefix to the module name during the `Import-Module` step, if specified. .PARAMETER RegisterViaPSRepository Registers the repository using `Register-PSRepository` if specified. Otherwise, it uses `Register-PackageSource`. .PARAMETER SkipInstallCredProvider Skips the installation of the Credential Provider if specified. .PARAMETER SkipCriticalPathCheck Skips the critical path check if specified. .PARAMETER UseWarningMsgForCriticalPath Uses a warning message for the critical path if specified. .PARAMETER SleepInSec Specifies the time (in seconds) to wait between checks for module readiness before importing. .PARAMETER MaxRetry Specifies the maximum number of retries while waiting for the module to become ready for import. .PARAMETER Proxy Specifies a proxy to use when accessing the repository, if required. .PARAMETER ProxyCredential Provides credentials to authenticate with the proxy, if required. .EXAMPLE $password = ConvertTo-SecureString 'xbchuuuuhaaaatest' -AsPlainText -Force $RepositoryCredential = New-Object System.Management.Automation.PSCredential 'feafeafae@mydomain.net',$password Import-OriAzBopPsModule ` -Name OriAzEncEnvironmentConfiguration ` -RequiredVersion 1.0.48 ` -Credential $RepositoryCredential .EXAMPLE $password = ConvertTo-SecureString 'xbchuuuuhaaaatest' -AsPlainText -Force $RepositoryCredential = New-Object System.Management.Automation.PSCredential 'feafeafae@mydomain.net',$password Import-OriAzBopPsModule ` -Name OriAzEncEnvironmentConfiguration ` -RequiredVersion 1.0.48 ` -Credential $RepositoryCredential ` -Proxy 'http://myproxy:8080' #> function Import-OriAzBopPsModule { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingInvokeExpression', '', Justification = "There's required use the re-execute code.")] [CmdLetBinding()] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false, HelpMessage = "The name of the dev ops account")] [String] $DevOpsAccount = $Script:VstsAccount, [Parameter(Mandatory = $true, HelpMessage = "Exact name of the module")] [String] $Name, [Parameter(Mandatory = $false, HelpMessage = "Powershell Repository feed to register if needed")] [String[]] $RegisterPsRepoFeedList = @('PackageManagementFeed'), [Parameter(Mandatory = $false, HelpMessage = "Nuget Repository feed to register if needed")] [String[]] $RegisterNugetRepoFeedList = @('DeploymentPackages'), [Parameter(Mandatory = $false, HelpMessage = "Repository feed to register if needed for getting powershell modules")] [String] $Repository = 'PackageManagementFeed', [Parameter(Mandatory = $false, HelpMessage = "GUID of the module")] [string] $Guid, [Parameter(Mandatory = $false, HelpMessage = "Maximum module version")] [Version] $MaximumVersion, [Parameter(Mandatory = $false, HelpMessage = "Required module version")] [Version] $RequiredVersion, [Alias("Version")] [Parameter(Mandatory = $false, HelpMessage = "Most likely minimum module version")] [Version] $MinimumVersion, [Parameter(Mandatory = $false, HelpMessage = "Repository Credential if needed")] [PSCredential] $Credential = $null, [Parameter(Mandatory = $false, HelpMessage = "When is set import-module will be skipped.")] [switch] $SkipImport, [Parameter(Mandatory = $False, HelpMessage = "When is set the Prefix is used while the Import-Module function as switch parameter")] [String] $Prefix, [Parameter(Mandatory = $false, HelpMessage = "When is set register via Register-PSRepository, otherwise use Register-PackageSource.")] [switch] $RegisterViaPSRepository, [Parameter(Mandatory = $false, HelpMessage = "When is set Installation of Credential provider will be skipped.")] [switch] $SkipInstallCredProvider, [Parameter(Mandatory = $false, HelpMessage = "When is set skip critical path check.")] [switch] $SkipCriticalPathCheck, [Parameter(Mandatory = $false, HelpMessage = "When is set use warning message for critical path.")] [switch] $UseWarningMsgForCriticalPath, [Parameter(Mandatory = $false, HelpMessage = "Use it when is required to use proxy while accessing the repository")] [Uri] $Proxy = $null, [Parameter(Mandatory = $false, HelpMessage = "Use it when is required to use proxy with credential")] [PSCredential] $ProxyCredential = $null, [Parameter(Mandatory = $False, HelpMessage = "Sleep time in sec between test if the module is ready to import.")] [int] $SleepInSec = 10, [Parameter(Mandatory = $False, HelpMessage = "Max retry")] [int] $MaxRetry = 20 ) $ErrorActionPreference = 'Stop' Write-Verbose -Message ("[ START: {0}:{1} (v.{2}) ]" -f $Local:MyInvocation.MyCommand.Source, $Local:MyInvocation.MyCommand.Name, $Local:MyInvocation.MyCommand.Version) foreach ($arg in $PSBoundParameters.GetEnumerator()) { if ([string]::IsNullOrEmpty($arg.Value)) { Write-Debug -Message ("[null] {0}: {1}" -f $arg.Key, $arg.Value) -ErrorAction SilentlyContinue } else { Write-Debug -Message ("[{2}] {0}: {1}" -f $arg.Key, $arg.Value, $arg.Value.GetType().Name) -ErrorAction SilentlyContinue } } # Required module is already imported if (-not($SkipImport.IsPresent) -and (Test-GetModule -Name $Name -RequiredVersion $RequiredVersion)) { Write-Debug "Module $Name is already imported." return } # Check if the $SkipCriticalPathCheck is set if (-not($SkipCriticalPathCheck.IsPresent)) { [string] $mutexName = 'Global\OriAzBopCriticalPathMutex' [System.Threading.Mutex] $mutex = [System.Threading.Mutex]::new($false, $mutexName) [int] $threadID = [System.Threading.Thread]::CurrentThread.ManagedThreadId if ($UseWarningMsgForCriticalPath.IsPresent) { Write-Warning "[$threadID]: Waiting to enter critical path..." } else { Write-Verbose "[$threadID]: Waiting to enter critical path..." } try { # Try to get the mutex $mutex.WaitOne() | Out-Null if ($UseWarningMsgForCriticalPath.IsPresent) { Write-Warning "[$threadID]: Entered critical path." } else { Write-Verbose "[$threadID]: Entered critical path." } [PSCustomObject] $DependencyMap = Import-OriAzBopPsModuleWithoutCriticalPath ` -DevOpsAccount $DevOpsAccount ` -Name $Name ` -RegisterPsRepoFeedList $RegisterPsRepoFeedList ` -RegisterNugetRepoFeedList $RegisterNugetRepoFeedList ` -Repository $Repository ` -Guid $Guid ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion ` -MinimumVersion $MinimumVersion ` -Credential $Credential ` -SkipImport:$SkipImport ` -Prefix $Prefix ` -RegisterViaPSRepository:$RegisterViaPSRepository ` -SkipInstallCredProvider:$SkipInstallCredProvider ` -Proxy $Proxy ` -ProxyCredential $ProxyCredential ` -SleepInSec $SleepInSec ` -MaxRetry $MaxRetry ` -Verbose:$VerbosePreference ` -Debug:$DebugPreference if ($UseWarningMsgForCriticalPath.IsPresent) { Write-Warning "[$threadID]: Leaving critical path." } else { Write-Verbose "[$threadID]: Leaving critical path." } } finally { # Release of the Mutex $mutex.ReleaseMutex() $mutex.Dispose() if ($UseWarningMsgForCriticalPath.IsPresent) { Write-Warning "[$threadID]: Exited critical path." } else { Write-Verbose "[$threadID]: Exited critical path." } } } else { Write-Verbose "Skip of critical path check." [PSCustomObject] $DependencyMap = Import-OriAzBopPsModuleWithoutCriticalPath ` -DevOpsAccount $DevOpsAccount ` -Name $Name ` -RegisterPsRepoFeedList $RegisterPsRepoFeedList ` -RegisterNugetRepoFeedList $RegisterNugetRepoFeedList ` -Repository $Repository ` -Guid $Guid ` -MaximumVersion $MaximumVersion ` -RequiredVersion $RequiredVersion ` -MinimumVersion $MinimumVersion ` -Credential $Credential ` -SkipImport:$SkipImport ` -Prefix $Prefix ` -RegisterViaPSRepository:$RegisterViaPSRepository ` -SkipInstallCredProvider:$SkipInstallCredProvider ` -Proxy $Proxy ` -ProxyCredential $ProxyCredential ` -SleepInSec $SleepInSec ` -MaxRetry $MaxRetry ` -Verbose:$VerbosePreference ` -Debug:$DebugPreference } Write-Verbose -Message ("[ END: {0} ]" -f $Local:MyInvocation.MyCommand.Name) return $DependencyMap } |