Public/Get-PSUModule.ps1
function Get-PSUModule { <# .SYNOPSIS Detects the module based on .psd1 or .psm1 file existence. .DESCRIPTION Walks up the directory tree from the specified root (or $PSScriptRoot by default) until it finds a .psd1 or .psm1 file. Returns module metadata including name, version, and paths. Useful for dynamic module introspection and automation scenarios. .PARAMETER ScriptRoot (Optional) The path to start searching from. Defaults to $PSScriptRoot. .PARAMETER ScriptPath (Optional) A specific script file path to use as the starting point. If provided, its directory is used. .EXAMPLE $Module = Get-PSUModule Detects the module from the current script's root. .EXAMPLE Get-PSUModule -ScriptPath "C:\repos\OMG.PSUtilities\OMG.PSUtilities.Core\Public\SomeScript.ps1" Detects the module starting from a specific script file. .OUTPUTS [PSCustomObject] .NOTES Author: Lakshmanachari Panuganti Date: 22nd August 2025 .LINK https://github.com/lakshmanachari-panuganti/OMG.PSUtilities/tree/main/OMG.PSUtilities.Core https://www.linkedin.com/in/lakshmanachari-panuganti/ https://www.powershellgallery.com/packages/OMG.PSUtilities.Core #> [CmdletBinding()] param ( [Parameter(ParameterSetName = 'ByRoot')] [ValidateNotNullOrEmpty()] [ValidateScript({ if (-not (Test-Path $_ -PathType Container)) { throw "`nThe specified ScriptRoot '$_' does not exist or `n'It is not a directory'." } $true })] [string]$ScriptRoot = $PSScriptRoot, [Parameter(ParameterSetName = 'ByPath')] [ValidateNotNullOrEmpty()] [ValidateScript({ if (-not (Test-Path $_ -PathType Leaf)) { throw "`nThe specified ScriptPath '$_' does not exist or `n'It is not a file'." } $true })] [string]$ScriptPath ) try { $startPath = if ($PSCmdlet.ParameterSetName -eq 'ByPath' -and $ScriptPath) { Split-Path -Path $ScriptPath -Parent } else { $ScriptRoot } $currentPath = $startPath while ($currentPath -and (Test-Path $currentPath)) { $psd1 = Get-ChildItem -Path $currentPath -Filter '*.psd1' -ErrorAction SilentlyContinue | Select-Object -First 1 $psm1 = Get-ChildItem -Path $currentPath -Filter '*.psm1' -ErrorAction SilentlyContinue | Select-Object -First 1 if ($psd1 -or $psm1) { $parentModule = Split-Path -Path $currentPath -Parent | Split-Path -Leaf $currentVersion = $null if ($psd1) { try { $manifestData = Import-PowerShellDataFile -Path $psd1.FullName $currentVersion = $manifestData.ModuleVersion } catch {} } return [PSCustomObject]@{ ModuleName = (Split-Path -Path $currentPath -Leaf) Path = $currentPath ManifestPath = if ($psd1) { $psd1.FullName } else { $null } ModuleFilePath = if ($psm1) { $psm1.FullName } else { $null } HasManifest = [bool]$psd1 HasModuleFile = [bool]$psm1 ParentModule = $parentModule CurrentVersion = $currentVersion PSTypeName = 'PSU.Module.Data' } } # Walk up one level $currentPath = Split-Path -Path $currentPath -Parent } throw "No module manifest (.psd1) or module file (.psm1) found above '$startPath'. Ensure you are running inside a valid PowerShell module folder." } catch { $PSCmdlet.ThrowTerminatingError($_) } } |