如何找到PowerShell模块的ArgumentList?

时间:2017-03-06 12:12:29

标签: powershell powershell-module

我正在尝试编写一个需要检测PowerShell模块的ArgumentList是什么的脚本。有没有办法找到这个?

最终游戏是能够使用它来创建一个简单的DI容器来加载模块。

1 个答案:

答案 0 :(得分:1)

您可以使用AST解析器向您显示模块文件的param()块。也许使用Get-Module来查找有关模块文件所在位置的信息,然后解析这些文件并遍历AST以获取您所需的信息。这看起来像是有用的吗?

function Get-ModuleParameterList {
    [CmdletBinding()]
    param(
        [string] $ModuleName
    )

    $GetModParams = @{
        Name = $ModuleName
    }

    # Files need -ListAvailable
    if (Test-Path $ModuleName -ErrorAction SilentlyContinue) {
        $GetModParams.ListAvailable = $true
    }

    $ModuleInfo = Get-Module @GetModParams | select -First 1 # You'll have to work out what to do if more than one module is found

    if ($null -eq $ModuleInfo) {
        Write-Error "Unable to find information for '${ModuleName}' module"
        return
    }

    $ParseErrors = $null
    $Ast = if ($ModuleInfo.RootModule) {
        $RootModule = '{0}\{1}' -f $ModuleInfo.ModuleBase, (Split-Path $ModuleInfo.RootModule -Leaf)

        if (-not (Test-Path $RootModule)) {
            Write-Error "Unable to determine RootModule for '${ModuleName}' module"
            return
        }

        [System.Management.Automation.Language.Parser]::ParseFile($RootModule, [ref] $null, [ref] $ParseErrors)
    }
    elseif ($ModuleInfo.Definition) {
        [System.Management.Automation.Language.Parser]::ParseInput($ModuleInfo.Definition, [ref] $null, [ref] $ParseErrors)
    }
    else {
        Write-Error "Unable to figure out module source for '${ModuleName}' module"
        return
    }

    if ($ParseErrors.Count -ne 0) {
        Write-Error "Parsing errors detected when reading RootModule: ${RootModule}"
        return
    }

    $ParamBlockAst = $Ast.Find({ $args[0] -is [System.Management.Automation.Language.ParamBlockAst] }, $false)

    $ParamDictionary = [ordered] @{}
    if ($ParamBlockAst) {
        foreach ($CurrentParam in $ParamBlockAst.Parameters) {
            $CurrentParamName = $CurrentParam.Name.VariablePath.UserPath
            $ParamDictionary[$CurrentParamName] = New-Object System.Management.Automation.ParameterMetadata (
                $CurrentParamName,
                $CurrentParam.StaticType
            )

            # At this point, you can add attributes to the ParameterMetaData instance based on the Attribute

        }
    }
    $ParamDictionary
}

您应该能够提供模块名称或模块的路径。它几乎没有经过测试,因此可能会出现一些不起作用的情况。现在,它返回一个字典,比如查看从Get-Command返回的'Parameters'属性。如果你想要属性信息,你需要做一些工作来构建每个属性。