2017-03-06 1 views
2

Je suis en train d'écrire un script qui doit être détecter ce que le ArgumentList d'un module PowerShell est. Y a-t-il un moyen de le découvrir?Comment puis-je savoir ArgumentList d'un module de PowerShell?

Le jeu final est de pouvoir l'utiliser pour créer un conteneur simple DI pour les modules de chargement.

+1

En relation: [Présentation d'un module Windows PowerShell] (https://msdn.microsoft.com/fr-fr/library/dd878324 (v = vs.85) .aspx) et/ou [_Utilisez le PowerShell Get-Command cmdlet à Trouver ensemble des paramètres information_] (https://blogs.technet.microsoft.com/heyscriptingguy/2012/05/16/use-the-get-command-powershell-cmdlet-to-find-parameter-set-information/) – JosefZ

+1

Que considérez-vous exactement de la « liste d'arguments d'un module de PowerShell »? Les modules n'ont généralement pas de paramètres, seuls les cmdlets qu'ils exposent le font. –

+1

Oui, ils ne les ont généralement pas mais peuvent les avoir. Cela nécessite juste une section param dans le fichier psm1. Avec les commandes et les fonctions, vous pouvez inspecter la propriété parameters à partir de Get-Command pour obtenir beaucoup d'informations. Il ne semble pas y avoir d'équivalent pour les paramètres du module –

Répondre

1

Vous pouvez utiliser l'analyseur AST pour vous montrer le bloc param() du fichier du module. Utilisez peut-être Get-Module pour trouver des informations sur l'emplacement des fichiers du module, puis analysez-les et parcourez l'AST pour obtenir les informations que vous recherchez. Est-ce que cela semble être quelque chose qui serait utile?

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 
} 

Vous devriez être en mesure de donner qu'un nom de module ou le chemin vers un module. Il a à peine été testé, il y a donc probablement des cas où cela ne fonctionnera pas. À l'heure actuelle, il retourne un dictionnaire comme l'affichage de la propriété 'Parameters' retournée par Get-Command. Si vous voulez l'information d'attribut, vous devriez faire un peu de travail pour construire chacun d'eux.