Powershell-Funktionen ausführen (und Ergebnisse auswerten)

Antworten
SchwabenTom
Beiträge: 49
Registriert: So 4. Jan 2015, 21:34
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Powershell-Funktionen ausführen (und Ergebnisse auswerten)

Beitrag von SchwabenTom »

Hallo,

wie kann ich Powershell-Befehle ausführen und auch das Ergebnis dabei "zurückbekommen".

Hintergrund: Ich möchte auf einem Server Core die VMs verwalten.

Beispiel wäre:
- Powershell-Befehl heißt: Get-VM. Den möchte ich ausführen. Und dabei dann aber auch an das Ergebnis kommen. D.h. die Liste der VMs haben.
- Powershell-Befehl heißt: Export-VM. Hier wird das Ergebnis wohl nur ein Fehlercode sein (bzw. Nichtfehler-Code).

Hier im Forum finde ich nichts dazu. Suche nach Powershell bringt ganze drei Threads. Nach VM oder ähnlichem bringt mich nur zu Diskussionen, ob Lazarus in eine VM installiert werden kann/soll/muß/darf/sinnvoll/etc. In Suchmaschinen finde ich auch nichts. Ergebnisse gibt's da natürlich massig - aber dann nur auf Powershell oder nur auf Hyper-V bezogen - aber nichts im Zusammenhang mit Lazarus/Delphi/Pascal. Nur ein einziger Treffer war interessant. Der hat mich zu einer kommerziellen Komponente geführt, die es aber anscheinend nicht mehr gibt. Ich komme mit meiner Suche nicht mehr weiter. Evtl. suche ich mit den falschen Keys (?).

Weiß einer wie das geht?
Gibt's Code-Examples?

Ich kenne von früher noch ShellExecute (PS.: Ich hab seit Delphi 5 nichts mehr in Richtung Pascal gemacht.). Über diesen Suchweg finde ich:

http://wiki.freepascal.org/Executing_Ex ... rograms/de

Ist das sinnvoll?

Über die Powershellsuche habe ich für eine andere Sprache (wird eine MS-Einwicklungsumgebung gewesen sein; bekomme es aus der Erinnerung nicht mehr ganz zusammen) etwas gefunden, daß man sich erst so etwas wie einen "Workspace" oder "Powershellspace" (oder irgendwie sowas) aufbaut (auruft, intiiert, ...) und dann damit mit Powershellobjekten komfortabel arbeiten kann. Das wäre wahrscheinlich einiges besser, als dem in dem Link angesprochenen TProcess. Ich vermute, daß jeder Aufruf durch den TProcess einen wie auch immer gearteten Overhead verursacht (Powershell aufrufen, initialisieren, etwas tun, Rückgaben, Abschlussarbeiten, Speicher frei geben, etc.), der bei der Workspace-Variante evtl. entfällt. Wobei es mir am Ende aber egal wäre. Es soll erstmal funktionieren :-)

Ein anderer Gedanke wäre, daß es möglicherweise auch direkt über die Windows-API geht (?).

Da ich nichts direktes finde. Und bevor ich mich über mögliche Umwege verrenne, dachte ich mir, ich frage mal nach :-)

Zusammenfassend:

Es geht darum, den Hyper-V Server mit einem lokalen Programm zu verwalten (bzw. ein paar der Verwaltungsfunktionen). Im besonderen geht's dabei um die VMs dort.

a) Möglichkeit die ich sehe: Powershell.
Frage: wie führe ich Powershell-Befehle aus - und verarbeite die Rückgabe(n) dieser Befehle?

b) Alternative wäre: ShellExecute (oder dazu Äquivalentes).
D.h. die cmd(.exe) nutzen und durch vorangestelltes "powershell -Command ...." die Powershell ausgeführt bekommen.

c) Evtl. gibt's eine "direkte" Methode ohne den "Umweg" über die Powershell?

Bin für jede Hilfe dankbar.
Grüße, Tom

SchwabenTom
Beiträge: 49
Registriert: So 4. Jan 2015, 21:34
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Powershell-Funktionen ausführen (und Ergebnisse auswerte

Beitrag von SchwabenTom »

PS.: ganz unten bei dem "cmd(.exe)" habe ich die Klammern eingefügt. Sollte eigentlich ohne sein ... aber da hat mich das Board "ausgesperrt".

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Powershell-Funktionen ausführen (und Ergebnisse auswerte

Beitrag von marcov »

Da Powershell relativ neu ist, nehme ich an das es sich über COM steuern las. Vielleicht kann man ein Header dafür herstellen mit importtl, das Free Pascal's COM typelib Tool

SchwabenTom
Beiträge: 49
Registriert: So 4. Jan 2015, 21:34
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Powershell-Funktionen ausführen (und Ergebnisse auswerte

Beitrag von SchwabenTom »

Stehe wieder vor Fragen ... und kann den Post gleich als kleinen Zwischenstandsbericht nutzen :-)

-----------------------------

Neues Projekt, Ein TEdit drauf, ein TButton, ein TMemo und dazu ein TProcess.

Button1-OnClick ist ein Dreizeiler:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  Process1.CommandLine:= Edit1.Text;
  Process1.Execute;
  Memo1.Lines.LoadFromStream(Process1.Output);
end;


Geht, aber nicht zufriedenstellend. Paar Dinge gehen (bspw. calc oder ping), auch Batch-Dateien (bspw. test1.bat oder c:\einpfad\test2.bat), anderes geht gar nicht (dir), wieder anderes war merkwürdig (kein Fehler, aber das cmd-Fenster bleibt wie "hängen")... Letztlich führte es mich auf den Punkt "Einlesen eines großen Outputs" aus

http://wiki.freepascal.org/Executing_Ex ... rograms/de

Dann: ping hat funktioniert, weil es eine exe ist. dir hat nicht funktioniert, weil es nicht eigenständig ist, sondern Teil der cmd - ich hätte es also mit cmd dir (bzw. ähnlich, siehe weiter unten) ausführen lassen müssen.

Erkenntnis:

Wenn du ein ein Programm, irgendeine exe, oder auch einfache Batch-Kommandos (mit nur sehr wenig Output) ausführen willst, reicht dir der obige Dreizeiler.

Ansonsten muß die Pipe regelmäßig geleert werden, da die Ausführung des Prozesses wartet, bis in der Pipe wieder Platz ist und dein Programm wartet, bis der Prozess endet: Dead Lock - siehe den Link oben.

Den Weg habe ich nicht weiter verfolgt und habe mit dem Beispielcode aus obigem Link (der die Pipe berücksichtigt) weiter getestet.

-----------------------------

Angehängt die Lazarus-Files für:

Basis "Einlesen eines großen Outputs" aus http://wiki.freepascal.org/Executing_Ex ... rograms/de angepasst (Eingabefeld, Memos, Button, etc.) ... angehängt die Lazarus-Files.

D.h. Stand ist der, daß ein TProcess über "CommandLine" und "Execute" einen Prozess startet; dabei aber diesmal die Pipe ständig geelert wird, damit a) das "Rückgabeergebnis" verfügbar wird und b) der Prozess nicht in den oben erwähnten Dead Lock gerät.

Versucht habe ich bspw.:

(PS.: /.C ohne den Punkt - Die Forensoftware schmeißt mich raus, wenn ich / und C direkt aneinander schreibe)

[001] calc
[002] dir
[003] ping
[004] cmd dir
[005] cmd /.C dir
[006] cmd /.C powershell -Command Get-ChildItem
[007] cmd /.C powershell -Command "& {Write-Host 'Testausgabe';Get-ChildItem}"
[008] cmd /.C powershell -Command "& {Write-Host 'Testausgabe';Get-ChildItem;Exit}"
[009] powershell Get-ChildItem
[010] powershell -Command "& {Write-Host 'Testausgabe';Get-ChildItem;Exit}"

1 bis 3 => Ist genauso wie der Dreizeiler ganz oben. "dir" alleine will nicht, also:

4 => cmd dir => bleibt "hängen", das Fenster fürs cmd öffnet sich, bleibt aber komplett schwarz, man muß es über das [x] schließen => Output ist dann vorhanden, aber kein dir und kein dir-Ergebnis. Nebenbei: keine Fehlerrückgabe.

Nach etwas Suche im Netz: cmd kennt die Schalter /K und /.C => also mal mit /.c probieren:
[005] cmd /.C dir => Treffer, funktioniert
(PS.: /.C ohne den Punkt)

6 bis 8 => sind nun die Powershell-Versuche.

[006] cmd /.C powershell -Command Get-ChildItem => wie vorher bei [004] (PS.: /.C ohne den Punkt). Das cmd-Fenster poppt auf, bleibt aber komplett leer und schließt sich nicht mehr. Wenn man es über [x] schließt, hat man das gewünschte im Memo Output. Es hat also funktioniert. Problem ist "nur", daß sich das cmd-Fenster nicht von sich aus schließt. BTW: Fehlercode "^C" wurde zurückgegeben. Einerseits klinkts logisch: wir hatten das Fenster ja händisch geschlossen; andererseits: selbes Problem mit Punkt [004] brachte aber keinen Fehlercode => ?

Ich habe noch einiges versucht, gesucht, gefunden, nicht gefunden ... 7 und 8 habe ich hier mal aufgeschrieben, um zu zeigen: a) man kann mehrere Powershellbefehle mit Semikolon trennen, b) Exit bringts nicht (Fenster bleibt offen), c) ob dieses "& {...}" unbedingt nötig ist, weiß ich nicht (ist jetzt aber mit dokumentiert :-)), d) soetwas wie /.C (ohne den Punkt) bei cmd habe ich für Powershell nicht gefunden

Dann der Gedanke: wieso cmd? Powershell ist doch cmd-"Ersatz". Also:
9 und 10 => Gleiches Ergebnis wie 6 bis 8. D.h. funktioniert zwar im Output, aber man muß das aufgepoppte Fenster selber schließen. Anzumerkender Unterschied: hier kein Fehlercode.

Ergebnis: Kein Ergebnis.

Erkenntnis:

cmd ist nicht notwendig; direkt über die powershell gehen.
Keine "volle Pipe, alles wartet"-Problematik. Output ist am Ende in Lazarus verfügbar; auch großer Output.

Frage:

Wie bekomme ich das powershell-Fenster automatisch geschlossen. D.h. nicht schließen, terminieren oder soetwas. Sondern "geregelter" Ablauf. So wie es bspw. mit Punkt 5 (cmd /.C dir) ist. (PS.: /.C ohne den Punkt)

---------------------

Dem Hinweis von marcov bin ich mal nachgegangen. Das wird die Lösung sein: WMI. Sucht man nach WMI und bspw. VirtualSystemManagementService kommen recht interessante Infos. Für die Aufgabe "Hyper-V Server verwalten" wird das wohl der richtige Weg sein. Das scheint mir aber ein recht weites Feld und ziemlich komplexes Thema zu sein.

Kennt da jemand was?
Evtl. auch direkt mit Pascal-Codes - vielleicht sogar für VMs?

----------------------

Powershell werde ich für meine Aufgabenstellung also wohl nicht brauchen. Andererseits: es ist "nur" noch diese eine "kleine" Problemchen zu lösen: daß sich das Fenster nicht schließt. Dann wäre für andere die die Powershell haben wollen ein fu8nktionierender Lösungsweg gezeigt.

Grüße, Tom



----------

Nachtrag: das Forum hat mich die Dateien tprocesstest.res, tprocesstest.lps und tprocesstest.lpi nicht hochladen lassen. Keine Ahnung, ob die nicht essentiell sind, um das Projekt zu "rekonstruieren". Mglw. einfach ein neues Projekt starten und die lfm und pas drüberkopieren. Das Projekt benennst du "tprocesstest".
Dateianhänge
tprocesstest.lpr
(386 Bytes) 114-mal heruntergeladen
unit1.lfm
(1.93 KiB) 120-mal heruntergeladen
unit1.pas
(2.77 KiB) 129-mal heruntergeladen
Zuletzt geändert von Lori am Di 6. Jan 2015, 18:44, insgesamt 1-mal geändert.
Grund: richtiger Highlighter

Antworten