Impossible de générer ParameterSetMetadata lors de la création Programmatically un bloc de paramètres

StackOverflow https://stackoverflow.com/questions/2466210

Question

Je suis en train de créer un programme bloc de paramètres pour une fonction (le long des lignes de ce billet de blog ).

Je commence avec un l'objet de CommandMetadata (à partir d'une fonction existante). Je peux créer ParameterMetadata objet et les choses Posé comme le ParameterType, le nom, ainsi que certains attributs.

Le problème que je suis en cours d'exécution en est que lorsque j'utilise le

Autres conseils

La raison pour laquelle il ne montre pas parce que votre NewParameter doit appartenir à au moins un jeu de paramètres. Dans ce cas, il devrait être membre du ParameterSet spécial, « __AllParameterSets. »

Vous pouvez vérifier cela en copiant l'instance ParameterSetMetadata de InitialParameter. Unfortuntely Je ne peux pas voir immédiatement comment obtenir ce ParameterSetMetadata si vous n'avez pas des paramètres pour la saisir de. il copie de l'autre paramètre fait apparaître dans la sortie, mais il est les métadonnées de InitialParameter, donc ce n'est pas la solution, seule la raison pour laquelle il ne fonctionne pas (encore). Je vais mettre à jour ce post quand je le figure out.

-Oisin

diatribe sur: J'étais même très, très en colère que l'on peut instancier un type de System.Management.Automation.ParameterMetadata mais nous ne pouvons pas initialisize il. Microsoft détruit une grande joie de la bibliothèque de classes par contraining les classes par l'utilisation de privé ou interne ou scellé ...... ils l'utilisent souvent, et sans aucune raison pensables. C'est un concept de bibliothèque très noix! tempêter off:

Pour metaprogramming et créer ProxyCommands (fonctions de proxy) J'ai eu la nécessité de créer un paramètre Windows PowerShell programatically à partir de zéro. Je n'aime même briser en classes et de voler et utiliser vorbidden choses, qui est sujet à changement. Même le truc de sérialisation est la même sale pour faire la même chose sur un itinéraire différent.

voici mon prototype d'une solution. Je crée une fonction avec un paramètre en tant que texte (fonction sourcecode). mon premier atempt était de faire un nouveau point Fonction: \ -value {code} dans le lecteur de fonction, puis faire un Get-Command à la nouvelle fonction pour extraire les métadonnées. Mais cela se voit, que la fonction était un sorcecode mort seulement cheval. Il n'a pas été obtenu compilé. Donc, je devais utiliser Invoke-Expression pour «la compilation du code source de la fonction.

Function New-Parameter {

    [CmdletBinding()]
    param(
        [Switch]$Mandatory,
        [UInt32]$Position,
        [Switch]$ValueFromPipeline,
        [Switch]$ValueFromPipelineByPropertyName,
        [Switch]$ValueFromRemainingArguments,
        [String]$HelpMessage,

        [Type]$Type=[Type]'System.Management.Automation.SwitchParameter',
        [Parameter(Mandatory=$True)]
        [String]$Name,
        [String]$DefaultValue,

        [Switch]$DontShow,

        [String[]]$ParameterSetName,
        [String[]]$Aliases,
        # if Metadata is present the result is an System.Management.Automation.ParameterMetadata object
        # If Metadata is absent the sourcecode for the Parameter is returned
        [Switch]$Metadata
    )

    $ParameterAttrib = [System.Collections.ArrayList]@()

    # using GUID to create an unique function Name
    $Guid = ([Guid]::NewGuid()).ToString()

    # using a StringBuilder to glue the sourcecode 
    $stringBuilder = New-Object System.Text.StringBuilder

        If($Metadata.IsPresent) {

        # Open the Function{} block
        [Void]$stringBuilder.AppendLine("Function $Guid {")

        # add the [CmdletBinding()] attribute 
        [Void]$stringBuilder.AppendLine("[CmdletBinding()]")

        # Open the Param() block
        [Void]$stringBuilder.AppendLine("param(")
    } 

    # query if we have one or more ParameterSetName
    $ParmameterSetNameCount = 0
    If(-not [String]::IsNullOrEmpty($ParameterSetName)) {
        $ParmameterSetNameCount = @($ParameterSetName).Count
    } 

    # Open the [Parameter()] attribut
    [Void]$stringBuilder.Append('[Parameter(')

    If($Mandatory.IsPresent) {
        [Void]$ParameterAttrib.Add('Mandatory=$True')
    }
    If($Position) {
        [Void]$ParameterAttrib.Add("Position=$Position")
    }
    If($ParmameterSetNameCount -gt 0){
            # in the first full blown [Parameter()] attribut allways insert the first ParametersetName
            [Void]$ParameterAttrib.Add("ParameterSetName='$($ParameterSetName[0])'")  
    }


    If($ValueFromPipeline.IsPresent) {
        [Void]$ParameterAttrib.Add('ValueFromPipeline=$True')
    }
    If($ValueFromPipelineByPropertyName.IsPresent) {
        [Void]$ParameterAttrib.Add('ValueFromPipelineByPropertyName=$True')
    }
    If($ValueFromRemainingArguments.IsPresent) {
        [Void]$ParameterAttrib.Add('ValueFromRemainingArguments=$True')
    }
    If($DontShow.IsPresent) {
        If($PSVersionTable.PSVersion.Major -lt 4) {
            Write-Warning "The 'DontShow' attribute requires PowerShell 4.0 or above! `n Supressing the 'DontShow' attribute!"
        } Else {
            [Void]$ParameterAttrib.Add('DontShow')
        }

    }
    If(-not [String]::IsNullOrEmpty($HelpMessage)) {
        [Void]$ParameterAttrib.Add("HelpMessage='$HelpMessage'")
    }

    # generate comma separated list from array
    [Void]$stringBuilder.Append("$($ParameterAttrib -Join ',')")

    $ParameterAttrib.Clear()

    # close the [Parameter()] attribut
    [Void]$stringBuilder.AppendLine(")]")
    $ParmameterSetLoopCounter++

    # If we have more then one ParametersetName
    IF($ParmameterSetNameCount -gt 1) {
        # add remaining parameterset names the parameter belongs to
        for ($i = 1; $i -lt $ParmameterSetNameCount; $i++) { 
            [Void]$stringBuilder.AppendLine("[Parameter(ParameterSetName='$($ParameterSetName[$i])')]")  
        }  
    }

    # Create Alias Attribute from Aliases
    If(-not [String]::IsNullOrEmpty($Aliases)) {
        [Void]$stringBuilder.AppendLine("[Alias('$($Aliases -join "','")')]")
    }

    # add Parameter Type
    [Void]$stringBuilder.Append("[$($Type.Fullname)]")

    # add the Parameter Name
    [Void]$stringBuilder.Append("`$$Name")

        If(-not [String]::IsNullOrEmpty($ParameterSetName)) {
        [Void]$stringBuilder.Append("=$DefaultValue")
        }

    If($Metadata.IsPresent) {
        # close the Param() block
        [Void]$stringBuilder.AppendLine()
        [Void]$stringBuilder.AppendLine(')')

        # close the Function block
        [Void]$stringBuilder.AppendLine('}')
    }

    # return the result
    If($Metadata.IsPresent) {
        # if we have to return a ParameterMetadata Object we create a temporary function
        # because you can instatiate a ParameterMetadata Object but most of the Properties are constrained to get only and not to set!

        # Create and 'compile' the function into the function: drive
        Invoke-Expression ($stringBuilder.ToString())

        # from the temporary function we query the the ParameterMetadata and
        # return theParameterMetadata Object
        (Get-Command -Name $Guid -CommandType Function).Parameters.$Name

        # remove the Function from Function: drive
        $Null = Remove-Item Function:\$Guid -Force

    } Else {
        # return the sourcecode of the Parameter
        Write-Output $stringBuilder.ToString()
    }

}

#Example calls:

# without Parametersets
New-Parameter -Name 'Param1' -Mandatory -Position 3 -ValueFromPipeline -ValueFromPipelineByPropertyName -ValueFromRemainingArguments -HelpMessage "Give me hope Joana!" -Type 'System.String' -Aliases 'Ali1','Ali2','Ali3' -DontShow -DefaultValue 34
New-Parameter -Name 'Param1' -Mandatory -Position 3 -ValueFromPipeline -ValueFromPipelineByPropertyName -ValueFromRemainingArguments -HelpMessage "Give me hope Joana!" -Type 'System.String' -Aliases 'Ali1','Ali2','Ali3' -DontShow -DefaultValue 34 -Metadata

# with Parametersets
New-Parameter -Name 'Param1' -Mandatory -Position 3 -ValueFromPipeline -ValueFromPipelineByPropertyName -ValueFromRemainingArguments -HelpMessage "Give me hope Joana!" -Type 'System.String' -ParameterSetName 'Snover','Payette' -Aliases 'Ali1','Ali2','Ali3' -DontShow -DefaultValue 34
New-Parameter -Name 'Param1' -Mandatory -Position 3 -ValueFromPipeline -ValueFromPipelineByPropertyName -ValueFromRemainingArguments -HelpMessage "Give me hope Joana!" -Type 'System.String' -ParameterSetName 'Snover','Payette' -Aliases 'Ali1','Ali2','Ali3' -DontShow -DefaultValue 34 -Metadata

que je fais DROIT DE CONSTRUIRE LES PARAMETERSETS?

scroll top