|
VB Script Grundlagen |
VB Script ist eine sehr leistungsfähige Scriptsprache für moderne Windows Betriebssysteme. Windows XP hat den Visual Basic Interpreter standardmäßig dabei.
Für andere Betriebssystem ist er nachinstallierbar. Es gibt 2 unterschiedliche Interpreter für vbs Dateien. cscript - Standardausgabe auf der Kommandozeile wscript - Standardausgabe als Windows MessageBox Fenster Start am einfachsten mit: cscript test.vbs in der Kommandozeile (Ausführen \ cmd) Wer die 2 Infozeilen nicht gebrauchen kann, verwendet: cscript //Nologo test.vbs |
BeispieleBeispieleDomäne, Computername und User anzeigen Programm starten Programm starten und Priorität ändern Programm mit höherer Priorität starten Die Priorität eines Prozesses für einen bestimmten Service ändern Äbhängigkeiten eines Dienstes anzeigen (Dependencies) CPU Infos Betriebssystem Infos Listenstarter - Run Once E-Mail Sender Timestamp einer Datei ändern DOS Fehlercode (Errorlevel) Beschreibung ermitteln Check Version Read Textfile (ANSI or Unicode) Ping mit WMI BIOS Info - Zeige alle Infos der Objektinstanz |
Domäne, Computername und User anzeigen Als einfache Übung nur ein paar Informationen anzeigen: Set oWSH = CreateObject("WScript.Network") WScript.Echo "Domäne = " & oWSH.UserDomain WScript.Echo "Computername = " & oWSH.ComputerName WScript.Echo "Benutzername = " & oWSH.UserName Download Programm starten Startet Programme und meldet Statuscode zurück... Dim oShell, oExec Set oShell = CreateObject("WScript.Shell") Set oNotepad = oShell.Exec("notepad") Set oCalc = oShell.Exec("calc") Do While oNotepad.Status = 0 WScript.Sleep 1000 Loop WScript.Echo oNotepad.Status WScript.Echo oCalc.Status Download Programm starten und Priorität ändern Startet ein Programm und ändern die Prozesspriorität. Das ganze ist nützlich wenn man durch einen rechnintensiven Hintergrundprozess sich nicht in der Arbeit einschränken lassen will. sProgram2run="c:\windows\notepad.exe" sProgramEXE = LCase(Mid(sProgram2run,InStrRev(sProgram2run,"\")+1)) sComputer = "." Const Low = 64 Set oShell = WScript.CreateObject("WScript.Shell") oShell.Run sProgram2run Set oWMI= GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2") set colProcesses = oWMI.ExecQuery ("Select * from Win32_Process where Name='" & sProgramEXE & "'") For Each objProcess in colProcesses i=i+1 y=objProcess.SetPriority(Low) if y<>0 then wscript.echo "Error: " & y next wscript.echo "Found " & i & " processes named " & sProgramEXE 'So, das wars auch schon, hier noch zur Referenz: 'RealTime = 128 'High = 256 'Above_Normal = 32768 'Normal = 32 'Below_Normal = 16384 'Low = 64 'Und die Return Codes von SetPriority '0 Successful completion '2 Access denied '3 Insufficient Privilege '8 Unknown Failure '9 Path Not Found '21 Invalid Parameter Download Oder gleich mit höherer Priorität starten Oder gleich mit der angegebenen Priorität starten: Const ABOVE_NORMAL = 32768 Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set objStartup = oWMI.Get("Win32_ProcessStartup") Set objConfig = objStartup.SpawnInstance_ objConfig.PriorityClass = ABOVE_NORMAL Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process") objProcess.Create "Notepad.exe", Null, objConfig, intProcessID Download Die Priorität eines Prozesses für einen bestimmten Service ändern (Bsp.: WUA - Windows Update Agent auf Prio Low setzen) Oft wäre ganz nett wenn man die Priorität eines Services (dt: Dienst) ändern könnte. So einfach ist des aber nicht immer. Zuerst muß man zu einem Service die zugehörige 'handelsübliche' ;-) Prozess ID ermitteln. Dann kann man die Priorität diese Prozesses ändern. Hier ein Bespiel mit dem man den zuständigen Prozess für den Automatische Update Dienst auf Niedrig setzt. Dazu sind allerdings Systemrechte notwendig (System User). Dazu ruft man die CMD mit psxec -s cmd auf. (aus PSTools von SysInternals.Com) Dim objWMI, objServiceList, objService, objProcessList, objProcess Dim intProcID, intRet Dim strServiceName strServiceName = "wuauserv" intPriority = 64 '64 - Low, siehe oben Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set objServiceList = objWMI.ExecQuery ("Select * from Win32_Service where Name='" & strServiceName & "'") For Each objService in objServiceList intProcID = objService.ProcessId If intProcID<>0 Then WScript.Echo "Found service " & sService & " with Process ID " & intProcID set objProcessList = objWMI.ExecQuery ("Select * from Win32_Process where ProcessId='" & intProcID & "'") For Each objProcess in objProcessList intRet=objProcess.SetPriority(intPriority) If intRet=0 Then WScript.Echo "Changed priority of Process ID " & intProcID & " to level " & intPriority & " without error." Else WScript.Echo "Changing priority of Process ID " & intProcID & " returns code " & intRet & "." End If Next Else WScript.Echo "No " & strService & " service found." End If Next Download In dem Fall 'serviced' der svchost.exe Prozess eine ganze Reihe von Diensten. Um alle Dienste dieser svchost.exe Instanz anzuzeigen dient das folgende Script: Zuerst wird die Prozess ID des WUA Dienstes gesucht. Dann werden alles Dienste mit der selben Prozess ID gesucht. strService = "wuauserv" Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set objServiceList = objWMI.ExecQuery ("Select * from Win32_Service where Name='" & sService & "'") For Each objService in objServiceList intProcID = objService.ProcessId If intProcID<>0 Then wscript.echo "Found service " & sService & " with Process ID " & intProcID Else wscript.echo "No " & sService & " service found." End If Next Set objServiceList = objWMI.ExecQuery ("Select * from Win32_Service where ProcessID='" & intProcID & "'") intProcCounter=0 For Each objService in objServiceList intProcCounter = intProcCounter+1 intProcID = objService.ProcessId strOut = objService.Name intLeer = 20-Len(strOut) if intLeer<1 then intLeer=0 WScript.Echo strOut & Space(intLeer) & " " & objService.PathName Next wscript.echo "Found " & intProcCounter & " Processes" Download Will man andere Dienste nicht beeinflussen, muß man den Typ des Dienstes in der Registry ändern: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv Type=0x10 (Standard=0x20 - jeweils Hex, siehe Microsoft) Anschließend den Dienst stoppen und neu starten... Es ist auch mit Hilfe des Befehls sc möglich einen Dienst - z.B. den Windows Update Agent zu separieren: sc config wuauserv type= own sc stop wuauserv sc start wuauserv Das Leerzeichen nach type= nicht vergessen! Der Dienst wird dann WUA - Servicetyp und Prozesspriorität ändern Hier das Komplettpaket um den Windows Update Agent in einer eigenen Instanz von svchost.exe laufen zu lassen und anschließend die Prozess Priorität auf Low zu ändern: Zum Start (Prio ändern funktioniert nur mit Systemuser Rechten, siehe oben) - z.B. psexec -s cscript change_wua_priority.vbs (korrekten Pfad voranstellen) Download change_wua_priority.vbs Abhängigkeiten (Dependencies) eines Dienstes anzeigen Wie kann man mit Hilfe von WMI die Abhängigkeiten eines Dienstes herausfinden? Ok, wie findet man es überhaupt so raus? Start > Ausführen > compmgmt.msc > Dienste & Anwendungen > Dienste - einen Dienst auswählen und dann auf Abhängigkeiten klicken. Screenshot sService="Winmgmt" If WScript.Arguments.Count = 1 Then If WScript.Arguments(0) = "/?" Then WScript.Echo "Service Dependencies - shows all antencedents and dependents of a service" & vbNewLine WScript.Echo WScript.ScriptName & " <service name>" Else sService = WScript.Arguments(0) End If End If Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 'Antencedents Set oServiceList = oWMI.ExecQuery("Associators of {Win32_Service.Name='" & sService & "'} WHERE AssocClass=Win32_DependentService Role=Antecedent" ) sOut = sOut & "Antecedents of Service " & sService & ":" & vbNewLine For each oService in oServiceList sOut = sOut & " " & oService.Name & vbNewLine Next 'Dependents sOut = sOut & "Dependents of Service " & sService & vbNewLine Set oServiceList = oWMI.ExecQuery("Associators of {Win32_Service.Name='" & sService & "'} WHERE AssocClass=Win32_DependentService Role=Dependent" ) For each oService in oServiceList sOut = sOut & " " & oService.Name & vbNewLine Next WScript.Echo sOut Download CPU Infos Einige Informationen über die CPU mittels WMI auslesen. strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Processor",,48) For Each objItem in colItems Wscript.Echo "CPU Name: " & objItem.Name Wscript.Echo "Socket: " & objItem.SocketDesignation Wscript.Echo "Max_Speed: " & objItem.MaxClockSpeed & " MHz" Next Download Betriebssystem Infos Einige Informationen über das Betriebssysteme anzeigen (auch mit WMI) strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2") Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem",,48) For Each objItem in colItems Wscript.Echo "Caption: " & objItem.Caption Wscript.Echo "Version: " & objItem.Version Wscript.Echo "CSDVersion: " & objItem.CSDVersion Wscript.Echo "OSLanguage: " & objItem.OSLanguage Wscript.Echo "CountryCode: " & objItem.CountryCode Wscript.Echo "SystemDrive: " & objItem.SystemDrive Wscript.Echo "WindowsDirectory: " & objItem.WindowsDirectory Wscript.Echo "SystemDirectory: " & objItem.SystemDirectory Next Download Listenstarter - Run Once Manchmal ist es nötig auf bestimmten Clients irgendetwas umzustellen. Oft hat man dazu eine Liste von Computernamen auf denen ein Script einmal ausgeführt werden soll. Hier ist eine einfache Möglichkeit die mit nur einer Liste auskommt. Man schreibt alle betroffenen Clients in die Textdatei, das Script schreibt in die Textdatei die erledigten Clients. Download VBS Datei Download Beispiel Liste E-Mail Sender Mit Hilfe von ein paar Zeilen CScript kann man ganz leicht eine E-Mail senden... Ach ja, sogar Attachments kann man anfügen: oEmail.AddAttachment "C:\Scripts\Output.txt" Set oEmail = CreateObject("CDO.Message") oEmail.From = "meineemail@absender.de" oEmail.To = "zieladresse@ibins.de" oEmail.Subject = "Automatic CScript E-Mail" oEmail.Textbody = "This E-Mail was sent by CScript" & vbNewLine & "www.bigerl.de" oEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 oEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "post.strato.de" oEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 oEmail.Configuration.Fields.Update oEmail.Send Download Timestamp einer Datei ändern Mit Hilfe von ein paar Zeilen CScript kann man auch ganz leicht den DateLastModified Zeitstempel einer Datei ändern. Das folgende Beispiel liest aus dem Verzeichnis a den Timestamp aller Dateien und schreibt ihn auf die Zieldatei im Verzeichnis b wenn die Zieldatei existiert. sSrcFolder = "c:\temp\a\" sTrgFolder = "c:\temp\b\" Set oFS = CreateObject("Scripting.FileSystemObject") Set oSrcFolder = oFS.GetFolder(sSrcFolder) Set oFiles = oSrcFolder.Files For Each oFile in oFiles If oFS.FileExists(sTrgFolder & oFile.Name) Then fReDateFile sTrgFolder & oFile.Name, oFile.DateLastModified Next Function fReDateFile(sFilepath, sTimestamp) Dim oApp, oFolder, oFileX iPosSep = InStrRev(sFilepath,"\") sFolder = Left(sFilepath,iPosSep) sFile = Mid (sFilepath,iPosSep+1) Set oApp = CreateObject("Shell.Application") Set oFolder = oApp.NameSpace(sFolder) Set oFileX = oFolder.ParseName(sFile) oFileX.ModifyDate = sTimestamp Set oApp = Nothing Set oFolder = Nothing Set oFileX = Nothing End Function Download |
DOS
Fehlercode (Errorlevel)
Beschreibung ermitteln Mit Hilfe dieser Funktion kann man die Beschreibung eines Fehlercodes in einer Variablen speichern. (Ausgabe des DOS Befehls: net helpmsg 2) Die Funktion Replace sorgt dafür das Ergebnis in einer Zeile steht. WScript.Echo "Beschreibung des Fehlercodes 2: " & fGetErrorDesc(2) Function fGetErrorDesc(iErrNumber) Dim oWSHGED, oExecGED Set oWSHGED = CreateObject("WScript.Shell") Set oExecGED = oWSHGED.Exec("net helpmsg " & iErrNumber) If Not oExecGED.StdOut.AtEndOfStream Then fGetErrorDesc = Replace(oExecGED.StdOut.ReadAll, vbNewline,"") If Not oExecGED.StdErr.AtEndOfStream Then fGetErrorDesc = Replace(oExecGED.StdErr.ReadAll, vbNewline,"") End Function Download Check Version Mit Hilfe dieser Funktion kann man leicht eine Version überprüfen. Versionsangaben sind meist 4 Zahlen durch einen Punkt getrennt. Dadurch kann einfach geprüft werden ob bestimmt Mindestvorraussetzungen von Systemkomponenten erfüllt sind. Function fCheckVersion(sCurVersion, sMinVersion) 'Returncode: -1 = error, 0 = current version is older, 1 = equal, 2 = current version is newer Dim bOlder, bNewer, aCurVersion, aMinVersion fCheckVersion = 1 If Len(sCurVersion) > 0 AND Len(sMinVersion) > 0 Then aCurVersion = Split(sCurVersion, ".") aMinVersion = Split(sMinVersion, ".") If UBound(aCurVersion) = 3 OR UBound(aMinVersion) = 3 Then For i = 0 To UBound(aCurVersion) If CInt(aCurVersion(i)) < CInt(aMinVersion(i)) Then bOlder = 1 If CInt(aCurVersion(i)) > CInt(aMinVersion(i)) Then bNewer = 1 If bOlder OR bNewer Then Exit For Next End If Else fCheckVersion = -1 End If If bOlder then fCheckVersion = 0 If bNewer then fCheckVersion = 2 End Function Download |
Read Textfile (ANSI or Unicode) Mit Hilfe des richtigen Parameters erkennt VBScript automatisch ob es sich um ANSI oder Unicode formatierte Textdateien handelt. Die letzte Zahl der OpenTextFile Methode bestimmt das Format: ANSI (normaler Text), -1 = Unicode, -2 = Automatisch Erkennung Set oFS = CreateObject("Scripting.FileSystemObject") Set oFile = oFS.OpenTextFile("C:\temp\textfile.txt", 1, ,-2) Download |
Ping mit WMI Mit Hilfe von WMI kann man einen Ping ausführen. (zum prüfen ob ein bestimmtes Netzwerk Gerät ansprechbar ist) Set oWMI = GetObject("WinMgmts:\\.\root\CIMV2") Set oPing = oWMI.ExecQuery("Select * From Win32_PingStatus where Address = 'localhost'") For Each oStatus in oPing If IsNull(oStatus.StatusCode) OR oStatus.StatusCode<>0 Then WScript.Echo "Client offline" Else Wscript.Echo "Client ONLINE" Wscript.Echo "Response Time: " & oStatus.ResponseTime Wscript.Echo "TTL: " & oStatus.ResponseTimeToLive Wscript.Echo "IP Address: " & oStatus.ProtocolAddress End If Next Download |
BIOS Infos - Beispiel für Show Instance of a object Mit Hilfe der Methode getObjectText_ kann der komplette Inhalt einer Objektinstanz ausgegeben werden: Set oWMI = GetObject("winmgmts:\\.") sWQL = "Select * From Win32_BIOS" Set oItems = oWMI.ExecQuery(sWQL) For Each oItem In oItems WScript.Echo oItem.getObjectText_ Next Download Beispiel |
Tools
Fiese Problemchen
Set oExec = oShell.Exec("\\server.de\share\a.vbs") Richtig ist: Set oExec = oShell.Exec("cscript.exe \\server.de\share\a.vbs")
iB = "22" If iA < iB Then WScript.Echo "go" Hier hilft: iB = CInt("22") |
Links |
Und noch mehr Links...
MSDN & TechNet Referenzen:
|