mayho33
Goto Top

Powershell dynamische Parameter ( DynamicParam ) verschachteln

Hallo @ All

Ich stehe wieder mal vor einem Problem mit Powershell das ich gerne umsetzen möchte.

In diesem Thread ( Powershell Parametersets und Auswahlmöglichkeiten ) hat mir colinardo (nochmals mein Dank dazu!) bereits mit super Beispielen und sogar einem 100% funktionierendem Snipped weiter geholfen. Jetzt bin ich auf den Geschmack gekommen und versuche seitdem dynamische Parameter zu verschachteln, sprich, wenn ein Parameter aus einem ParameterSet ausgewählt wurde, dass weitere Parameter angezeigt werden.

In etwa so wie in diesem Beispiel:

Function Start-Test() {
    [CmdletBinding()]
    param ([parameter(ParameterSetName="CREATEREGKEY")] [switch]$CreateRegistryKey)  

    DynamicParam{
    $attrCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute]
    $paramDic = new-object System.Management.Automation.RuntimeDefinedParameterDictionary
        if ($CreateRegistryKey) {
                $attr = new-object System.Management.Automation.ParameterAttribute
                $attr.ParameterSetName = "CREATEREGKEY" ; $attr.Mandatory = $false ; $attrCollection.Add($attr)  
                $paramDic.Add("HIVE", (new-object System.Management.Automation.RuntimeDefinedParameter("HIVE", [Array], $attrCollection)))  
                $paramDic.Add("Path", (new-object System.Management.Automation.RuntimeDefinedParameter("Path", [String], $attrCollection)))  
                $paramDic.Add("AsActiveSetup", (new-object System.Management.Automation.RuntimeDefinedParameter("AsActiveSetup", [String], $attrCollection)))  
                return $paramDic
        }
    }
}

Wählt man nun "CreateRegKey_AsActiveSetup" sollen noch zusätzliche Parameter auftauchen wie "StubPath", "ComponentID", "Version". Irgendwie weiß ich aber nicht so recht wie ich ansetzen soll. Bisher hat alles was ich versucht habe schlicht "nicht" funktioniert.

Hat eventuell jemand eine Ide dazu?

Danke!

Mayho

Content-Key: 236646

Url: https://administrator.de/contentid/236646

Printed on: May 22, 2024 at 15:05 o'clock

Member: colinardo
colinardo Apr 28, 2014 updated at 12:27:03 (UTC)
Goto Top
Hallo Mayho,
also was ich jetzt auf Anhieb in deinem Bild erkennen kann ist folgender Fehler:
Der Name des ersten Parameters CreateRegKey_HIVE stimmt nicht mit dem RuntimeDefinedParameter Namen überein CreateRegKey_TOHIVE

Ist doch alles kein Hexenwerk, wenn du dir mein Beispiel nochmal genau ansiehst. Wichtig ist auch das du bei Verwendung von DynamicParam die Funktions-Abschnitte wie begin{}, process{} und end{} benutzt.

Grüße Uwe
Member: mayho33
mayho33 Apr 28, 2014 updated at 12:51:36 (UTC)
Goto Top
Hallo Uwe!

Danke! Habe ich gesehen und im Script korrigiert. Bildist korrigiert

Dein Beispiel habe ich mir schon oft angeschaut und auch oft verwendet. Wie das jetzt in diesem fall weiterhilft...Großes ?

Ich wollte es mal so versuchen:
Function Start-Test() {
    [CmdletBinding()]
    param ([parameter(ParameterSetName="CREATEREGKEY")] [switch]$CreateRegistryKey)  

    DynamicParam{
    $attrCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute]
    $paramDic = new-object System.Management.Automation.RuntimeDefinedParameterDictionary
        if ($CreateRegistryKey) {
                $attr = new-object System.Management.Automation.ParameterAttribute
                $attr.ParameterSetName = "CREATEREGKEY" ; $attr.Mandatory = $false ; $attrCollection.Add($attr)  
                $paramDic.Add("HIVE", (new-object System.Management.Automation.RuntimeDefinedParameter("HIVE", [Array], $attrCollection)))  
                $paramDic.Add("Path", (new-object System.Management.Automation.RuntimeDefinedParameter("Path", [String], $attrCollection)))  
                $paramDic.Add("AsActiveSetup", (new-object System.Management.Automation.RuntimeDefinedParameter("AsActiveSetup", [String], $attrCollection)))  
                if($PSBoundParameters.AsActiveSetup) {
                    $paramDic.Add("StubPath", (new-object System.Management.Automation.RuntimeDefinedParameter("StubPath", [String], $attrCollection)))  
                    $paramDic.Add("Version", (new-object System.Management.Automation.RuntimeDefinedParameter("Version", [String], $attrCollection)))  
                    $paramDic.Add("ComponentID", (new-object System.Management.Automation.RuntimeDefinedParameter("ComponentID", [String], $attrCollection)))  
                }
                return $paramDic
        }
    }
}

...Das bring aber nix. kein Effekt

Grüße mayho
Member: colinardo
colinardo Apr 28, 2014 updated at 12:26:07 (UTC)
Goto Top
Zitat von @mayho33:
Danke! Habe ich gesehen und im Script korrigiert. Bild folgt...
warum alles mit Bildern ?? Code mit Tags reicht hier doch ... und ich kann auch Copy n' Paste machen falls das nötig sein sollte !
Member: colinardo
colinardo Apr 28, 2014 updated at 12:32:19 (UTC)
Goto Top
hier noch ein Beispiel:
Suche DNS Command um Host A Einträge zu ändern

Du hast 100% einfach wieder dein Anzeigeproblem in der ISE, das hindert aber nichts an der korrekten Funktion. Damit die Parameter auch angezeigt werden musst du natürlich immer wieder zwischendurch F5 drücken und kompilieren damit die Parameter in der Konsole angezeigt werden können.
Member: mayho33
mayho33 Apr 28, 2014 at 12:34:01 (UTC)
Goto Top
Erledigt...
Member: colinardo
Solution colinardo Apr 28, 2014, updated at May 09, 2014 at 09:54:45 (UTC)
Goto Top
Zitat von @mayho33:
...Das bring aber nix. kein Effekt
das kann so auch nicht gehen, da zu dem Zeitpunkt PSBoundParameters noch nicht mit deinen vorherigen Parametern befüllt ist; das wird ja erst mit return $paramDic gemacht.
Schau mir das mal an und melde mich später wieder...

-edit- öhm, der Code ist wieder der alte ...
Member: mayho33
mayho33 Apr 28, 2014 at 12:56:03 (UTC)
Goto Top
Jetzt sollte es passen. CopyPaste-Problem.

Zum Beispiel: [ValidationSet] kann ich natürlich auch verwenden, aber DynamicParam{} gefällt mir sehr gut und der Vorteil ist, dass man für jeden Fall nur die Parameter bereitstellen kann die gerade gefragt sind.
Ich bin mir aber garnicht mehr so sicher ob ich das brauche. Sollte vielleicht einfach noch einen zusätzliche Switch einführen mit den entsprechenden Parametern:

[parameter(ParameterSetName="CREATEAC")] [switch]$CreateActiveSetup

...
...
...

Danke fürs Schauen...
Member: colinardo
colinardo Apr 28, 2014 updated at 13:01:10 (UTC)
Goto Top
So wie du das machen willst (das Verschachteln) geht das meines Wissens nicht(der Grund siehe voriger Kommentar). Hier solltest du deine Vorgehensweise überdenken und am Anfang mit differenzierten Parametern arbeiten z.B mit zwei unterschiedlichen Switches -CREATEREGKEY / -CREATEREGKEY-XYZ.
Der User muss schon wissen was er tut. Dazu hilft außerdem eine gute Dokumentation im Synopsis Abschnitt deiner Funktion.
Ich bin mir aber garnicht mehr so sicher ob ich das brauche. Sollte vielleicht einfach noch einen zusätzliche Switch einführen mit den entsprechenden Parametern:
genau das meine ich face-smile

Grüße Uwe
Member: mayho33
mayho33 Apr 28, 2014 at 13:33:51 (UTC)
Goto Top
Danke für den Hinweis! Habe es mittlerweile auch so umgesetzt.


Der User muss schon wissen was er tut.

Ja schon, aber wir führen PS im Bereich SCCM und Paketierung neu ein. Sämtliche Paketierer (jene die das Script für die automatisierte Installation basteln) bis auf mich und einen Kollegen haben 0 Erfahrung mit PS (und manche sind so eingefahren, dass sie sich auch nciht damit befassen wollen). Darum sollten die Functions bzw. cmdlets so weit wie möglich wasserdicht sein.

Mit zusätzlichen Switches gehts tlw eh. Einge SpezialSettings hätten so ein Customizing aber schon gut brauchen können.

z.B: sowas:

if ($CreateActiveSetup) {
            $attr = new-object System.Management.Automation.ParameterAttribute
            $attr.ParameterSetName = "ACTIVESETUP" ; $attr.Mandatory = $false ; $attrCollection.Add($attr)  
            $paramDic.Add("SetAutomatically_KeyName", (new-object System.Management.Automation.RuntimeDefinedParameter("SetAutomatically_KeyName", [Switch], $attrCollection)))  
            $paramDic.Add("SetManually_KeyName", (new-object System.Management.Automation.RuntimeDefinedParameter("SetManually_KeyName", [String], $attrCollection)))  
            $paramDic.Add("ComponentID", (new-object System.Management.Automation.RuntimeDefinedParameter("ComponentID", [Array], $attrCollection)))  
            $paramDic.Add("StubPath", (new-object System.Management.Automation.RuntimeDefinedParameter("StubPath", [String], $attrCollection)))  
            $paramDic.Add("Version", (new-object System.Management.Automation.RuntimeDefinedParameter("Version", [String], $attrCollection)))  
            return $paramDic
        }

wenn "SetAutomatically_KeyName" gesetzt ist, soll "SetManually_KeyName" garnicht mehr zur Auswahl stehen, lässt sich zum Glück ja noch mal prüfen und entsprechend abfackeln.

Danke für die Hilfe jedenfalls. Lasse den Thread trotzdem noch offen. Eventuell hat jemand noch eine zündende Idee....oder wäscht mit mal so richtig den Kopft face-wink

lg

Christian