.temp_commit_revert/UserAdminModule-6383df066ad425f1fcb580c09aa46e3edd8eeea2/Public/Import-PersonalModules.ps1
|
#requires -Version 5.1 <# .SYNOPSIS Imports PowerShell submodules by category name, with dynamic tab-completion. .DESCRIPTION Discovers available categories at runtime by scanning the UserAdminModule installation directory for built-in submodules and any configured custom modules path for user-created submodules. A folder qualifies as a submodule if it contains a .psm1 file whose name matches the folder name. Tab-completion for -Category is built dynamically from what actually exists — no configuration is needed when new submodules are added. Configure a custom modules path first with Initialize-UserAdminModule. Reference: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/import-module .PARAMETER Category One or more category names to import. Tab-completes dynamically from all discovered submodules (both built-in and custom). Accepts multiple values. .EXAMPLE Import-PersonalModules -Category Shell Imports the built-in Shell submodule. .EXAMPLE Import-PersonalModules -Category ADFunctions, Exchange Imports multiple built-in categories in one call. .EXAMPLE Import-PersonalModules -Category MyScripts -Verbose Imports a user-created custom category with verbose timing output. .EXAMPLE Import-PersonalModules -Category HomeLabTools -WhatIf Shows what would be imported without making any changes. .NOTES Author: Luke Leigh Tested on: PowerShell 5.1 and 7+ Reference: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/import-module .LINK Initialize-UserAdminModule Invoke-PersonalModulesMenu New-PSM1Module Get-UserAdminModuleConfig #> function Import-PersonalModules { [CmdletBinding(SupportsShouldProcess)] param() DynamicParam { # --- Discover built-in submodules from the module root --- # Use $script:UAMModuleRoot (set by UserAdminModule.psm1) rather than $PSScriptRoot, # because this file lives in Public/ and $PSScriptRoot would point to Public/, not the module root. $_uamRoot = if ($Script:UAMModuleRoot) { $Script:UAMModuleRoot } else { Split-Path $PSScriptRoot -Parent } $discovered = [System.Collections.Generic.List[string]]::new() if (Test-Path $_uamRoot) { Get-ChildItem -Path $_uamRoot -Directory -ErrorAction SilentlyContinue | Where-Object { Test-Path (Join-Path $_.FullName "$($_.Name).psm1") } | ForEach-Object { $discovered.Add($_.Name) } } # --- Discover custom submodules from config --- $cfg = if (Get-Command Get-UserAdminModuleConfig -ErrorAction SilentlyContinue) { Get-UserAdminModuleConfig -ErrorAction SilentlyContinue } if ($cfg -and $cfg.CustomModulesPath -and (Test-Path $cfg.CustomModulesPath)) { Get-ChildItem -Path $cfg.CustomModulesPath -Directory -ErrorAction SilentlyContinue | Where-Object { Test-Path (Join-Path $_.FullName "$($_.Name).psm1") } | ForEach-Object { if (-not $discovered.Contains($_.Name)) { $discovered.Add($_.Name) } } } $allCategories = ($discovered | Sort-Object) # --- Build dynamic -Category parameter --- $attrCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $paramAttr = New-Object System.Management.Automation.ParameterAttribute $paramAttr.Mandatory = $true $paramAttr.HelpMessage = 'Category name to import. Tab-completes from all discovered submodules.' $attrCollection.Add($paramAttr) if ($allCategories.Count -gt 0) { $validateSet = New-Object System.Management.Automation.ValidateSetAttribute( [string[]]$allCategories ) $attrCollection.Add($validateSet) } $dynParam = New-Object System.Management.Automation.RuntimeDefinedParameter( 'Category', [string[]], $attrCollection ) $paramDict = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDict.Add('Category', $dynParam) return $paramDict } begin { trap { Write-Error "Failed to initialise Import-PersonalModules: $_" break } $Category = $PSBoundParameters['Category'] # --- Build category -> psm1 path map --- $moduleMap = @{} # Built-in submodules (discovered from module root) $_uamRoot = if ($Script:UAMModuleRoot) { $Script:UAMModuleRoot } else { Split-Path $PSScriptRoot -Parent } if (Test-Path $_uamRoot) { Get-ChildItem -Path $_uamRoot -Directory -ErrorAction SilentlyContinue | Where-Object { Test-Path (Join-Path $_.FullName "$($_.Name).psm1") } | ForEach-Object { $moduleMap[$_.Name] = Join-Path $_.FullName "$($_.Name).psm1" } } # Custom $cfg = if (Get-Command Get-UserAdminModuleConfig -ErrorAction SilentlyContinue) { Get-UserAdminModuleConfig -ErrorAction SilentlyContinue } if ($cfg -and $cfg.CustomModulesPath -and (Test-Path $cfg.CustomModulesPath)) { Get-ChildItem -Path $cfg.CustomModulesPath -Directory -ErrorAction SilentlyContinue | Where-Object { Test-Path (Join-Path $_.FullName "$($_.Name).psm1") } | ForEach-Object { if (-not $moduleMap.ContainsKey($_.Name)) { $moduleMap[$_.Name] = Join-Path $_.FullName "$($_.Name).psm1" } } } $timingResults = @() } process { trap { Write-Error "Failed to import category: $_" continue } foreach ($cat in $Category) { if (-not $moduleMap.ContainsKey($cat)) { Write-Warning "Category '$($cat)' was not found on disk. Run Initialize-UserAdminModule to configure a custom modules path, or use New-PSM1Module to scaffold a new submodule." continue } $modulePath = $moduleMap[$cat] if ($PSCmdlet.ShouldProcess($modulePath, 'Import-Module')) { $start = Get-Date Write-Verbose "Importing '$($cat)' from: $($modulePath)" Import-Module -Name $modulePath -Force -DisableNameChecking -ErrorAction SilentlyContinue $duration = (Get-Date) - $start $timingResults += [PSCustomObject]@{ Category = $cat Path = $modulePath Duration = "$([math]::Round($duration.TotalSeconds, 2))s" } Write-Verbose "Imported '$($cat)' in $([math]::Round($duration.TotalSeconds, 2))s" } } } end { trap { Write-Error "Failed in Import-PersonalModules end block: $_" continue } if ($PSBoundParameters.ContainsKey('Verbose') -and $timingResults.Count -gt 0) { $timingResults | Format-Table -AutoSize } Write-Verbose 'Import-PersonalModules completed.' } } |