Sprachausgabe per VBS

Manchmal sitzt man einfach so herum und hat Langeweile. Dabei bin ich auf die Idee gekommen, dass man doch einfach mal fröhlicheren Anwender schaffen kann mit kleinen Nettigkeiten, die kein Aufwand sind.

Zum Beispiel kann man den Mitarbeitern GeburtstagsgrĂŒĂŸe beim Start des Rechners akustisch zukommen lassen. Hier ein kleines Beispiel:

Set objNetwork = CreateObject("Wscript.Network")
Set sprache = CreateObject("SAPI.SpVoice")
sprache.Volume = 100
sprache.speak "Herzlichen GlĂŒckwunsch zum Geburtstag!"

Die LautstĂ€rke wird auf 100 Prozent fĂŒr die Programmart Windows Scripting Host gestellt. Mute wird nicht aufgehoben.

Vielleicht hat der eine oder andere auch interessante Ideen fĂŒr Umsetzungen. Eine Erweiterung mit dem Anwendernamen wĂ€re natĂŒrlich auch denkbar.

Umrechnung von Bytes in grĂ¶ĂŸere Einheiten

Bei einigen Auswertungen oder Abfragen per Visual Basic oder anderen Skriptsprachen erhĂ€lt man DatengrĂ¶ĂŸen in Bytes.
Nun werden diese Zahlen zuweilen sehr lang, so dass man diese zur vernĂŒnftigen Darstellung umrechnen sollte.
Dabei soll folgende Umrechnungstabelle unterstĂŒtzen:

  • 1 KiloByte sind 1024 Bytes
  • 1 MegaByte sind 1048576 Bytes
  • 1 GigaByte sind 1073741824 Bytes
  • 1 TerraByte sind 10995116277776 Bytes

Entsprechend mit diesen Angaben können die Werte in die erforderlichen GrĂ¶ĂŸeneinheiten umgerechnet werden.

VBS: IMEI der WWAN-Karte ermitteln

In einem Projekt gab es die Aufgabe die IMEI-Nummer der verbauten UMTS-Karte zu ermitteln. Dieses ist per NETSH-Befehl möglich, was allerdings automatisiert durchgefĂŒhrt werden sollte.

Anbei das Skript, was die IMEI-Nummer als Messagebox ausgibt:

    Option Explicit
 
    Dim IMEI, IMEIID
    Dim cmdquery
    Dim oShell
    Dim Result, strLine
    Dim Flag
 
    Set oShell = CreateObject("WSCript.Shell")
 
    cmdquery = "netsh mbn sh int"
 
    Flag = False
 
    Set Result = oShell.Exec(cmdquery)
 
    Set IMEI = Result.StdOut
 
    While Not IMEI.AtEndOfStream
       strLine = IMEI.ReadLine
       If InStr(strLine, "Mobile Breitbandverbindung") Then
        Flag = True
       End If
       If Flag = True Then
         If InStr(strLine, "Ger„te-ID          :") Then
          IMEIID = Trim(strLine)
          IMEIID = Right(IMEIID, Len(IMEIID)-21)
        Msgbox(IMEIID)
	Flag = False
         End If
       End If
    Wend

Statt der MessageBox kann der Wert auch weitergenutzt oder an andere Programme weitergegeben werden. Dieses ist derzeit nur unter Windows 7 (deutsch) getestet. FĂŒr andere Sprachen sind Anpassungen erforderlich

MessageBox per Batch-Datei anzeigen

Über eine Batchdatei sollte ein Hinweisfenster angezeigt werden. Dieses habe ich wie folgt realisiert:

@echo off
echo msgbox"Text der MessageBox",vbInformation , "Titel der Messagebox"> %temp%\msg.vbs 
%Temp%\msg.vbs 
erase %temp%\msg.vbs

Es können natĂŒrlich auch weitere Zeilen eingefĂŒgt werden, so dass auch eine Abfragesteuerung nach „OK“ und „Abbrechen“ genutzt werden kann. SelbstverstĂ€ndlich kann auch wie sonst unter VBS das Design definiert werden. Unter anderem das Hinweiszeichen hier im Beispiel als Information (vbInformation).

Nach der Abarbeitung wird das Skript auch vom System gelöscht.

VBS: Bitlocker-Key erneut in AD speichern

Wenn man die Bitlocker-WiederherstellungsschlĂŒssel in der DomĂ€ne speichert, kann es zu dem Fall kommen, dass ein Computerobjekt keinen SchlĂŒssel zur VerfĂŒgung hat, obwohl das System selber sich trotzdem in der DomĂ€ne befindet.

Meistens passiert dieses, wenn ein Rechner-Objekt in der DomĂ€ne gelöscht wird und wieder aufgenommen wird. Bei der DomĂ€nenaufnahme wird der BitlockerschlĂŒssel nicht wieder an den DomĂ€nencontroller ĂŒbergeben. Dieses kann aber durch ein VBS-Skript durchgefĂŒhrt werden. 

Ich veröffentliche hier das Skript unter Nutzung von „Deutsch“ als Displaysprache. Das von Microsoft verfĂŒgbare Skript ist auf Englisch ausgelegt und wurde von mir angepasst.

    Option Explicit
 
    Dim strNumericalKeyID
    Dim strManageBDE,strManageBDE2
    Dim oShell
    Dim StrPath
    Dim StdOut, strCommand
    Dim Result, TPM, strLine
    Dim Flag, NumericalKeyID
 
    Set oShell = CreateObject("WSCript.Shell")
 
    strManageBDE = "Manage-BDE.exe -protectors -get c:"
 
    Flag = False
 
    Set Result = oShell.Exec(strManageBDE)
 
    Set TPM = Result.StdOut
 
    While Not TPM.AtEndOfStream
       strLine = TPM.ReadLine  'Sets strLine
       If InStr(strLine, "Numerisches Kennwort:") Then  
        Flag = True
       End If
       If Flag = True Then
         If InStr(strLine, "ID:") Then 
          NumericalKeyID = Trim(strLine)
          NumericalKeyID = Right(NumericalKeyID, Len(NumericalKeyID)-4)
          Flag = False
         End If
       End If
    Wend
 
    strManageBDE2 = "Manage-BDE.exe -protectors -adbackup C: -ID " & NumericalKeyID
    oShell.Run strManageBDE2, 0, True

Dieses Skript kann auch automatisiert regelmĂ€ĂŸig ausgefĂŒhrt werden, da der WiederherstellungsschlĂŒssel mit dem entsprechenden Datum seiner Erstellung in der AD gespeichert wird und nicht bei jeder Übermittlung des entsprechenden Wertes. Somit kann eine Ablage dieses wichtigen Objektes in der Active Directory gewĂ€hrleistet werden ohne zusĂ€tzliches Datenvolumen in der AD aufzubauen.

Alle DomÀnengruppen inkl. Mitglieder in HTML auflisten

Aufgrund von umfangreicher Benutzerlöschungen habe ich einen Report erstellen wollen, welcher Benutzer in welcher Gruppe als Mitglied zum aktuellen Zeitpunkt eingebunden ist.

DafĂŒr habe ich ein sehr angenehmes VBS-Skript gefunden, welches ich minimal fĂŒr die Abfrage des Managers erweitert habe. Der Report selber wird als HTML-Datei angelegt.

' DocumentGroups.vbs
' VBScript program to document all groups in Active Directory.
' Outputs group name, type of group, all members, and types of member.
' Lists all groups that are members, but does not list the nested group
' membership.
'----------------------------------------------------------------------
' Copyright (c) 2002 Richard L. Mueller
' Hilltop Lab web site - http://www.rlmueller.net
' Version 1.0 - November 10, 2002
' Version 1.1 - February 19, 2003 - Standardize Hungarian notation.
' Version 1.2 - March 11, 2003 - Remove SearchScope property.
 
' *** MODIFIED March 13, 2006 - Added HTML File Out, Addtional Group/User Properties
'
' This script is designed to be run at a command prompt, using the
' Cscript host. The output can be redirected to a text file.
' For example:
' cscript //nologo DocumentGroups.vbs > groups.txt
'
' You have a royalty-free right to use, modify, reproduce, and
' distribute this script file in any way you find useful, provided that
' you agree that the copyright owner above has no warranty,obligations,
' or liability for such use.
'
' Version 1.3 - June 25, 2012 - Added attribute "managedby" by Daniel Lensing
 
Option Explicit
 
Dim objConnection, objCommand, objRootDSE, strDNSDomain, strQuery
Dim objRecordSet, strDN, objGroup
Dim FileSystem, oFile
' Open Text File for Output
Set FileSystem = WScript.CreateObject("Scripting.FileSystemObject")
Set oFile = FileSystem.CreateTextFile("GroupMemebrshipNew.html", True)
 
oFile.writeLine "<HTML><HEAD><TITLE>Group Membership for MyDomain.com</TITLE><HEAD><BODY>"
oFile.writeLine "<h4><TABLE width=100% border=0 padding=0 cellspacing=0 valign=top>"
 
 
' Use ADO to search Active Directory.
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
 
' Determine the DNS domain from the RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
 
' Search for all groups, return the Distinguished Name of each.
strQuery = "<LDAP://" & strDNSDomain _
& ">;(objectClass=group);distinguishedName;subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False
 
Set objRecordSet = objCommand.Execute
If objRecordSet.EOF Then
Wscript.Echo "No groups found"
objConnection.Close
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Wscript.Quit
End If
 
' Enumerate all groups, bind to each, and document group members.
Do Until objRecordSet.EOF
strDN = objRecordSet.Fields("distinguishedName")
Set objGroup = GetObject("LDAP://" & strDN)
 
' OUTPUT
oFile.writeLine "<TR>"
oFile.writeLine "<TD width=20% valign=top bgcolor=black><font color=white><strong><u>" & "Group Name:" &_
"</u></strong></font></TD><TD width=80% valign=top><strong>" &_
objGroup.SAMaccountName & "</strong></TD>"
oFile.writeLine "</TR><TR>"
oFile.writeLine "<TD valign=top bgcolor=black><font color=white><strong><u>" & "Distinguished Name:" &_
"</u></strong></font></TD><TD valign=top><strong>" &_
objGroup.distinguishedName & "</strong></TD>"
oFile.writeLine "</TR><TR>"
oFile.writeLine "<TD valign=top bgcolor=black><font color=white><strong><u>" & "Description:" &_
"</u></strong></font></TD><TD valign=top><strong>" &_
objGroup.description & "</strong></TD>"
oFile.writeLine "</TR><TR>"
oFile.writeLine "<TD valign=top bgcolor=black><font color=white><strong><u>" & "Manager:" &_
"</u></strong></font></TD><TD valign=top><strong>" &_
objGroup.managedby & "</strong></TD>"
oFile.writeLine "</TR><TR>"
oFile.writeLine "<TD valign=top bgcolor=black><font color=white><strong><u>" & "Type:" & "</u></strong></font></TD><TD valign=top><strong>" & GetType(objGroup.groupType) & "</strong></TD>"
oFile.writeLine "</TR>"
 
oFile.writeLine "<TR><TD valign=top bgcolor=black><font color=white><strong><u>Members:</font></TD><TD align=left valign=top>"
oFile.writeLine "<TABLE width=70% border=0 cellspacing=0 cellpadding=0>"
oFile.writeLine "<Tr>"
oFile.writeLine " <TD valign=top><strong><u> Name </u></strong></TD>"
oFile.writeLine " <TD valign=top><strong><u> Account </u></strong></TD>"
oFile.writeLine " <TD valign=top><strong><u> Type </u></strong></TD>"
oFile.writeLine "</Tr>"
Call GetMembers(objGroup)
oFile.writeLine "</TABLE>"
 
oFile.writeLine "</TD></TR>"
 
oFile.writeLine "<TR><TD COLSPAN=2><hr width=90%></TD></TR>"
 
 
objRecordSet.MoveNext
 
Loop
oFile.writeLine "</TABLE></BODY></HTML>"
 
msgBox "Done !!!"
 
' Clean up.
objConnection.Close
Set objRootDSE = Nothing
Set objGroup = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
 
Function GetType(intType)
' Function to determine group type from the GroupType attribute.
If (intType And &h01) <> 0 Then
GetType = "Built-in"
ElseIf (intType And &h02) <> 0 Then
GetType = "Global"
ElseIf (intType And &h04) <> 0 Then
GetType = "Local"
ElseIf (intType And &h08) <> 0 Then
GetType = "Universal"
End If
If (intType And &h80000000) <> 0 Then
GetType = GetType & "/Security"
Else
GetType = GetType & "/Distribution"
End If
End Function
 
Sub GetMembers(objADObject)
' Subroutine to document group membership.
' Members can be users or groups.
Dim objMember, strType
For Each objMember In objADObject.Members
If UCase(Left(objMember.objectCategory, 8)) = "CN=GROUP" Then
strType = "Group"
Else
strType = "User"
End If
 
' OUTPUT
 
oFile.writeLine "<TR>"
oFile.writeLine "<TD valign=top>" & objMember.displayName & _
"</TD><TD valign=top>" & objMember.SAMaccountName & _
"</TD><TD valign=top>" & strType & "</TD>"
oFile.writeLine "</TR>"
' Wscript.Echo " Member: " & objMember.sAMAccountName & " (" & strType & ")"
Next
Set objMember = Nothing
End Sub

VBS: Zugriff auf andere DomÀnen mit Authentifizierung

In einigen meiner Skripte nutze ich auch DomĂ€nenfunktionen, sie ich ĂŒber VBS ansteuere. Dabei nutze ich im Standardfall folgende Zeile, um die Anbindung zum Active Directory zu bestimmen:

Set objRootDSE = GetObject ("LDAP://RootDSE")

Nun kann es vorkommen, dass man ein Skript auf einem System ausfĂŒhren möchte, welches sich in einer anderen DomĂ€ne befindet, aber durch einen DomĂ€nen-Trust im direkten Zugriff genutzt werden kann. Dabei Ă€ndert sich die Zeile zum Beispiel wie folgt:

Set objRootDSE = GetObject ("LDAP://domain.de/RootDSE")

Allerdings kann es ja auch sein, dass fĂŒr die entfernte DomĂ€nen keine Vertrauensstellung besteht und man eine Benutzerauthentifizierung machen muss. So muss dieses ebenfalls in der Zeile mitgegeben werden:

Set objRootDSE = GetObject ("LDAP://domain.de/RootDSE", "domain\scriptuser", "userpassword", 1)

Die benötigten Werte fĂŒr Benutzername und Passwort können natĂŒrlich auch ĂŒber Variablen oder Abfragen zur VerfĂŒgung gestellt werden.