joml
Goto Top

Befehl remote auf mehreren Clients ausführen

Hallo zusammen,

Folgende Ausgangslage:

Ich möchte per Batchdatei (wenn's geht ohne VB) auf 100 Clients überprüfen, ob es einen lokalen user mit dem Namen "Admin" oder "administrator" gibt.
Wenn ja, soll das Resultat in ein "result.txt" geschrieben werden.
Dies soll nicht per login oder Startscript geschehen sondern live... dass heisst wenn ich das Script starte, geht es auf jede Maschine und überprüft dies.

Die Namen der Clients sind in einer Liste "clients.txt".

Wie kann mann dies am besten bewerkstelligen..?

Vielen Dank für Eure Hilfe

Gruss
JOML

Content-ID: 83886

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

Ausgedruckt am: 25.11.2024 um 07:11 Uhr

funkmasta2k
funkmasta2k 25.03.2008 um 15:10:28 Uhr
Goto Top
Sind das denn alles XP Clients in Deinem Netzwerk?
JOML
JOML 25.03.2008 um 16:01:02 Uhr
Goto Top
Ouupps... sorry.
Na ja sagen wir mal zu 95%.. JA.. der Rest ist 2000.
funkmasta2k
funkmasta2k 25.03.2008 um 16:13:05 Uhr
Goto Top
Ok, weiß nicht ob das unter den 2000 Clients geht, aber nen Versuch ist es wert.

Zum Ausführen nimmst Du psExec

Kooperiert dank "@Datei" sogar mit Deiner Clients.txt

Dann kopiert Du auf alle Client folgende Batch:

@echo off
net user | findstr "Admin" > M:\%computername%.txt

M: steht jetzt für ein von mir erfundenes Netzlaufwerk. Somit sieht Du welche Clients den User
Admin oder Administrator bei sich auf dem System haben.

Du könntest Dir sogar noch eine Batch erstellen, die die obere Batch (nennen wir sie mal auslesen.bat) auf alle Clients kopiert:
@echo OFF
FOR /F %%a IN (clients.txt) DO (
copy C:\auslesen.bat \\%%a\c$\auslesen.bat
)
JOML
JOML 25.03.2008 um 16:33:17 Uhr
Goto Top
Hallo funkmasta2k,

Vielen Dank face-smile

Geht das auch irgendwie OHNE dass das Batch File auf den Client kopiert wird..?

Ziel ist es das ganze remote zu machen, ohne das irgend ein Tool etc lokal auf die Clients kopiert wird...


Gruss
JOML
funkmasta2k
funkmasta2k 25.03.2008 um 16:49:36 Uhr
Goto Top
Wenn es irgendwie möglich ist, würde ich es gerne wissen face-smile
Also ich wüsste da leider nichts!
miniversum
miniversum 25.03.2008 um 18:06:39 Uhr
Goto Top
Andere Möglichkeit (ungetestet)... Nötige Berechtigungen natürlich vorausgesetzt:
@echo off
FOR /F "delims=" %%i in (clients.txt) do(
echo Prüfe %%i
net use X: %%i /persistent:NO
dir "X:\Dokumente und Einstellungen\Admin*" && echo %%i Hat ein Adminkonto>>Gefundene.txt
net use X: /delete
)
JOML
JOML 25.03.2008 um 19:20:53 Uhr
Goto Top
Mhmm.. ich versuche gerade was in der Art von:

psexec.exe @clients.txt net user | findstr "Admin" >> result.txt

Da bekomme ich aber immer Fehlermeldungen wie:
net exited on clientX with error code 1.

Wenn ich noch user und Passwort dazu gebe kommt error code 0.
Kommt immer ein Error Code..??

Gruss
JOML
funkmasta2k
funkmasta2k 25.03.2008 um 20:03:41 Uhr
Goto Top
@miniversum
Gute Idee, aber sollte es nen User Admin* geben und der hat sich nie eingeloggt,
so wird dieser leider auch nicht ausgegeben, da der Ordner ja nie erstellt worden ist.

@JOML
Ich glaube das hat was mit der "Umleitung" zu tun.
JOML
JOML 29.03.2008 um 19:19:38 Uhr
Goto Top
Danke für die Tipp's..
Aber irgendwie komm ich da leider nicht weiter.

Der Einwand von "funkmasts2k" ist berechtigt. Wenn sich ncoh niemand mit diesem Konto eingeloggt hatte... gibt's auch diesen Ordner nicht. Ich muss aber sicherstellen, dass wirklich ausgegeben wird, wenn sich ein Konto mit dem Namen "Admin*" auf dem Rechner befindet.

Habe noch grössere Probleme mit der Ausgabe im txt File.
Aussehen sollte es in etwa so:

Computer1
Admin

Computer2
Administrator

Computer3
Administrator
Admin_Z

usw.

Ist auf diesem Computer kein solches Konto zu finden, gibts einfach keinen Eintrag.

Und jedes mal erscheint diese error Meldung "net exited on clientX with error code 1 (oder 0)"


Vielen Dank für Eure Hilfe.
JOML
JOML
JOML 30.03.2008 um 13:47:20 Uhr
Goto Top
So.. ich habe mir mal ein (das erste face-smile ) WMI Script zusammengebastelt. Hab mir z.T die einzelnen Befehle hier aus dem Forum herausgesucht. Ich hoffe das Script ist einigermassen OK.. funktionieren tut's jedenfalls nicht schlecht face-smile

On Error Resume Next

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set fso = CreateObject("Scripting.FileSystemObject")
Set oCList = fso.OpenTextFile("C:\Scripts\LocalAccounts\clients.txt", 1)
Do While Not oCList.AtEndOfStream
strComputer = oCList.ReadLine
WScript.Echo
WScript.Echo "=========================================="
WScript.Echo strComputer
WScript.Echo "=========================================="

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_UserAccount", "WQL", _
wbemFlagReturnImmediately + wbemFlagForwardOnly)

For Each objItem In colItems
WScript.Echo objItem.Name
WScript.Echo
Next

Loop
oCList.Close


Leider habe ich da aber noch ein paar Fragen:

1. Braucht es die beiden Linien "Const wbem..." ?

2. Wie/Wo kann ich da ein "Ping" Befehl einbauen (Wenn 2xPing keine Antwort =go to next client)?

3. Zum Ausführen gebe ich folgendes ein:
cscript /nologo localAccounts.vbs > result.txt

Das funktioniert auch bestens... nur sehe ich leider keinen Status im CMD Fenster. Erst wenn alle durch sind springt das Script wieder auf C:\.
Kann mann da irgendwie einen Status ausgeben lassen wie z.B "36 from 266 Clients done".. oder so..?

Vielen Dank

Gruss
JOML
miniversum
miniversum 30.03.2008 um 17:29:35 Uhr
Goto Top
Du kanst dir die umleitung mit >results.txt sparen wenn du in der VBS datei direkt in die datei schreibst UND zusätzlich eine ausgabe auf dem Bildschirm machst.

Eine andere Möglichkeit wäre einfach das ganze so von der Eingabeaufforderung aufzurufen:
FOR /F "delims=" %i in ('cscript /nologo localAccounts.vbs') do (@echo %i & echo %i>>results.txt)
in einer Batch dann die %% durch %% ersetzen.
JOML
JOML 30.03.2008 um 17:55:02 Uhr
Goto Top
Du kanst dir die umleitung mit
>results.txt sparen wenn du in der VBS
datei direkt in die datei schreibst UND
zusätzlich eine ausgabe auf dem
Bildschirm machst.

Das ist ja was ich im Punkt 3 Angefragt hatte... wie..?
Vor allem das ich im CMD Fenster einen Status habe (wie oben geschrieben; "36 from 266 Clients done").


Eine andere Möglichkeit wäre
einfach das ganze so von der
Eingabeaufforderung aufzurufen:
> FOR /F "delims=" %i in
('cscript /nologo
localAccounts.vbs') do (@echo %i &
echo %i>>results.txt)

Das bringt mir leider auch nicht den oben Angefragten Effekt betreffend Ausgabe face-sad
Da erscheint die Ausgabe völlig durcheinander am Bildschirm

in einer Batch dann die %% durch %%
ersetzen.

Ähhm... %% durch %% ersetzten..??
bastla
bastla 30.03.2008 um 18:24:27 Uhr
Goto Top
Hallo JOML!

Versuch es einmal mit dieser Variation Deines Scripts:
On Error Resume Next

Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

Set fso = CreateObject("Scripting.FileSystemObject")  
Set oCList = fso.OpenTextFile("C:\Scripts\LocalAccounts\clients.txt", 1)  
Set oRList = fso.OpenTextFile("C:\Scripts\LocalAccounts\results.txt", 2, True)  

Clients = Split(oCList.ReadAll, vbCrLF)
oCList.Close

U = UBound(Clients)
Do While Clients(U) = ""  
	U = U - 1
Loop

For i = 0 To U
	strComputer = Clients(i)
	WScript.Echo Right("   " & CStr(i + 1), 3) & "/" & CStr(U + 1) & ": " & strComputer  

	If Ping(strComputer) Then
		Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")  
		Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_UserAccount WHERE Name LIKE 'Admin%'", "WQL", _  
		wbemFlagReturnImmediately + wbemFlagForwardOnly)

		For Each objItem In colItems
			oRList.WriteLine strComputer & vbTab & objItem.Name
		Next
	Else
		oRList.WriteLine strComputer & vbTab & "### nicht erreichbar ###"  
	End If
Next
oRList.Close

Function Ping(machine)
PingResult = True
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._  
	ExecQuery("select * from Win32_PingStatus where address = '" & machine & "'")  
For Each objStatus in objPing
	If IsNull(objStatus.StatusCode) Or objStatus.StatusCode <> 0 Then 
		PingResult = False
	End If
Next
Ping = PingResult
End Function
Hier wird, wie auch von miniversum vorgeschlagen, durch das Script selbst in die Zieldatei geschrieben, sodass Du es tatsächlich ohne Umleitung der Ausgabe starten kannst.

Erfasst werden nur Computer mit den entsprechenden Konten sowie nicht erreichbare Clients.

Grüße
bastla
JOML
JOML 30.03.2008 um 18:49:49 Uhr
Goto Top
Hallo bastla,

Die Ausgabe im CMD Fenster ist genial face-smile face-smile
Genau was ich gesucht hatte. Vielen, vielen Dank !

Jetzt habe ich nur das Problem, dass bei allen Clients, die voher funktionert hatten, nur der folgende Eintrag im "result.txt" steht:
Client1 "### nicht erreichbar ###"
Client2 "### nicht erreichbar ###"
Client3 "### nicht erreichbar ###"

Voher (das obenstehende Script):
Client1
User1

User2

User3

Client2
User1

User2

User3

Client3
User1

User2

User3


Wenn man das jetzt irgendwie verbinden könnte...PERFEKT.

NACHTRAG:
Ich hab jetzt das Script nochmals angeschaut... GENIAL.. da ist ja auch schon die Abfrage für Admin* drin. Es ist PERFEKT. face-smile face-smile
Kann man den Ping intervall verlängern...? Ich vermute, das darum "### nicht erreichbar ###" erschien.


Gruss
JOML
bastla
bastla 30.03.2008 um 19:06:31 Uhr
Goto Top
Hallo JOML!

Client1 "### nicht erreichbar ###"
sollte eigentlich nur eingetragen werden, wenn kein "ping" möglich war.

Lässt Du das Script auf einem W2000 laufen? Dort ist "Win32_PingStatus" nicht verfügbar, was aber wegen des "On Error Resume Next" zu keinem angezeigten Fehler führt - lass das "On Error" doch einmal weg ...
Um wieder sämtliche User der einzelnen Clients (und nicht nur solche, deren Namen mit "Admin" beginnen) angezeigt zu bekommen, müsstest Du nur wieder das
WHERE Name LIKE 'Admin%'  
aus der "Set colItems ..."-Zeile entfernen.

Die Ausgabe wird aber leichter auswertbar (zB über Excel), wenn, wie derzeit vorgesehen, für jeden User eine Zeile
Client<TAB>Username
in die Ergebnisdatei geschrieben wird. Um zu Deiner ursprünglichen Ausgabe zurückzukehren, musst Du nur die entsprechenden "WScript.Echo"-Zeilen in die Datei schreiben, also zB
oRList.WriteLine "=========================================="  
(nach der Zeile "If Ping(strComputer) Then" einfügen) verwenden.

Grüße
bastla

[Edit]
Hatte Deinen Nachtrag zu spät gesehen ...

Nachtrag meinerseits: Auch die zu pingenden Clients müssten mind XP verwenden ...
[/Edit]
JOML
JOML 30.03.2008 um 19:19:27 Uhr
Goto Top
Hallo Bastla,

Auf den 9 Testclients, auf denen ich jetzt getestet hatte + der Client von wo das Script läuft, ist XP Pro installiert..
Leider haben wir auch (noch) ein paar 2000er Clients.

gruss
JOML
bastla
bastla 30.03.2008 um 19:19:40 Uhr
Goto Top
Hallo JOML!

Um das "Pingen" in den Griff zu bekommen, tausche bitte die entsprechende Function gegen
Function Ping(machine)
Set objShell = CreateObject("WScript.Shell")  
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & machine)  
strPingResults = LCase(objExec.StdOut.ReadAll)
If InStr(strPingResults, "antwort von") Then  
	Ping = True
Else
	Ping = False
End If
End Function
Dadurch wird auf den CMD-"Ping" zurückgegriffen (siehe die Parameter in der Zeile "Set objExec = ...").

Nachzulesen ist das Ganze hier.

Grüße
bastla
JOML
JOML 31.03.2008 um 01:12:41 Uhr
Goto Top
Hallo zusammen,

Vielen, vielen Dank an alle (vor allem an bastla) die mir bei diesem Problem geholfen haben.
Jetzt funktionierts perfekt face-smile

Gruss
JOML

PS:
Vieleicht kann mir jemand da einen guten Tipp geben.. face-smile
Script Tools VB-WMI für Anfänger