none
Parameter bei Start-Job aus Variablen auslesen RRS feed

  • Frage

  • Hallo liebe Powershellgemeinde,

    ich habe das Problem, dass ich es nicht hinbekomme ein Befehl als Job mit Parametern aus einer Variable zu starten. Die angegebenen Parameter werden nicht als solche vom Befehl erkannt und/oder werfen einen Fehler:

    "Cannot convert '-recurse' to the type 'System.String' required by parameter 'Filter'. Die angegebene Methode wird nicht unterstützt.
    An :Zeile:4 Zeichen:11
    + Receive-Job <<<<  Test"

     

    Beispielskript zum Problem

    $1 = "-recurse"
    Start-Job -name Test -ScriptBlock {dir C:\ $args} -ArgumentList $1 
    Wait-Job Test
    Receive-Job Test
    Stop-Job test

     

    In meinem Fall baue ich aus einer Datenbankabfrage die Parameter für den Befehlsaufruf zusammen und möchte dann den Befehl als Job starten und auf das erfolgreiche beenden warten.

     

    Montag, 23. August 2010 11:43

Antworten

  • Hallo,

    ah, ok. Sorry für das Misverständniss, jetzt ist mir dein Vorhaben klar. Was du bräuchtest ist eine (String) Variable in dem der gesamte Befehl aufgebaut wird um diese Variable anschließend durch das Invoke-Expression Cmdlet auszuführen. In meiner Testumgebung habe ich folgenden Code erfolgreich ausführen können:

    $1 = "-recurse"
    
    Start-Job -name Test -ScriptBlock {$cmd="dir C:\Scripts "+$args[0]; Invoke-Expression $cmd| Out-File C:\test.txt} -ArgumentList $1

    -----
    test.txt Output:

      Verzeichnis: C:\Scripts


    Mode                LastWriteTime     Length Name                                                                                     
    ----                -------------     ------ ----                                                                                     
    d----         8/24/2010   4:34 PM            test1                                                                                    
    d----         8/24/2010   4:34 PM            test2                                                                                    
    -a---         8/24/2010   4:41 PM        160 args.ps1                                                                                 
    -a---         7/29/2010  12:10 PM        401 hard.ps1                                                                                 
    -a---         7/20/2010   9:47 AM       3586 ie.ps1                                                                                   


        Verzeichnis: C:\Scripts\test1


    Mode                LastWriteTime     Length Name                                                                                     
    ----                -------------     ------ ----                                                                                     
    d----         8/24/2010   4:34 PM            test11                                                                                   


        Verzeichnis: C:\Scripts\test2


    Mode                LastWriteTime     Length Name                                                                                     
    ----                -------------     ------ ----                                                                                     
    d----         8/24/2010   4:34 PM            test21                                                                                   
    d----         8/24/2010   4:34 PM            test22       

    Hoffe das hilft dir weiter.

    Gruß,
    Andrei

    • Als Antwort markiert Talarion Dienstag, 24. August 2010 14:14
    Dienstag, 24. August 2010 13:52
    Moderator

Alle Antworten

  • Hallo,

    klappt es nach einem Cast?

    Start-Job -name Test -ScriptBlock {dir C:\ $args} -ArgumentList $1.ToString()
    

    Gruß,
    Andrei

    Dienstag, 24. August 2010 06:31
    Moderator
  • Hi,

    Nein es klappt so leider auch nicht. Die Variable $1 ist ja auch schon ein String. Ich verstehe nicht warum versucht wird das nochmal in ein String zu konvertieren, obwohl es schon einer ist. Ausserdem würde der Übergebene Befehl dann ja wie folgt lauten:

    dir c:\ "-recurse" -> was natürlich kein Effekt hat, da die Parameter so nicht erkannt werden.

     

     

    In der Powershell sind doch alles Objekte, soweit ich es verstanden habe. Sind dann nicht auch Befehlsaufrufe Objekte? Kann es sein, dass man die Parameter als Attribute dieses Objekts festlegen muss, damit es funktioniert? Und wenn ja wie?

    Dienstag, 24. August 2010 06:55
  • Hi,

    fast alles ist Objekt orientiert, ja. Natürlich kann man Cmdlets anpassen/selber definieren. Persönlich würde ich zu einer solchen Methode greifen nur wenn es über die eingebauten/öffentlich verfügbaren Cmdlets nicht funktionieren würde.

    Habe mir inzwischen auch das Problem genauer angeschaut. Einen -recurse parameter gibt es nicht für das Start-Job Cmdlet. Daher ist die Fehlermeldung auch begründet.

    Wenn ich dein Vorhaben richtig verstanden habe, würde ich einfach vorschlagen das switch Statement zu nutzen:

    switch ($s)
      { 
        option1 {Cmdlet -parameter1} 
        option2 {Cmdlet -parameter2} 
        option3 {Cmdlet -parameter3} 
        default {"Geben Sie einen Parameter an"}
      }
    

    Falls das auch nicht weiterhilft, lass uns bitte wissen was du genau erreichen möchtest. Evtl. könnten wir mit einem konkreten Beispiel weiterhelfen.

    Gruß,
    Andrei

    Dienstag, 24. August 2010 11:10
    Moderator
  • Der Parameter -recurse war auch nicht für Start-job gedacht sondern für den Befehl im Skriptblock {dir c:\ $args}, wobei $args den Werten der ArgumentList enstpricht(Aus der Doku). In einem Skriptblock kann man nämlich nicht einfach so Variablen verwenden, da sie nicht durch die Werte ersetzt werden.

    Ich muss einen Befehl mehrmals mit verschieden Parametern absetzen. Die Reihenfolge der Ausführung ist wichtig, desshalb wird ein Befehl als Job gestartet, damit ich die Möglichkeit habe auf die Fertigstellung zu warten(wait-job). Es ändern sich lediglicht die Parameter mit denen der Befehl aufgerufen wird.

    Ich lese die Daten aus einer Datenbank aus und bastel mir einen langen String($Argumente) für alle Parameter zusammen:(Bsp."-Param1 Value1 -Param2 Value2...")

    der soll dann dem Programm als Parameter übergeben werden, was aber nicht passiert.

    Start-Job -InitializationScript {cd 'c:\Program Files\S4ATSCalc\K3Client'} -ScriptBlock {.\k3client.exe $args} -Name calc -ArgumentList $Argumente
        
    
    Das ganze mit Switch zu umschiffen ist zu umfangreich, da es über 13 Parameter sind, und der Aufwand(Schleife in Schleife...) exponetiell steigt.

    Dienstag, 24. August 2010 11:34
  • Hallo,

    ah, ok. Sorry für das Misverständniss, jetzt ist mir dein Vorhaben klar. Was du bräuchtest ist eine (String) Variable in dem der gesamte Befehl aufgebaut wird um diese Variable anschließend durch das Invoke-Expression Cmdlet auszuführen. In meiner Testumgebung habe ich folgenden Code erfolgreich ausführen können:

    $1 = "-recurse"
    
    Start-Job -name Test -ScriptBlock {$cmd="dir C:\Scripts "+$args[0]; Invoke-Expression $cmd| Out-File C:\test.txt} -ArgumentList $1

    -----
    test.txt Output:

      Verzeichnis: C:\Scripts


    Mode                LastWriteTime     Length Name                                                                                     
    ----                -------------     ------ ----                                                                                     
    d----         8/24/2010   4:34 PM            test1                                                                                    
    d----         8/24/2010   4:34 PM            test2                                                                                    
    -a---         8/24/2010   4:41 PM        160 args.ps1                                                                                 
    -a---         7/29/2010  12:10 PM        401 hard.ps1                                                                                 
    -a---         7/20/2010   9:47 AM       3586 ie.ps1                                                                                   


        Verzeichnis: C:\Scripts\test1


    Mode                LastWriteTime     Length Name                                                                                     
    ----                -------------     ------ ----                                                                                     
    d----         8/24/2010   4:34 PM            test11                                                                                   


        Verzeichnis: C:\Scripts\test2


    Mode                LastWriteTime     Length Name                                                                                     
    ----                -------------     ------ ----                                                                                     
    d----         8/24/2010   4:34 PM            test21                                                                                   
    d----         8/24/2010   4:34 PM            test22       

    Hoffe das hilft dir weiter.

    Gruß,
    Andrei

    • Als Antwort markiert Talarion Dienstag, 24. August 2010 14:14
    Dienstag, 24. August 2010 13:52
    Moderator
  • Hi Andrei,

     

    Vielen dank das ist die Lösung!! Ist zwar ein wenig umständlich, aber funktioniert.

     

    Nochmals Danke

    Dienstag, 24. August 2010 14:16