[Solved] Ausführen von Powershell Befehlen

Antworten
Vir2ell
Beiträge: 16
Registriert: 20 Okt 2014, 13:54
Wohnort: Braunschweig

[Solved] Ausführen von Powershell Befehlen

Beitrag von Vir2ell »

Hallo,

ich bin gerade dabei ein Windows Updatescript zu schreiben.

Das Script soll die Powershell aufrufen, welches auch wunderbar funktioniert.
Anschließend soll auf laufende Prozesse innerhalb der Powershell geprüft werden und bei Bedarf sollen diese Prozesse gekillt werden.
Das habe ich in der Powershell Skirptsprache geschrieben. Normal als .ps1 Datei ausgeführt funktionert auch alles.

Wenn ich nun mittels ExecWith_Powershell die Powershell aufrufe, öffnet sich diese, jedoch werden die nachfolgenden Eingaben dort nicht eingegeben. Auch im Hintergrund passiert nichts, wenn ich sehe, dass die Dienste bereits laufen und gekillt werden sollen.

Da es sich hier bei mir um eine Art Prüfung handelt, kann ich leider keine Ausschnitte aus meinem Skript posten.

Ich habe schon viel gesucht, bin allerdings nicht fündig geworden, deswegen die Frage an euch:
Wie kann ich opsi dazu bringen, die Befehle in die Powershell einzugeben?

So in etwa sieht der Teil des Scriptes aus:

Code: Alles auswählen

[ExecWith_Powershell]

	Start-Process powershell -Verb runAs
Bis hier hin funktioniert alles. Die Powershell wird aufgerufen und öffnet sich anschließend im Administratormodus.

Die folgenden Eingaben sollen anschließend komplett der Reihenfolge nach eingegeben werden. Das funktioniert allerdings nicht.
Hier verfeinfacht dargestellt:

Code: Alles auswählen

powershell.exe set-executionpolicy RemoteSigned
	
	$tasks = @("hier die Prozesse die gekillt werden sollen")
		
	for($i=0; $i -le ($tasks.length -1); $i++) 
	{			
		$no_running_process =Hier die Überprüfung auf laufende Prozesse, eben 3 stück}
		if ($no_running_process -imatch $tasks[$i])
		{
			Hier wird dann der Prozess gestoppt
		}
		
	}
	exit 0
Ich hoffe das die Angaben reichen.

Desweiteren habe ich noch eine kleine Frage.
Ich führe zwei mal hintereinander die Powershell aus, möchte jedoch, dass opsi zwischen Sektion 1 und Sektion 2 5 Sekunden wartet.
Der Befehl zum ausführen lautet

Code: Alles auswählen

ExecWith_Powershell "%Systemdrive%\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" /WaitSeconds 5
Die Unterscheidung zwischen den einzelnen Sektionen findet natürlich statt.
Als Fehlermeldung im Skript Tester kommt dann:

Code: Alles auswählen

Die Benennung "/WaitSeconds" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt. Überprüfen Sie die Schreibweise des Namens, oder ob der Pfad korrekt ist 
Mit /TimeOutSeconds habe ich es auch schon versucht.

Vielen Dank für die Hilfe!

LG
Vir2ell
Zuletzt geändert von Vir2ell am 21 Apr 2017, 11:35, insgesamt 1-mal geändert.
uncle_scrooge
Beiträge: 650
Registriert: 21 Feb 2012, 12:03
Wohnort: Mainz

Re: Ausführen von Powershell Befehlen

Beitrag von uncle_scrooge »

Da Du die Preisgabe Deines geistigen Eigentums verweigerst, ist es schwierig, zu sagen, was bei Dir querläuft.

So etwas funktioniert jedenfalls:
[Actions]
DefVar $exitcode$

DosInAnIcon_setpolicy

ExecWith_powershell powershell.exe
set $exitcode$ = getLastExitcode
if not ($exitcode$ = "0")
comment "powershell script failed"
endif

[DosInAnIcon_setpolicy]
echo "powershell set-executionpolicy RemoteSigned ..."
powershell.exe set-executionpolicy RemoteSigned
exit %ERRORLEVEL%

[ExecWith_powershell]
echo "powershell opsi-winst-test"
echo "Get process list"
get-process
if ($?) {Exit(0)}
else {Exit(1)}


WINST schreibt schön die 'echos' ins Log, und gibt aus der Powershell-Sektion die Prozessliste ebenfalls ins Log aus.

Also, erste Anlaufstelle: Ins Log schauen.

(Disclaimer: Das snippet ist aus dem Handbuch geklaut.)
Vir2ell
Beiträge: 16
Registriert: 20 Okt 2014, 13:54
Wohnort: Braunschweig

Re: Ausführen von Powershell Befehlen

Beitrag von Vir2ell »

Hi uncle_scrooge,

danke für Deine schnelle Rückmeldung.

Mein Skript werde ich am Ende, wenn es fertiggestellt ist, im Wiki veröffentlichen :)
Ich habe mir das angesehen und mein Skript teilweise erweitert. Das Log sieht nun wie folgt aus:

Code: Alles auswählen

[5] [Apr 20 14:16:57:505] DosInAnIcon_SetPolicy
[6] [Apr 20 14:16:57:514]   c:\opsi.org\tmp\_opsiscript_Gy25Tw26.cmd saved back with encoding: system
[6] [Apr 20 14:16:57:522]   Executing "cmd.exe" /C c:\opsi.org\tmp\_opsiscript_Gy25Tw26.cmd
[6] [Apr 20 14:16:59:866]   ExitCode 0
[6] [Apr 20 14:16:59:874]               
[6] [Apr 20 14:16:59:881]               output:
[6] [Apr 20 14:16:59:888]               --------------
[6] [Apr 20 14:16:59:895]               
[6] [Apr 20 14:16:59:902]               C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst>echo "powershell set-executionpolicy RemoteSigned" 
[6] [Apr 20 14:16:59:919]               "powershell set-executionpolicy RemoteSigned"
[6] [Apr 20 14:16:59:926]               
[6] [Apr 20 14:16:59:934]               C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst>powershell.exe set-executionpolicy RemoteSigned 
[6] [Apr 20 14:16:59:941]               
[6] [Apr 20 14:16:59:956]               C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst>exit 0 
[6] [Apr 20 14:16:59:964]   
[6] [Apr 20 14:16:59:972]   Delete "c:\opsi.org\tmp\_opsiscript_*"
[6] [Apr 20 14:16:59:979]     Search "c:\opsi.org\tmp\"
[6] [Apr 20 14:16:59:994]     Search "c:\opsi.org\tmp\_opsiscript_*"
[6] [Apr 20 14:17:00:002]     File "c:\opsi.org\tmp\_opsiscript_Yv68Sl26.cmd"
[6] [Apr 20 14:17:00:010]       The file is 1 day(s) old, no deletion
[5] [Apr 20 14:17:00:019] 
[5] [Apr 20 14:17:00:036] Execution of ExecWith_Powershell
[6] [Apr 20 14:17:00:047]   c:\opsi.org\tmp\_opsiscript_Ha55Dg72.ps1 saved back with encoding: system
[6] [Apr 20 14:17:00:055]   Executing "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"  "c:\opsi.org\tmp\_opsiscript_Ha55Dg72.ps1"  
[6] [Apr 20 14:17:01:592]   ExitCode 0
[6] [Apr 20 14:17:01:599]               
[6] [Apr 20 14:17:01:606]               output:
[6] [Apr 20 14:17:01:613]               --------------
[6] [Apr 20 14:17:01:620]               powershell als Admin ausgeführt
[6] [Apr 20 14:17:01:626]               get process list
[6] [Apr 20 14:17:01:633]               stop process
[6] [Apr 20 14:17:01:640]               get process list
[6] [Apr 20 14:17:01:647]               stop process
[6] [Apr 20 14:17:01:653]               get process list
[6] [Apr 20 14:17:01:661]               stop process
[6] [Apr 20 14:17:01:668]   
[6] [Apr 20 14:17:01:676] Delete "c:\opsi.org\tmp\_opsiscript_*"
[6] [Apr 20 14:17:01:694]   Search "c:\opsi.org\tmp\"
[6] [Apr 20 14:17:01:700]   Search "c:\opsi.org\tmp\_opsiscript_*"
[6] [Apr 20 14:17:01:707]   File "c:\opsi.org\tmp\_opsiscript_Yv68Sl26.cmd"
[6] [Apr 20 14:17:01:715]     The file is 1 day(s) old, no deletion
[6] [Apr 20 14:17:06:733] EndIf
[6] [Apr 20 14:17:06:741] If
[5] [Apr 20 14:17:06:748]   $exitcode$ = "0"   <<< result true
[5] [Apr 20 14:17:06:755]   not ($exitcode$ = "0")   <<< result false
[6] [Apr 20 14:17:06:762] Then
[6] [Apr 20 14:17:06:769] EndIf
[1] [Apr 20 14:17:06:787] ___________________
[1] [Apr 20 14:17:06:794] script finished: success
[1] [Apr 20 14:17:06:800] 0 errors
[1] [Apr 20 14:17:06:813] 0 warnings
Er zeigt an, dass er drei Prozesse gefunden hat die laufen, und sie anschließend beendet.
Allerdings sagt das nur das Log. Im Taskmanager zeigt er mir die Prozesse dennoch an.
Das Powershell Fenster bleibt "leer" und er scheint nichts zu machen.

Ich habe dann mal versucht über das noch offene Fenster den Befehl "wuauclt.exe /DetectNow" einzugeben.
Da meldet er mir auf einmal zurück, dass er den Befehl nicht kennt, bzw das es kein cmdlet sei.

Der Pfad in dem sich die Powershell befindet lautet "PS C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst>"
Ist das eventuell das Problem? Muss ich ihm erst sagen, dass er den Pfad zu System32 wechseln soll?

PS: Das Problem mit /WaitSeconds habe ich durch sleepsecodns zwischen den einzelnen Sektionen gelöst.

EDIT:
Ok, das ist strange.
Wenn ich über das bereits geöffnete PS Fenster in den Ordner System32 navigiere und anschließens ls ausführe, erhalte ich alle Dateien und Ordner die sich in dem Ordner befinden.
Soweit so gut, aber es fehlt die Datei wuauclt.exe, obwohl sie eigentlich vorhanden ist?

Das sind die Dateien vor und nach "wua" die "noch" da sind.
52664 wtsapi32.dll
726528 wuapi.dll
29696 wuapp.exe
81920 wudriver.dll
27136 wups.dll
305664 wusa.exe
124928 wuwebv.dll
478720 wvc.dll

Ist das irgendwie bekannt?

Danke,

LG
Vir2ell
Zuletzt geändert von Vir2ell am 20 Apr 2017, 15:14, insgesamt 1-mal geändert.
uncle_scrooge
Beiträge: 650
Registriert: 21 Feb 2012, 12:03
Wohnort: Mainz

Re: Ausführen von Powershell Befehlen

Beitrag von uncle_scrooge »

>>Der Pfad in dem sich die Powershell befindet lautet "PS C:\Program Files (x86)\opsi.org\opsi-client-agent\opsi-winst>"
Nein, tut es nicht. Das ist der Pfad, aus dem WINST gestartet wird/wurde. Und WINST startet ohne weitere Pfadangabe (ich nehme an, Du hast die DOSinanIcon unverändert übernommen) von dieser Stelle aus powershell.exe. Und da die im Pfad ist, wird sie gefunden und ausgeführt.
Das er die 'richtige' nimmt, siehst Du ja am Log bei der ExecWith-Sektion.

>>über das noch offene Fenster
Wieso bleibt bei Dir das PS-Fenster offen? Hast Du in Deinem Skript die Anweisung 'if good weather keep all windows open' drin?
Edith sagt: Wenn er so was baut, wundert es mich nicht mehr.
[ExecWith_Powershell]
Start-Process powershell -Verb runAs

Damit startest Du aus einer bereits laufenden PowerShell-Session eine weitere. Ohne Deine Intention und Vorgehensweise zu kennen, überflüssig wie ein Kropf.

Ohne Dein Skript versagt meine Glaskugel jetzt aber die Mitarbeit.
Vir2ell
Beiträge: 16
Registriert: 20 Okt 2014, 13:54
Wohnort: Braunschweig

Re: Ausführen von Powershell Befehlen

Beitrag von Vir2ell »

Den Hintergrund kann ich dir verraten, warum ich aus der Powershell eine weitere starte, oder gestartet habe...
Ich habe angenommen, dass die PS standardmäßig nicht als Administratormodus gestartet wird.

Um einen Prozess mittels -Force zu beenden, werden Adminrechte benötigt. Die habe ich damit erhalten.

Ich habe das Skript jetzt einmal ohne diesen zusätzlichen Parameter gestartet und es sieht gleich aus.
Mir scheint, dass opsi die PS wohl gleich als Admin ausführt.

Nun habe ich aber noch immer das Problem, dass die Dienste nicht beendet werden.
Laut Log sagt er, dass er die Prozesse gekillt hat, zeigt mir dieses allerdings nicht im Taskmanager an.

Wenn ich den reinen Text, den opsi in die PS eingeben soll, selber händisch eintrage, funktioniert alles tadellos.
In meinem vorherigen Kommentar habe ich noch etwas anderes angemerkt.
Wenn ich in den Ordner System32 über die PS navigiere, finde ich dort nicht die wuauclt.exe.
Kennt man das Problem? Oder ist es gar kein Problem?

In der ersten Abfolge sollen etwaige Dienste die für den Updateprozess zuständig sind beendet werden.
Anschließend wird das Programm für 5 Sekunden angehalten, damit sichergegangen wird, dass die Dienste wirklich alle beendet sind.
Danach wird über die PS der Befehl wuauclt.exe /DetectNow /UpdateNow eingegeben um nach neuen Updates zu suchen und diese gleich zu installieren.

Hier taucht dann das oben genannte Problem auf, dass er die wuauclt.exe nicht finden kann und beendet anschließend das Skript ohne Fehler oder Warnung.

Habe ich irgendwo einen Denkfehler?
uncle_scrooge
Beiträge: 650
Registriert: 21 Feb 2012, 12:03
Wohnort: Mainz

Re: Ausführen von Powershell Befehlen

Beitrag von uncle_scrooge »

>>Wenn ich in den Ordner System32 über die PS navigiere, finde ich dort nicht die wuauclt.exe.
Die Freuden von 32bittigen Prozessen in einer 64bittigen Umgebung (Windows-only).
Wenn Du in einem 64Bit Windows einen 32bittigen Prozess startest, siehst Du nicht the real \windows\system32, sondern \windows\syswow64.
Und dort gibt es keine wuauclt.exe. Dein Prozess, in diesem Fall die PowerShell, bekommt von der Verbiegerei nichts mit, und fällt auf die Nase.
Wenn Du die PowerShell bei Dir 'per Hand' startest, läuft die 64Bit Variante. Kannst Du im Taskmanager sehen. Drum klappt das Spielchen mit wuauclt auch.
Müsstest Du mal nachschlagen, ob man ExecWith als Parameter /64 mitgeben kann. Allerdings würde ich die wuauclt-Geschichte eh in einen DOSBatch oder DOSinanIcon verlagern. Oder die entsprechenden Befehle der PS nutzen. (So sie in Deiner Version denn vorhanden sind.)

Was die nicht beendeten Dienste angeht, kann ich Dir im Moment nicht viel sagen. Bitte aber an die Unterscheidung Prozess/Dienst denken. wuauserv ist z.B. ein Dienst, und muß mit stop-service und nicht stop-process beendet werden.
Unabhängig davon reicht es m.E. völlig aus, wenn Du wuauserv abschießt, damit Du Ruhe vor etwaigen Updateaktionen des Systems hast.

Edith raunt mir zu, ich hätte noch was vergessen:
WINST, also der Skript-Interpreter, läuft per default im Kontext nt-authority\system. Ist KEIN Admin, aber hat vergleichbare, eher weitreichendere Rechte.
Vir2ell
Beiträge: 16
Registriert: 20 Okt 2014, 13:54
Wohnort: Braunschweig

Re: Ausführen von Powershell Befehlen

Beitrag von Vir2ell »

Hi uncle_scrooge,

vielen Dank für Deine Hilfe, es ist vollbracht.
Die Poweshell konnte ich mittels ExecWith_Powershell powershell.exe winst /64Bit im 64 Bit Modus starten.
Dort konnten die Prozesse entgültig beendet werden und auch die anschließende Suche nach neuen Updates erfolgt problemlos ;)

Ich habe teilweise in den vorherigen Posts Prozesse und Dienste vertauscht. Hier ging es wirklich nur um Prozesse, welche auch im Taskmanager zu sehen waren, also alles gut, und Danke für die super Erklärung! :)

Also ein großes Dankeschön nochmal. Wenn das Projekt fertiggestellt ist, wird es natürlich hochgeladen.

LG,
Vir2ell
Antworten