megamazl
Goto Top

CPU-Auslastung einlesen mit VBS und Datei erzeugen wenn unter 20 Prozent

Hallo Administrator Gemeinde,

folgendes Vorhaben:
Ich habe ein Netzwerk mit 11 Rechnern. Einer ist der Zentralrechner auf dem Videos geschnitten werden. Diese Videos müssen danach noch umgewandelt werden. Dies soll auf den 10 anderen Rechnern geschehen. Allerdings müßte die Umcodierung so geregelt werden, daß der Zentralrechner die Videos mit Xcopy auf die anderen Rechner verteilt, wo sie dann mit einem Codierungsprogramm mit Watchfolder-Funktion umcodiert werden. Allerdings sollen diese Dateien natürlich nur kopiert werden, wenn der jeweilige Umcodierungsrechner nicht grade am arbeiten ist. Um das herauszufinden habe ich folgendes Script geschrieben, welches eine Datei erzeugen soll, wenn die Prozessorlast unter 20% ist. Wenn die Last über 20% ist, soll diese Datei wieder gelöscht werden. Somit kann mit einer einfachen "if exist" Abfrage des Zentralrechners überprüft werden, ob der Codierrechner besetzt ist.

On Error Resume Next 

strComputer = "."   
Set objWMIService = GetObject("winmgmts:" _   
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")   
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")   
For Each objItem in colItems 
    Wscript.Echo "Load Percentage: " & objItem.LoadPercentage   
Next

If objItem.LoadPercentage <= 20 Then 
Call ErstelleEineDatei
Else
Call Dateiloschen
End if

Sub ErstelleEineDatei
   Dim fso, MeineDatei
   Set fso = CreateObject("Scripting.FileSystemObject")  
   Set MeineDatei = fso.CreateTextFile("c:\CPUnotbusy.txt", True)  
   MeineDatei.WriteLine("im moment keine codierung.")  
   MeineDatei.Close
End Sub

Sub Dateiloschen
Set fso = CreateObject("Scripting.FileSystemObject")  
fso.GetFile("c:\CPUnotbusy.txt").Delete  
End Sub

Allerdings funktioniert diese Script noch nicht so richtig, wenn die Last unter 20% ist, wird wohl eine Datei erzeugt, ist sie über 20% wird die Datei allerdings nicht wieder gelöscht.

Hat jemand eine Idee?
Wahrscheinlich ein dummer Fehler, hab mir VBS heute zum ersten Mal angeschaut.

Content-ID: 95122

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

Ausgedruckt am: 26.11.2024 um 10:11 Uhr

bastla
bastla 23.08.2008 um 00:35:38 Uhr
Goto Top
Hallo megamazl!

Bedingt durch das "On Error Resume Next" wird keine Fehlermeldung angezeigt und nach der fehlerhaften Zeile einfach fortgesetzt, weswegen immer "Call ErstelleEineDatei" zum Zug kommt - Du solltest daher die "On Error"-Zeile erst nach dem (erfolgreichen face-wink) Testen in das Script aufnehmen.

Das Problem liegt darin, dass "objItem.LoadPercentage" nur innerhalb der "For Each"-Schleife zur Verfügung steht - die entsprechende Fehlermeldung "C:\Scripts\FlagFile.vbs(11, 1) Laufzeitfehler in Microsoft VBScript: Objekt erforderlich: 'objItem' hätte dies leichter erkennbar gemacht.

Die Lösung ist aber einfach: Schreibe den entsprechenden Prozentsatz innerhalb der Schleife in eine Variable, oder setze gleich die Abfrage selbst in die Schleife.

Version 1 sähe so aus:
...
For Each objItem in colItems
    LoadPercentage = objItem.LoadPercentage
    WScript.Echo  "Load Percentage: " & LoadPercentage  
Next

If LoadPercentage <= 20 Then
...
Sind das übrigens Single-Core-Prozessoren? Wenn Du mehrere Kerne zur Verfügung hast, werden in der Schleife die Werte der einzelnen Kerne nacheinander ausgegeben. Falls Du dann die Gesamtauslastung ermitteln möchtest, ginge das so:
...
TotalLoadPercentage = 0
For Each objItem in colItems
    LoadPercentage = objItem.LoadPercentage
    WScript.Echo  "Load Percentage: " & objItem.LoadPercentage  
    TotalLoadPercentage = TotalLoadPercentage + LoadPercentage 
Next

If TotalLoadPercentage <= 20 Then 'oder 40/80, da ja 200% oder 400% Gesamtwert möglich  
...
Grüße
bastla
megamazl
megamazl 23.08.2008 um 21:00:01 Uhr
Goto Top
super, vielen Dank mit:
On Error Resume Next 

strComputer = "."   
Set objWMIService = GetObject("winmgmts:" _   
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")   
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor")   

TotalLoadPercentage = 0 
For Each objItem in colItems 
    LoadPercentage = objItem.LoadPercentage 
    WScript.Echo  "Load Percentage: " & objItem.LoadPercentage   
    TotalLoadPercentage = TotalLoadPercentage + LoadPercentage  
Next 
   
If TotalLoadPercentage <= 20 Then 
Call ErstelleEineDatei() 
Else 
Call Dateiloschen() 
End if 

Public Sub ErstelleEineDatei()
   Dim fso, MeineDatei
   Set fso = CreateObject("Scripting.FileSystemObject")  
   Set MeineDatei = fso.CreateTextFile("c:\CPUnotbusy.txt", True)  
   MeineDatei.WriteLine("im moment keine codierung.")  
   MeineDatei.Close
End Sub

Public Sub Dateiloschen()
Set fso = CreateObject("Scripting.FileSystemObject")  
fso.GetFile("c:\CPUnotbusy.txt").Delete  
End Sub
klappt es bestens.

Ich habe mir jetzt eine Batch geschrieben die so aussieht:
:run 
cpu.vbs
sleep 60
goto run

Jetzt bräuchte ich eine stop.bat die den Prozess beendet und die die evtl. vorhandene CPUnotbusy.txt löscht. Das Problem ist jetzt, wie krieg ich den jetzt die im Loop laufende cmd.exe gelöscht? Wenn ich das über den Kill Befehl laufen lassen will, funktioniert das nicht.

Danke im voraus.
bastla
bastla 23.08.2008 um 21:24:04 Uhr
Goto Top
Hallo megamazl!

Jetzt bräuchte ich eine stop.bat die den Prozess beendet und die die evtl. vorhandene CPUnotbusy.txt löscht.
Welchen Prozess willst Du unter welcher Bedingung beenden?

Grüße
bastla
megamazl
megamazl 23.08.2008 um 21:40:23 Uhr
Goto Top
wenn ich die START.bat starte, wird ja die cpu.vbs gestartet und alle 60 Sekunden wiederholt. Die cpu.vbs startet ja als cmd.exe, da sie im Batch läuft. Und genau diese cmd.exe möchte ich mit einer STOP.bat beenden und die CPUnotbusy.txt löschen, falls diese im Moment existiert. Wenn ich aber per "kill cmd.exe" versuche die cmd.exe zu beenden passiert nichts, die STOP.bat läuft ja ebenfalls in einer cmd.exe. Ich bräuchte sozusagen einen Identifier für genau diese gestartete cmd.exe.
bastla
bastla 23.08.2008 um 21:51:06 Uhr
Goto Top
Hallo megamazl!

Das ist mir nicht klar ...

Zum Einen wird die "cpu.vbs" durch "cscript.exe" oder, defaultmäßig, "wscript.exe" (nicht aber durch "cmd.exe") ausgeführt, zum Anderen läuft das VBScript ja nur einmal durch und Du hast danach eine "CPUnotbusy.txt" oder eben nicht - das kannst Du ja im Batch (vor dem "sleep") mit "if exist" abfragen und dementsprechend weiter verfahren - oder übersehe ich etwas?

Grüße
bastla
megamazl
megamazl 23.08.2008 um 22:05:30 Uhr
Goto Top
ja, ok, die cpu.vbs läuft natürlich im cscript.exe, aber da ja fortwährend die Prozessorlast abgefragt werden soll, um zu überprüfen ob der Rechner grade am codieren ist, soll die cpu.vbs natürlich im Loop ablaufen. Und genau diese Batchdatei (START.bat, siehe oben) läuft ja unter cmd.exe. Die START.bat soll ja wirklich stundenlang laufen während der Rechner codiert. Erst wenn der Rechner nach ca. 2 oder 3 Stunden mit dem Videofile fertig ist, soll die CPUnotbusy.txt wieder erstellt werden. Wenn ich jetzt nur die cscript.exe killen würde, würde sie im nächstem Durchgang nach sleep ja wieder erstellt würden.
Allerdings soll man auch eben mit dieser STOP.bat die laufende START.bat beenden können und damit auch die CPUnotbusy.txt löschen, damit nicht aus Versehen Dateien kopiert werden.
bastla
bastla 23.08.2008 um 22:27:58 Uhr
Goto Top
Hallo megamazl!

Allerdings soll man auch eben mit dieser STOP.bat die laufende START.bat beenden können und damit auch die CPUnotbusy.txt löschen, damit nicht aus Versehen Dateien kopiert werden.
Da stellt sich natürlich die Frage: Wie wird die STOP.bat gestartet?

Trotzdem ein Ansatz:
Wenn Du in der START.bat (übrigens ist es nicht zu empfehlen, Batches Namen von CMD-Befehlen zu geben) eine Zeile
title ##CheckCPU##
an den Anfang stellst, würde ein
taskkill /F /FI "WINDOWTITLE eq ##CheckCPU##" /T  
genügen - allerdings gibt es "taskkill" erst seit XP, und ich vermute (wissen kann ich's ja nicht face-wink), dass Du W2000 verwendest ...

Grüße
bastla
megamazl
megamazl 23.08.2008 um 22:37:26 Uhr
Goto Top
juhuuuu, vielen vielen Dank, es funktioniert.
Übrigens ich hab XP Pro. wünsche die ein frohes Wochenende
bastla
bastla 23.08.2008 um 22:45:31 Uhr
Goto Top
Hallo megamazl!

Übrigens ich hab XP Pro
Schade eigentlich - jetzt hätte ich gerade einen Ansatz für W2000 ...

... den ich aber trotzdem poste: face-wink
Dazu müsste die "starter.bat" mit einem Parameter gestartet werden, also etwa
start starter.bat ##CheckCPU##
Danach könnte per VBScript die verwendete Commandline (bzw der relevante Teil) zum Finden und dann Terminieren (klingt weniger brutal als "Killen" face-wink) des Prozesses verwendet werden, also etwa:
strComputer = "."   
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")   
Set colItems = objWMIService.ExecQuery( _
   "SELECT * FROM Win32_Process WHERE CommandLine LIKE '%##CheckCPU##%'",,48)   
For Each objItem in colItems 
    objItem.Terminate
Next
Natürlich sollte die Kennung (also etwa "##CheckCPU##") so gewählt werden, dass es keine Verwechslung mit einem anderen Prozess geben kann (gilt auch für die "taskkill"-Variante).

Grüße
bastla

P.S.: Auf W2000 hatte ich getippt, weil Du "kill" verwenden wolltest ...