79758122

Date: 2025-09-07 13:00:25
Score: 0.5
Natty:
Report link

Building on @Daniel's approach.... a helper function like this:

function Get-ModuleInventory {
    param (
        [Parameter(Mandatory = $true)] [scriptblock] $ScriptBlock
    )

    # Find all commands in this script
    $cmdlets = $ScriptBlock.Ast.FindAll( { $args[0] -is [System.Management.Automation.Language.CommandAst] }, $true) | ForEach-Object{
        Write-Output $_.CommandElements[0].Value
    }

    $cmdlets | Select-Object -Unique | Get-Command | Where-Object {$_.Source} | Sort-Object -Property Source | Group-Object -Property Source | ForEach-Object {
        
        if($module = Get-Module $_.Name) {
            [PSCustomObject]@{
                ModuleName = $module.Name
                ModuleVersion = $module.Version.ToString()
                ModulePath = $module.Path
                ModuleCommandsUsed = $_.Group.Name
            } | Write-Output
        }
    }
}

can be called from a script like this:

$modulesUsed = Get-ModuleInventory -ScriptBlock $MyInvocation.MyCommand.ScriptBlock
Write-Host "### BEGIN MODULE MANIFEST"
$modulesUsed | ConvertTo-Json | Write-Host
Write-Host "### END MODULE MANIFEST`r`n"

which will produce a handy list of the modules used (including version and whether the module was installed for all users or just the current user. This is handy if you're trying to understand, for example, why a script runs from a dev workstation but not as a scheduled task on a job server.

  {
    "ModuleName": "Az.Resources",
    "ModuleVersion": "8.0.1",
    "ModulePath": "C:\\Users\\xxx\\Documents\\PowerShell\\Modules\\Az.Resources\\8.0.1\\Az.Resources.psm1",
    "ModuleCommandsUsed": [
      "Get-AzResourceProvider",
      "Get-AzResourceGroup",
      "Get-AzResource"
    ]
  },
  {
    "ModuleName": "Microsoft.PowerShell.Management",
    "ModuleVersion": "7.0.0.0",
    "ModulePath": "C:\\program files\\powershell\\7\\Modules\\Microsoft.PowerShell.Management\\Microsoft.PowerShell.Management.psd1",
    "ModuleCommandsUsed": "Split-Path"
  },
Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Daniel's
  • Low reputation (1):
Posted by: user594102