Post from September, 2005

How To Make My Script Terminal Server Aware?

Tuesday, 20. September 2005 20:04

In order to detect if a script was started in a terminal server session the script can check the SESSIONNAME environment variable which is only defined if the Terminal Services are installed on Windows 2000 Server, Windows Server 2003, and Windows XP clients (or newer). When a client connects via a RDP or ICA (Citrix) session, this variable is a combination of the connection name, i.e. "RDP-Tcp" or "ICA-Tcp", followed by a pound symbol "#" and then the session number in three figures "nnn". When logging on directly to the machine, this variable returns "Console".

The VScript function below returns True if the SESSIONNAME variable resolve to a value beginning with "RDP" or "ICA"

If fctCheckTS Then
	WScript.Echo "I am running on TS"
End If

Function fctCheckTS

	Dim objWsh
	Set objWsh = WScript.Shell

	Select Case Left(objWsh.ExpandEnvironmentStrings("%SESSIONNAME%"),3)
		Case "RDP", "ICA"   fctCheckTS = True
		Case Else           fctCheckTS = False
	End Select

End Function

Terminal Server aware batch files can use this approach:

CALL :Test-TermServer
IF %TermServer%==True ECHO I am running on TS
GOTO :EOF

:Test-TermServer
SETLOCAL

	SET _=False
	IF DEFINED SESSIONNAME (
		IF /I %SESSIONNAME:~,3%==RDP SET _=True
		IF /I %SESSIONNAME:~,3%==ICA SET _=True
	)

ENDLOCAL & SET TermServer=%_%
GOTO :EOF

Category:Cmd.exe Shell, Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Show The End Of a Text File (Tail)?

Saturday, 10. September 2005 23:27

The VBScript file below, Tail.vbs, shows the end (the last lines) of a text file.

During the read of the text file, instead of counting the lines, each line is pushed into a small, rotating stack held in a dynamic array (size = number of tail lines). At the end of file, the stack array is popped to echo the tail.

' ___________________________________________________________________
'
'  VBScript File:   Tail.vbs
'  Author:          Frank-Peter Schultze
'
'  Updates:         http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=80
'  Enhancement Req.
'  And Bug Reports: support@fpschultze.de
'
'  Built/Tested On: Windows 2003 Server
'  Requirements:    WSH: 1.0+
'
'  Purpose:         Show the end of a text file
'
'  Syntax:          Tail filename nn
'
'                     filename     The name of a text file.
'                     nn           The number of lines to be shown.
'
'  Last Update:     2005-06-06
' ___________________________________________________________________
'

Option Explicit

Const FOR_READING = 1

Dim objFs, objFile, strFileName, lngTail, i, aryLine, j

If WScript.Arguments.Count = 2 Then
  strFileName = WScript.Arguments(0)
  lngTail     = WScript.Arguments(1)
  Set objFs   = WScript.CreateObject("Scripting.FileSystemObject")
  If objFs.FileExists(strFileName) Then
    Set objFile = objFs.OpenTextFile(strFileName, FOR_READING)
    ReDim aryLine(lngTail)
    i = 0
    Do Until objFile.AtEndOfStream
      i = (i+1) Mod lngTail
      aryLine(i) = objFile.ReadLine
    Loop
    For j = 1 To lngTail
      i = (i+1) Mod lngTail
      If aryLine(i) = vbEmpty Then Exit For
      WScript.Echo aryLine(i)
    Next
  Else
    WScript.Echo "File not found - " & strFileName
  End If
Else
  WScript.Echo "Show the end of a text file."
  WScript.Echo ""
  WScript.Echo WScript.ScriptName & " filename nn"
  WScript.Echo ""
  WScript.Echo "  filename     The name of a text file."
  WScript.Echo "  nn           The numer of lines to be displayed."
End If

Category:Scripting, VBScript | Comments (1) | Author: Frank-Peter

How To Test WMI Connectivity?

Saturday, 10. September 2005 23:18

The VBScript file below, WMIPing.vbs, checks if connection to WMI of the target system can be established.

WMIPing.vbs exits with an errorlevel:

  • 0 = WMI Ping succeeded successfully
  • 1 = ICMP Ping failed, WMI Ping omitted
  • 2 = WMI Ping failed
' ___________________________________________________________________
'
'  VBScript File:   WMIPing.vbs
'  Author:          Frank-Peter Schultze
'
'  Updates:         http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=79
'  Enhancement Req.
'  and Bug Reports: support@fpschultze.de
'
'  Built/Tested On: Windows XP Prof.
'  Requirements:    OS: Windows 2000+ w/ WMI service started
'
'  Purpose:         Check if connection to WMI of the target system
'                   can be established
'
'  Syntax:
'
'  wmiping [systemname] [/n:namespace] [/u:account /p:password] [/q]
'
'    systemname       IP address, full DNS name, or NetBIOS name of
'                     the target system (default: localhost)
'    /n:namespace     WMI namespace (default: root\cimv2)
'    /u:account       Account to be used to connect to WMI
'    /p:password      Password from 'username'
'    /q               Quiet mode (no console output)
'
'  State Changes:
'
'  Possible errorlevels
'
'    0     WMI Ping succeeded successfully
'    1     ICMP Ping failed, WMI Ping omitted
'    2     WMI Ping failed
'
'  Assumptions And
'  Limitations:     -
'
'  Last Update:     10:47 23.07.2008
' ___________________________________________________________________
'

Option Explicit

On Error Resume Next

Const DEFAULT_COMPUTER  = "localhost"
Const DEFAULT_NAMESPACE = "root\cimv2"

Dim objLoc
Dim objWmi
Dim strSysname
Dim strNamespace
Dim strUsername
Dim strPassword
Dim blnQuiet

strSysname   = DEFAULT_COMPUTER
strNamespace = DEFAULT_NAMESPACE
strUsername  = ""
strPassword  = ""
blnQuiet     = False
Call subParseArgs(WScript.Arguments, strSysname, strNamespace, strUsername, strPassword, blnQuiet)
If fctIsAlive(strSysname) Then
 If Not blnQuiet Then
  WScript.Echo "ICMP Ping for " & strSysname & " passed."
  WScript.Echo "Connecting to namespace " & strNamespace & " . . ."
 End If
 Set objLoc = WScript.CreateObject("WbemScripting.SWbemLocator")
 Set objWmi = objLoc.ConnectServer(strSysname, strNamespace, strUsername, strPassword)
 If Err.Number Then
  If Not blnQuiet Then
   WScript.Echo "Unable to connect to WMI: " & Err.Description
  End If
  Err.Clear
  WScript.Quit(2)
 Else
  Set objWmi = Nothing
  Set objLoc = Nothing
  If Not blnQuiet Then
   WScript.Echo "WMI successfully connected."
  End If
  WScript.Quit(0)
 End If
Else
 If Not blnQuiet Then
  WScript.Echo "ICMP Ping for " & strSysname & " failed."
 End If
 WScript.Quit(1)
End If

Function fctIsAlive(strHostOrIP)

Dim objSh, objCmd, strCmd

strCmd     = "%ComSpec% /C %SystemRoot%\system32\ping.exe -n 1 " & strHostOrIP & " | " _
           & "%SystemRoot%\system32\find.exe /c /i " & Chr(34) & "ttl=" & Chr(34)
Set objSh  = WScript.CreateObject("WScript.Shell")
Set objCmd = objSh.Exec(strCmd)
fctIsAlive = CBool(Trim(objCmd.StdOut.ReadAll))
Set objCmd = Nothing
Set objSh  = Nothing

End Function

Sub subParseArgs(objArgs, strSysname, strNamespace, strUsername, strPassword, blnQuiet)

Dim i
Dim strArg
Dim blnNamed

For i = 0 To objArgs.Count - 1
 strArg   = Split(objArgs(i), ":")
 blnNamed = UBound(strArg)
 Select Case Left(strArg(0), 1)
  Case "/", "-"
   Select Case UCase(strArg(0))
    Case "/?", "/H", "-?", "-H"
     Call subUsageBox("help", True)
    Case "/N", "-N"
     If blnNamed Then
      strNamespace = Trim(strArg(1))
     Else
      Call subUsageBox("syntax error", True)
     End If
    Case "/U", "-U"
     If blnNamed Then
      strUsername = Trim(strArg(1))
     Else
      Call subUsageBox("syntax error", True)
     End If
    Case "/P", "-P"
     If blnNamed Then
      strPassword = Trim(strArg(1))
     Else
      Call subUsageBox("syntax error", True)
     End If
    Case "/Q", "-Q"
     If blnNamed Then
      Call subUsageBox("syntax error", True)
     Else
      blnQuiet = True
     End If
    Case Else
     Call subUsageBox("unknown argument: " & strArg(0), True)
   End Select
  Case Else
   If blnNamed Then
    Call subUsageBox("syntax error", True)
   Else
    strSysname = Trim(strArg(0))
   End If
 End Select
Next

End Sub

Sub subUsageBox(strTitle, blnQuit)

Dim strUsage

strUsage = WScript.ScriptName & " initially pings the target system. If the ping is successful " & vbNewLine
strUsage = strUsage & "it connects to the target system using WMI." & vbNewLine & vbNewLine
strUsage = strUsage & "Usage: " & WScript.ScriptName & " [systemname] [/n:namespace] [/u:account /p:password] [/q]" & vbNewLine & vbNewLine
strUsage = strUsage & "  systemname"   & vbTab & "IP address, full DNS name, or NetBIOS name of the" & vbNewLine
strUsage = strUsage & vbTab            & vbTab & "target system (default: " & DEFAULT_COMPUTER & ")" & vbNewLine
strUsage = strUsage & "  /n:namespace" & vbTab & "WMI namespace (default: " & DEFAULT_NAMESPACE & ")" & vbNewLine
strUsage = strUsage & "  /u:account"   & vbTab & "Account to be used to connect to WMI" & vbNewLine
strUsage = strUsage & "  /p:password"  & vbTab & "Password from 'username'" & vbNewLine
strUsage = strUsage & "  /q" & vbTab   & vbTab & "Quiet mode (no console output)" & vbNewLine & vbNewLine
strUsage = strUsage & "Possible errorlevels:" & vbNewLine & vbNewLine
strUsage = strUsage & "  0" & vbTab & "WMI Ping succeeded successfully." & vbNewLine
strUsage = strUsage & "  1" & vbTab & "ICMP Ping failed, WMI Ping omitted." & vbNewLine
strUsage = strUsage & "  2" & vbTab & "WMI Ping failed"
Call MsgBox(strUsage, vbOKOnly + vbInformation, WScript.ScriptName & " - " & strTitle)
If blnQuit Then
 WScript.Quit
End If

End Sub

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Copy The Standard Output To a File (Tee)?

Saturday, 10. September 2005 22:53

The VBScript file below, Tee.vbs, copies standard input to a file.

Basically, it reads a line from standard input (ie. WScript.StdIn) and writes it to both, standard output (WScript.StdOut) and a textstream object.

' ___________________________________________________________________
'
'  VBScript File:   Tee.vbs
'  Author:          Frank-Peter Schultze
'
'  Updates:         http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=78
'  Enhancement Req.
'  And Bug Reports: support@fpschultze.de
'
'  Built/Tested On: Windows 98 SE, Windows 2000
'  Requirements:    OS: Windows 95+, Windows NT4+
'                   WSH: 1.0+
'
'  Purpose:         Copy standard input to both standard output and a
'                   file.
'
'  Syntax:          Command | CSCRIPT Tee.vbs [-a] Filename
'
'                     -a     Append output to Filename.
'
'  State Changes:
'
'  Assumptions And
'  Limitations:     * There is a bug in Windows NT/2000 that causes
'                     command redirection to fail with an Error
'                     unless the WSH host is explicitly specified on
'                     the command line (regardless of default host
'                     selected). Therefore, always explicitly specify
'                     CSCRIPT host when using i/o redirection or
'                     pipes.
'
'  Last Update:     2005-07-14
' ___________________________________________________________________
'

Option Explicit

On Error Resume Next

Const FOR_WRITING   = 2
Const FOR_APPENDING = 8

Dim oFs, oStrm, oStdIn, oStdOut, sLine, sFileName, iIOMode

If Not IsCscript() Then
  WScript.Echo "Please run this script using CSCRIPT."
  WScript.Quit(1)
End If

If Not ParseCmdLine(sFileName, iIOMode) Then
  ShowUsage(True)
End If

Set oFs = CreateObject("Scripting.FileSystemObject")
Set oStrm = oFs.OpenTextFile(sFileName, iIOMode, True)

If Err.Number > 0 Then
  WScript.Echo "Error processing OpenTextFile method: 0x" & _
               Hex(Err.Number) & " (" & Err.Description & ")"
  Set oStrm = Nothing
  Set oFs   = Nothing
  WScript.Quit(1)
End If

Set oStdIn  = Wscript.StdIn
Set oStdOut = Wscript.StdOut

Do Until oStdIn.AtEndOfStream
  sLine = oStdIn.ReadLine
  oStdOut.WriteLine sLine
  oStrm.WriteLine sLine
Loop

Set oStdOut = Nothing
Set oStdIn  = Nothing
Set oStrm   = Nothing
Set oFs     = Nothing

WScript.Quit(0)

Private Function ParseCmdLine(sFileName, iIOMode)

  Dim i

  ParseCmdLine = False
  sFileName    = ""
  iIOMode      = FOR_WRITING

  For i = 0 To WScript.Arguments.Count - 1
    Select Case Left(WScript.Arguments(i), 1)
      Case "/"  : If LCase(WScript.Arguments(i)) = "/a" Then
                    iIOMode = FOR_APPENDING
                  Else
                    ShowUsage(True)
                  End If
      Case "-"  : If LCase(WScript.Arguments(i)) = "-a" Then
                    iIOMode = FOR_APPENDING
                  Else
                    ShowUsage(True)
                  End If
      Case Else : sFileName = WScript.Arguments(i)
                  ParseCmdLine = True
    End Select
  Next

End Function

Private Function IsCscript()

  IsCscript = False

  If InStrRev(LCase(WScript.FullName), "cscript.exe", -1) Then
    IsCscript = True
  End If

End Function

Private Sub ShowUsage(bExit)

  WScript.Echo "Copies standard input to both standard output and a file."
  WScript.Echo ""
  WScript.Echo "  Command | CSCRIPT Tee.vbs [-a] Filename"
  WScript.Echo ""
  WScript.Echo "    -a     Append output to filename."
  WScript.Echo ""
  WScript.Echo "Note:"
  WScript.Echo "There is a bug in Windows NT/2000 that causes command redirection to fail with"
  WScript.Echo "an Error unless the WSH host is explicitly specified on the command line"
  WScript.Echo "(regardless of default host selected). Therefore, always explicitly specify"
  WScript.Echo "CSCRIPT host when using i/o redirection or pipes."

  If bExit Then
    WScript.Quit(1)
  End If

End Sub

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Run A Process In A Hidden Window?

Saturday, 10. September 2005 22:37

The WScript.Shell‘s Run method executes the specified command line in a new process. Optionally you can specify an integer value called intWindowStyle that sets the appearance of the window. A value of 0 hides the window.

The VBScript file below, RunHide.vbs, demonstrate the usage of Run and creates a new process that executes in a hidden window.

' ___________________________________________________________________
'
'  VBScript File:   RunHide.vbs
'  Author:          Frank-Peter Schultze
'
'  Updates:         http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=77
'  Enhancement Req.
'  And Bug Reports: support@fpschultze.de
'
'  Built/Tested On: Windows 2000 SP2
'  Requirements:    OS: Windows NT4+
'                   WSH: 1.0+
'
'  Purpose:         Create a new process that executes in a hidden
'                   window.
'
'  Syntax:          RunHide Command [Arg1 ["Arg 2" [...
'
'  State Changes:
'
'  Assumptions And
'  Limitations:
'
'  Last Update:     2004-01-29
' ___________________________________________________________________
'

Option Explicit

On Error Resume Next

Dim oSh, sCmd, i

If Not IsWscript() Then
  WScript.Echo "Please run this script using WSCRIPT."
  WScript.Quit(1)
End If

If ParseCmdLine(sCmd) Then
  Set oSh = CreateObject("WScript.Shell")
  oSh.Run Trim(sCmd), 0, False
End If

WScript.Quit(0)

Private Function ParseCmdLine(sCmd)

  Dim i

  ParseCmdLine = False

  If WScript.Arguments.Count > 0 Then
    Select Case WScript.Arguments(0)
      Case "/?" : ShowUsage(True)
      Case "-?" : ShowUsage(True)
      Case "/h" : ShowUsage(True)
      Case "-h" : ShowUsage(True)
      Case "h"  : ShowUsage(True)
      Case Else : For i = 0 to WScript.Arguments.Count -1
                    If InStr(WScript.Arguments(i), " ") Then
                      sCmd = sCmd & " " & Chr(34) & WScript.Arguments(i) & Chr(34)
                    Else
                      sCmd = sCmd & " " & WScript.Arguments(i)
                    End If
                  Next
                  ParseCmdLine = True
    End Select
  Else
    ShowUsage(True)
  End If

  ParseCmdLine = True

End Function

Private Function IsWscript()

  IsWscript = False

  If InStrRev(LCase(WScript.FullName), "wscript.exe", -1) Then
    IsWscript = True
  End If

End Function

Private Sub ShowUsage(bExit)

  Dim strHelp

  strHelp = "Creates a new process that executes in a hidden window." & _
            vbCrLf & vbCrLf & _
            "RunHide Command [Arg1 [" & Chr(34) & "Arg 2" & Chr(34) & " [..."
  MsgBox strHelp, 64, "RunHide Syntax"

  If bExit Then
    WScript.Quit(1)
  End If

End Sub

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Determine an AD User’s GUID?

Saturday, 10. September 2005 21:16

The VBScript file below, ShowGUID.vbs, shows the current user’s GUID.

ShowGUID.vbs shows how to use ADSI‘s NameTranslate object.

' NameTranslate constants
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4    = 3
Const ADS_NAME_TYPE_GUID   = 7

' Determine the NetBIOS name of the domain and the NT name of the current user.
Set objNet = WScript.CreateObject("WScript.Network")
strNT4Name = objNet.UserDomain & "\" & objNet.UserName

' Use the NameTranslate object to convert the NT user name to the GUID
Set objNameTranslate = WScript.CreateObject("NameTranslate")

' Initialize NameTranslate by locating the Global Catalog.
objNameTranslate.Init ADS_NAME_INITTYPE_GC, ""

' Use the Set method to specify the NT format of the object name.
objNameTranslate.Set ADS_NAME_TYPE_NT4, strNT4Name

' Use the Get method to retrieve the GUID string.
WScript.Echo objNameTranslate.Get(ADS_NAME_TYPE_GUID)

More info on NameTranslate: NameTranslate FAQ

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Copy a Textfile To The Clipboard?

Friday, 9. September 2005 0:13

The script below copies the first 8k characters of a textfile to the clipboard using the IE object. It requires IE 5.0 or higher.

If WScript.Arguments.Count Then
	Const FOR_READING    = 1
	Const MAX_CHARACTERS = 8192
	Set fs = WScript.CreateObject("Scripting.FileSystemObject")
	Set f  = fs.OpenTextFile(WScript.Arguments(0), FOR_READING)
	t = f.Read(MAX_CHARACTERS)
	With WScript.CreateObject("InternetExplorer.Application")
		.Navigate "about :blank"
		Do Until .ReadyState = 4 : WScript.Sleep 50 : Loop
		.document.ParentWindow.ClipboardData.SetData "text", t
	End With
	f.Close
End If

This script’s syntax is easy: Type the name of the script followed by the name of the textfile which contents you want to be copied to the clipboard.

Perform this steps to implement this script in the txtfile’s right-click context menu:

  • Save the code as C:\WINDOWS\system32\Cop2Clip.vbs
  • Start regedit.exe and expland the HKCR\txtfile key in the left pane
  • Right-click HKCR\txtfile\shell and create a new key called Cop2Clip
  • Mark HKCR\txtfile\shell\Cop2Clip and double-click the (Default)-entry in the right pane.
  • Enter "C&opy file contents to clipboard" – this text will appear in the context menu.
  • Right-click HKCR\txtfile\shell\Cop2Clip and create a new key called command
  • Mark HKCR\txtfile\shell\Cop2Clip\command and double-click the (Default)-entry in the right pane.
  • Enter C:\WINDOWS\system32\wscript.exe C:\WINDOWS\system32\Cop2Clip.vbs //nologo "%1" – this is the command line that will be executed if you choose the new Copy file contents to clipboard context menu item.

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Map Drives Based On an Active Directory Site?

Thursday, 8. September 2005 23:50

You can use the ADSystemInfo object to determine the site name of the local computer:

On Error Resume Next

Set objSysInfo = WScript.CreateObject("ADSystemInfo")
Set objNetwork = WScript.CreateObject("Wscript.Network")

strSiteName = objSysInfo.SiteName

Select Case strSiteName
	Case "Amsterdam"
		objNetwork.MapNetworkDrive "X:", "\\fs-nl\data"
	Case "Berlin"
		objNetwork.MapNetworkDrive "X:", "\\fs-de\data"
	Case "London"
		objNetwork.MapNetworkDrive "X:", "\\fd-gb\data"
	Case "Paris"
		objNetwork.MapNetworkDrive "X:", "\\fs-fr\data"
End Select

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Script INI Files?

Thursday, 8. September 2005 23:36

The VBScript file IniFileClass.vbs provides a VBScript class to read from and write to ini files.

Import and Usage

The following approach shows how to import and use the IniFile class with a WSH 2.0 .ws file:

<job>
<script language="VBScript" src="IniFileClass.vbs" />
<script language="VBScript">
'	Instantiate the IniFile class
	Dim objInifile
	Set objInifile      = new IniFile

'	Show "Last File" key under "Settings" section of
'	uedit32.ini (if exists)
	objInifile.FileName = "C:\WINDOWS\uedit32.ini"
	objInifile.Section  = "Settings"
	objInifile.Key      = "Last File"
	If objInifile.Value <> "" Then MsgBox objInifile.Value

'	Now, set "Last File" key to "C:\boot.ini"
	objInifile.Value    = "C:\boot.ini"

'	Now, delete the "Last File" key
	objInifile.Value    = ""

'	Now, show the complete ini file
	MsgBox objInifile.Content

	Set objInifile      = Nothing
</script></job>

If you still use WSH 1.0 or prefer .vbs files, you can include all the class file’s content at the top of a script or import the class file’s content using the VBScript 5.0 runtime evaluation function ExecuteGlobal as that shown below.

' An example script to import and use the IniFile class

Include("IniFileClass.vbs")

Dim objInifile
Set objInifile      = new IniFile

' Show "Last File" key under "Settings" section of
' uedit32.ini (if exists)
objInifile.FileName = "C:\WINDOWS\uedit32.ini"
objInifile.Section  = "Settings"
objInifile.Key      = "Last File"
If objInifile.Value <> "" Then MsgBox objInifile.Value

' Now, set "Last File" key to "C:\boot.ini"
objInifile.Value    = "C:\boot.ini"

' Now, delete the "Last File" key
objInifile.Value    = ""

' Now, show the complete ini file
MsgBox objInifile.Content

Set objInifile      = Nothing

Sub Include(strFilename)
	Dim objFileSys, objFile, strContent
	Set objFileSys = WScript.CreateObject("Scripting.FileSystemObject")
	Set objFile    = objFileSys.OpenTextFile(strFilename, 1)
	strContent     = objFile.ReadAll
	objFile.Close
	Set objFileSys = Nothing
	ExecuteGlobal strContent
End Sub

And finally, here comes the listing of IniFileClass.vbs

' ___________________________________________________________________
'
'  VBScript File:   IniFileClass.vbs
'  Author:          Frank-Peter Schultze
'
'  Updates:         http://www.fpschultze.de/modules/smartfaq/faq.php?faqid=51
'  Enhancement Req.
'  and Bug Reports: support@fpschultze.de
'
'  Built/Tested On: Windows 2003
'  Requirements:    WSH 1.0+, VBScript 5.0+
'
'  Purpose:         Provides a class to read from/write to ini files
'
'  Last Update:     28-Sep-2006
' ___________________________________________________________________
'
'  This script is a rewritten/improved version of Jean-Luc Antoine's
'  class to accesss ini files, class_ini.vbs. URL of original code:
'  http://www.interclasse.com/scripts/class_ini.php
' ___________________________________________________________________
'

Option Explicit

Class IniFile

    Public Filename
    Public Section
    Public Key

    Private objFso
    Private objIni

    Private Sub Class_Initialize

        Set objFso = WScript.CreateObject("Scripting.FileSystemObject")

    End Sub

    Private Sub Class_Terminate

        Set objFso = Nothing

    End Sub

    Private Sub SectionStartEnd(ByRef lngSectionStart, ByRef lngSectionEnd)

        Dim arrContent, i, s

        lngSectionStart = -2
        lngSectionEnd = -1
        arrContent = Split(Content, vbNewLine, -1, 1)
        If (UBound(arrContent) > -1) Then
            If (Section <> "") Then
                For i = LBound(arrContent) To UBound(arrContent)
                    s = Trim(arrContent(i))
                    If (LCase(s) = "[" & LCase(Section) & "]") Then
                        lngSectionStart = i
                    ElseIf (Left(s, 1) = "[") AND _
                        (Right(s, 1) = "]") AND _
                        (lngSectionStart >= 0) Then
                        lngSectionEnd = i - 1
                        Exit For
                    End If
                Next
                If (lngSectionStart >= 0) AND (lngSectionEnd < 0) Then
                    lngSectionEnd = UBound(arrContent)
                End If
            Else
                lngSectionStart = -1
                lngSectionEnd = UBound(arrContent)
            End If
            If (lngSectionStart > -2) Then
                If (arrContent(lngSectionEnd) = "") Then
                    lngSectionEnd = lngSectionEnd - 1
                End If
            End If
        End If

    End Sub

    Property Get Content

        Const FOR_READING = 1

        Content = ""
        If objFso.FileExists(FileName) Then
            Set objIni = objFso.OpenTextFile(Filename, FOR_READING)
            Content = objIni.ReadAll
            objIni.Close
            Set objIni = Nothing
        End If

    End Property

    Property Let Content(strContent)

        Const OVERWRITE = True

        Set objIni = objFso.CreateTextFile(Filename, OVERWRITE)
        objIni.Write strContent
        objIni.Close
        Set objIni = Nothing

    End Property

    Property Get Value

        Dim lngSectionStart, lngSectionEnd, lngIndex, arrContent
        Dim strLine, i, s

        Value = ""
        SectionStartEnd lngSectionStart, lngSectionEnd
        If (lngSectionStart > -2) Then
            arrContent = Split(Content, vbNewLine, -1, 1)
            For lngIndex = lngSectionStart + 1 To lngSectionEnd
                strLine = arrContent(lngIndex)
                i = InStr(1, strLine, "=", 1)
                If (i > 0) Then
                    s = Left(strLine, i - 1)
                    s = Trim(s)
                    If (LCase(s) = LCase(Key)) Then
                        Value = Mid(strLine, i + 1)
                        Value = Trim(Value)
                        Exit For
                    End If
                End If
            Next
        End If

    End Property

    Property Let Value(strValue)

        Dim lngSectionStart, lngSectionEnd, arrContent
        Dim lngIndex, lngIndex2, strContent, blnKeyNotFound
        Dim strLine, i, s

        SectionStartEnd lngSectionStart, lngSectionEnd
        If (lngSectionStart < -1) AND (strValue <> "") Then
            strContent = Content & vbNewLine _
                & "[" & Section & "]" & vbNewLine _
                    & Key & "=" & strValue
        Else
            blnKeyNotFound = True
            arrContent = Split(Content, vbNewLine, -1, 1)
            For lngIndex = lngSectionStart + 1 To lngSectionEnd
                strLine = arrContent(lngIndex)
                i = InStr(1, strLine, "=", 1)
                If (i > 0) Then
                    s = Left(strLine, i - 1)
                    s = Trim(s)
                    If (LCase(s) = LCase(Key)) Then
                        blnKeyNotFound = False
                        If (strValue <> "") Then
                            arrContent(lngIndex) = Key & "=" & strValue
                        Else
                            For lngIndex2 = lngIndex To UBound(arrContent) - 1
                                arrContent(lngIndex2) = arrContent(lngIndex2 + 1)
                            Next
                            Redim Preserve arrContent(UBound(arrContent) - 1)
                        End If
                        Exit For
                    End If
                End If
            Next
            If blnKeyNotFound AND (strValue <> "") Then
                Redim Preserve arrContent(UBound(arrContent) + 1)
                For lngIndex = UBound(arrContent) To lngSectionEnd + 2 Step -1
                    arrContent(lngIndex) = arrContent(lngIndex - 1)
                Next
                arrContent(lngSectionEnd + 1) = Key & "=" & strValue
            End If
            strContent = arrContent(0)
            For lngIndex = 1 To UBound(arrContent)
                strContent = strContent & vbNewLine & arrContent(lngIndex)
            Next
        End If
        Content = strContent

    End Property

End Class

Category:Scripting, VBScript | Comment (0) | Author: Frank-Peter

How To Change The CD/DVD Drive Letter?

Thursday, 8. September 2005 23:16

The cmd.exe command line below uses mountvol.exe in order to delete the old and to set the new drive letter assignment (where E: represents the old and Z: the new drive letter):

FOR /F %V IN (
	'mountvol.exe E: /L'
) DO (
	mountvol.exe E: /D
	mountvol.exe Z: %V
)

The FOR /F command parses a mountvol command that returns the CD-ROM drive’s volume name. The volume name looks like this:

\\?\Volume{1d926311-403a-11d9-94c8-806d6172696f}\

If FOR /F successfully determines a volume name it executes two mountvol commands, the first one deletes the current drive letter assignment the seconds one sets the new drive letter assignment (using the volume name).

Category:Cmd.exe Shell, Scripting, Utilities | Comment (0) | Author: Frank-Peter