Monday, September 27, 2010

Introducción a VBScript


Introducción a VBScript

VBScript es un lenguaje de programación horrible, pero extremadamente útil
en el entorno de sistemas ya que durante años ha sido el lenguaje que por
excelencia se ha usado para la administración/automatización de Windows.

Se trata de un lenguaje interpretado, no compilado. Otros lenguajes interpretados
son JavaScript, perl, y salvando las distancias Python. El proceso que ejecuta los vbs es el WScript.exe


Seis cosas sobre VBS:

1. Los comentarios empiezan por '
2. Al iniciar el script decidimos si es necesario o no declarar las variables
  antes de usarlas: Option Explicit
3. El script se interrumpe ante cualquier error, a no ser que declaremos:
On Error Resume Next
4. Una instrucción es una línea (no ";" final)
5. Las variables se declaran con la expresión Dim
 Algunas consideraciones sobre variables:
- se puede declarar más de una a la vez separándolas por ","
- por convención, aquellas que apuntan a objetos empiezan por "obj"
         y las otras tienen nombres representativos.
6. Para asignar valor a una variable NO objeto: var = <valor>



' SCript de prueba que muestra una frase en un msgBox
Option Explicit

On Error Resume Next
Dim frase
frase="Bienvenido"

MsgBox frase



Probar:
1. Comentando la declaración de la variable (Dim frase)
2. Comentando la declaración de la variable y además el Resume Next
3. Todo lo anterior + el Option Explicit




Arrays:

0. Es necesario DECLARARLOS

1. La primera posición de una matriz es la 0. Así un Array de 10 elementos empieza
en el 0 y acaba en el 9

2. Pueden tener varias dimensiones, y contener diferentes tipos de datos.

3. Para añadir un elemento a un array indicamos en qué posición queremos añadirlo

Ejemplo: programa que declara un array de 2x10, y asigna valores. Luego muestra dos de ellos
Dim arrUsuarios(1,9)
arrUsuarios(0,0)= "Alex"
arrUsuarios(0,1)= "Garcia"
arrUsuarios(1,0)= "Jose"
arrUsuarios(1,1)= "Garrido"

MsgBox "El primer usuario es " & arrUsuarios(0,0) & " y el segundo " & arrUsuarios (1,0)

4. Hay arrays dinámicos, se declaran sin especificar sus elementos. P.e.
        Dim arrUsuarios()
y se les asigna un tamaño mediante las sentencias "ReDim" y "Redim Preserve"
        Redim arrUsuarios(9) 'la primera vez
        Redim Preserve arrUsuarios(10) 'para añadirle una fila más

5. Se pueden declarar/asignar mediante el uso de la función Array()
de esta otra forma:

Ejemplo:
 Dim arrUsuarios
 arrUsuarios = Array("valor1","valor2","valor3")
 ReDim Preserve arrUsuarios(10)


Convirtiendo Strings en Arrays gracias a la función Split(cad,separador)

 str = "alex,jose,maria,carla"
 arrNombres= Split(str,",")
 MsgBox arrstr(3)

Convirtiendo Arrays en Strings gracias a la función Join(array,separador)

 dim arrNombres
 arrNombres = Array("alex","jose","maria","carla")
 str = Join(arrNombres,";")
 MsgBox str




Tipos de datos

Ésta es la lista de los tipos de datos que tenemos en VBScript, y a continuación está la lista de las funciones para pasar de un tipo a otro.

Tipos de datos:


Funciones de conversión entre datos:



STATEMENTS y FUNCTIONS

En castellano también se habla como de Procedimientos y de Funciones. Ambos son una forma de reutilizar y ordenar el código, y ambos permiten el paso de parámetros. La diferencia entre ellos es:

Statements:
  1. no devuelven nada
  2. sus parámetros se pasan sin paréntesis
Functions:
  1. devuelven un valor, que por lo tanto habrá que recoger en una variable y procesar
  2. sus parámetros se pasan entre paréntesis

Para comprobar la diferencia entre uno y otro tipo de subrutina vamos a tomar como ejemplo el “MsgBox”, que es una subrutina que tanto puede ser un Statement como una Function según se invoque.
Cuando se usa la función MsgBox, el valor que devuelve es un número u otro en función del botón que se pulse en el cuadro de diálogo.

MsgBox "vbscript is in linguiji sicriti", 48 , "mensaje secreto"

(Poner captura)

Los parámetros que admite son:
1. String: que será el cuerpo del mensaje que se mostrará
2. Integer: que identifica el tipo de iconos/recuadro que aparecerá
3. String: que aparecerá en la barra de título

Ejemplo de MsgBox como Function primero, y como Statement posteriormente en el If ... Then

Dim valorElegido
valorElegido = MsgBox ("Desea continuar" & VbCrLf &  _
                        "en caso negativo lo tiene muy mal", _
                   vbYesNo , "Seguimos?")

If valorElegido = vbYes Then
        MsgBox ("Buena elección, continuemos")
Else MsgBox ("Ha pulsado NO, en junio su elección se verá cumplida")
End If

Ejemplo de la función InputBox que permite recoger texto introducido por el usuario:

Dim loginName
Dim confirmacion

loginName = InputBox ("Nombre del usuario a dar de alta")
confirmacion = MsgBox ("El nombre de usuario que introdujo es: " &  _
            loginName & VbCrLf & " es correcto?", _
            vbYesNo , "Continuar?")

If confirmacion = vbYes Then
        MsgBox  "Usted ha decidido continuar",0,"titulo"
Else
           MsgBox  "Usted ha decidido NO continuar"
End If

Notas:
  1. VbCrLf es una Constante definida en VBS que corresponde al valor de salto de línea y retorno de carro en un texto
  2. El “_” a final de línea indica que la instrucción sigue en la línea siguiente.
  3. vbYesNo es una constante númerica igual a 4, y que corresponde con el cuadro con Yes y No cuando se pasa como segundo parámetro de MsgBox

Tipos de MsgBox y constantes asociadas:

Valores devueltos por MsgBox según el botón que se pulse:

Algunas funciones de uso muy común:

De fecha:
Year, Month, Day, WeekDay, Hour, Minute, Second

De conversión de tipo:
Cstr, CBool, ... las que aparecían en el cuadro anterior

De cadena (strings):
Join y Split, que hemos visto al hablar de Arrays
InStr y InStrRev para hacer búsquedas
Len
Replace
LCase y UCase
LTrim, RTrim, Trim
LBound, UBound



Monday, November 23, 2009

VBScript: manejo de cadenas de texto

VBScript: manejo de cadenas de texto



Algunas de las funciones más habituales para manipular cadenas de texto son:


Function
Description
InStr
Returns the position of the first occurrence of
one string within another. The search begins at the first character of the
string
InStrRev
Returns the position of the first occurrence of one string
within another. The search begins at the last character of the string
LCase
Converts a specified string to lowercase
Left
Returns a specified number of characters from
the left side of a string
Len
Returns the number of characters in a string
LTrim
Removes spaces on the left side of a string
RTrim
Removes spaces on the right side of a string
Trim
Removes spaces on both the left and the right side of a
string
Mid
Returns a specified number of characters from a
string
Replace
Replaces a specified part of a string with another string a
specified number of times
Right
Returns a specified number of characters from
the right side of a string
Space
Returns a string that consists of a specified number of
spaces
StrComp
Compares two strings and returns a value that represents
the result of the comparison
String
Returns a string that contains a repeating character of a
specified length
StrReverse
Reverses a string
UCase
Converts a specified string to uppercase

(la fuente es: http://www.w3schools.com/VBscript/vbscript_ref_functions.asp)


A menudo, los ficheros que procesamos tienen líneas con varios campos delimitados por algún tipo de carácter. Todos los lenguajes de programación/scripting poseen algun método para procesar cadenas divididas en campos. En VBScript esta función es:

Split(expression[,delimiter[,count[,compare]]])


La descripción de sus parámetros tal y como la muestran en
http://www.w3schools.com/VBscript/func_split.asp

Parameter
Description
expression
Required. A string expression that contains substrings
and delimiters
delimiter
Optional. A string character used to identify substring
limits. Default is the space character
count
Optional. The number of substrings to be returned. -1
indicates that all substrings are returned
compare
Optional. Specifies the string comparison to use.
Can
have one of the following values:

  • 0 = vbBinaryCompare - Perform a binary comparison
  • 1 = vbTextCompare - Perform a textual comparison

Ejemplo de uso:

Se trata de un script que comprueba la existencia de un fichero de texto, y si existe lo abre y lo recorre línea a línea procesando cada una de ellas. Las líneas contienen campos separados por ";" y el script nos muestra primero la línea y a continuación los campos que contiene.

dim oshell
dim fich, fs

'ubicación del fichero de altas
nombre_fich="c:\tmp\altas.txt"

set oshell=createobject("WScript.shell")
set fs=createobject("scripting.FileSystemObject")

'comprobamos que exista el fichero de altas
if not fs.FileExists(nombre_fich) then
  wscript.echo "no existe el fichero "& nombre_fich
  WScript.Quit 4
end if

'Si hemos llegado hasta aquí es que existe y lo abrimos
set fich=fs.OpenTextFile (nombre_fich, 1, "True" )

'Lo recorremos
Do While fich.atEndOfStream <> True
  linea=fich.ReadLine
' Ahora mostramos la línea leída
  wscript.echo linea
' Parseamos los campos
  campos = split(linea,";")
  for each a in campos
    wscript.echo "valor del campo: "&a
  next
Loop

fich.close



Evidentemente, podríamos hacer algo más útil que mostrar la línea, como por ejemplo usar un objeto de tipo shell para ejecutar dsadd user <usuario> -memberof <grupos>

Sunday, November 22, 2009

VBScript: trabajando con ficheros (II)

VBScript: trabajando con ficheros (II)


Microsoft proporciona mediante FSO una herramienta para trabajar con carpetas y ficheros.

Microsoft se refiere a FileSystemObject como a un "Object Model", esto puede entenderse como sinónimo de clase. Así, FSO es una clase mediante la cual se puede trabajar con ficheros y carpetas. Esta clase está en la librería de nombre "Scripting", que está en la dll: Scrrun.dll.

En la sesión anterior abrimos un fichero para leer su contenido y recorrimos su contenido línea a línea.

En la siguiente dirección hay una lista de los métodos que proporciona esta clase:

http://msdn.microsoft.com/en-us/library/aa711216(VS.71).aspx

y aquí está la lista, cada nombre de función es un link a una página con una explicación detallada con un ejemplo:



BuildPath Method

This method is used to append a name onto an existing path.


[newfullpath = ]object.BuildPath(path, name)




CopyFile Method

This method allows us to copy one or more files from one location (the source) to another (destination).


Syntax: object.CopyFile source, destination [, overwrite]




CopyFolder Method

Copies one or more folders and all contents, including files and subfolders, from one location to another.


Syntax: object.CopyFolder source, destination, [, overwrite]



CreateFolder Method

This method allows us to create a folder.


Syntax: object.CreateFolderfoldername




CreateTextFile Method

Creates a text file and returns a TextStreamObject that can then be used to write to and read from the file.


Syntax: object.CreateTextFile
filename [, overwrite[, unicode]]





DeleteFile Method

This method deletes a specified file or files (using wilcards).


Syntax: object.DeleteFile
file [, force]




DeleteFolder Method

This method deletes a specified folder, including all files and subfolders.


Syntax: object.DeleteFolder
folder [, force]




DriveExists Method

This method lets us check if a specified drive exists. It returns True if the drive does exist and False if it doesn't.


Syntax: object.DriveExists(drive)



FileExists Method

Lets us check whether a specified file exists. Returns True if the file does exist and False otherwise.


Syntax: object.FileExists(file)



FolderExists Method

Allows us to check if a specified folder exists. Returns True if the folder does exist and False if it doesn't.


Syntax: object.FolderExists(folder)



GetAbsolutePathName Method

This method gets the complete path from the root of the drive for the specified path string.


Syntax: object.GetAbsolutePathName(path)



GetBaseName Method

This method gets the base name of the file or folder in a specified path.


Syntax: object.GetBaseName(path)



GetDrive Method

This method returns a Drive object corresponding to the drive in a supplied path.


Syntax: object.GetDrive(drive)



GetDriveName Method

This method gets a string containing the name of the drive in a supplied path.


Syntax: object.GetDriveName(path)



GetExtensionName Method

Used to return a string containing the extension name of the last component in a supplied path.


Syntax: object.GetExtensionName(path)



GetFile Method

Returns the File object for the specified file name.


Syntax: object.GetFile(filename)



GetFileName Method

This method is used to return the name of the last file or folder of the supplied path.


Syntax: object.GetFileName(path)



GetFileVersion Method

This method is used to return the version of the file in the
specified path.



Syntax: object.GetFileVersion(path)



GetFolder Method

This method returns a Folder object of the folder specified in the folder parameter.


Syntax: object.GetFolder(folder)



GetParentFolderName Method

Returns a string containing the name of the parent folder of the last file or folder in a specified path.


Syntax: object.GetParentFolderName(path)



GetSpecialFolder Method

Returns the path to one of the special folders - \Windows, \System or \TMP.


Syntax: object.GetSpecialFolder(folder)



GetTempName Method

This method is used to generate a random filename for a temporary file..


Syntax: object.GetTempName



MoveFile Method

Moves one or more files from one location to another.


Syntax: object.MoveFile source, destination



MoveFolder Method

Moves one or more folders from one location to another.


Syntax: object.MoveFolder source, destination



OpenTextFile Method

Opens the file specified in the filename parameter and returns an instance of the TextStreamObject for that file.


Syntax: object.OpenTextFile(filename [, iomode[, create[, format]]])










Friday, November 20, 2009

VBScript: empezando a trabajar con fi...

VBScript: empezando a trabajar con ficheros (I)




Si para ejecutar otros programas usábamos un objeto de tipo WScript.shell, para acceder al sistema de ficheros usamos un objeto de tipo FileSystemObject.

Podemos abrir ficheros con uno de sus métodos:
OpenTextFile
OpenAsTextStream

Para abrir un fichero de texto abretxt.vbs:

dim fso
dim fich
set fso=createobject("Scripting.FileSystemObject")
set fich=fso.OpenTextFile("c:\altas.txt")


Los ficheros se pueden abrir:
ForReading    1
ForWriting    2
ForAppending    8


Un fichero además se puede abrir con la codificación UTF, ASCII o la codificación por defecto, eso lo controlamos mediante las constantes:
UTF: TristateTrue -1
ASCII: TristateFalse -2
Default: TristateUseDefault 0

Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateUseDefault = -2
Const TristateTrue = -1
Const TristateFalse = 0
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile("D:\data\log.txt", ForWriting, True, TristateFalse)



Ahora vamos a ir leyendo una a una las líneas de un fichero d:\altas.txt:

Const ForReading = 1
Const TristateFalse = 0

Set fs = CreateObject("Scripting.FileSystemObject")
Set fich = fs.OpenTextFile("D:\\altas.txt", ForReading, "True")
Do While fich.atEndOfStream <> True
  linea=fich.ReadLine
' Ahora mostramos la línea leída
  wscript.echo linea
Loop

fich.close








VBScript: acceso a variables de sistema y ejecución de otros prog

VBScript: acceso a variables de sistema y ejecución de otros programas



Acceso a variables de sistema

VBScript proporciona acceso a las variables de sistema mediante el método ExpandEnvironmentStrings() de los objetos de tipo WScript.Shell.

La manera de obtener el valor de una variable es:
'Obtener una variable de tipo "WScript.shell"
set ws=createobject("WScript.shell")
'Obtener el valor de la variable de sistema que nos interese
'mediante la función ExpandEnvironmentStrings()
variable=ws.ExpandEnvironmentStrings("COMPUTERNAME")

'Ahora ya podemos hacer lo que sea con ese valor



Variable
Descripción
Ejemplo
COMMONPROGRAMFILESUbicación de la carpeta common program files
C:\Program files\Common Files
COMPUTERNAMENombre del equipo
PC2
COMSPECRuta completa hasta el actual cmd.exe
C:\Windows\system32\cmd.exe
HOMEDRIVEDisco en que está el perfil del usuario que ejecuta el script
C:
HOMEPATHUbicación de la raíz
\
LOGONSERVERNombre del servidor que validó al usuario
\\DC1
NUMBER_OF_PROCESSORSNumero de CPUs del equipo

OS
Nombre del S.O.
Window_NT
PATH
Rutas en que busca por defecto

PATHEXT
Extensiones que reconoce como de ejecutables
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;
PROCESSOR_ARCHITECTUREArquitectura de los procesadores
X86
SYSTEMDRIVEDisco de sistema
C:
SYSTEMROOTRaíz de la instalación de Windows
C:\WINNT
USERDOMAINDominio del usuario
LASALLE
USERNAME
Nombre del usuario
Steve Ballmer
USERPROFILE
Ruta del perfil de usuario
D:\Documents and Settings\Steve Ballmer


Ejecución de otros programas desde VBScript


Para ejecutar una aplicación en WSH hay que crear una instancia de  WScript.Shell, y entonces usar run().  Por ejemplo, para hacer un script que añada un usuario que pasamos por parámetro a nuestro script altas.vbs:

dim oshell

set oshell=createobject("WScript.shell")
oshell.run "dsadd user "& Chr(34) & "cn=jana montana,cn=users,dc=lasalle,dc=local"& Chr(34) & " -pwd P@@ssw0rd"


y en la OU users del dominio en cuestión aparecería el nombre de usuario en cuestión.
Chr(34) es la forma de escribir unas comillas que van dirigidas al parámetro de run() y no al VBScript. Lo que queremos que ejecute en realidad el script cuando lo llamamos como altas.vbs "jana montana" es:

dsadd user "cn=jana montana,cn=users,dc=lasalle,dc=local" -pwd P@@ssw0rd

ya que sin las comillas, dsadd dará un error al detectar un espacio entre jana y montana.

También podemos usar variables de sistema al llamar a run(). El siguiente ejemplo se encarga de abrir con el notepad el fichero que pasemos por parámetro:

dim oshell
set oshell=createobject("WScript.shell")
oshell.run "%SystemRoot%\system32\notepad "& wscript.arguments(0)


Parámetros adicionales para la función run():

Hasta ahora hemos tomado un objeto de tipo WScript.shell y hemos ejecutado run() pasándole como único argumento el nombre o ruta completa del programa que queríamos ejecutar. El método run() admite no obstante dos parámetros más, uno para controlar el comportamiento de la ventana en que se ejecutará el programa al que llamamos, y otro para controlar si el script debe esperar a que finalice el programa que acabamos de lanzar, o si puede seguir con la siguiente instrucción mientras se va ejecutando el programa que hemos lanzado.

object.Run (“command”, [winStyle], [“waitOnReturn”])

winStyle puede tomar valores entre 0 y 10. En el siguiente artículo de microsoft hay una descripción muy extensa: http://technet.microsoft.com/en-us/library/ee156605.aspx












 Integer 



                  Window Style Description



0



Hides the window and activates another window.



1



Activates and displays a window. If the window is minimized or
maximized, the system restores it to its original size and position. An
application should specify this flag when displaying the window for the
first time.



2



Activates the window and displays it as a minimized window.



3



Activates the window and displays it as a maximized window.



4



Displays a window in its most recent size and position. The active window remains active.



5



Activates the window and displays it in its current size and position.



6



Minimizes the specified window and activates the next top-level
window in the Z order. The Z order is nothing more than the list
detailing the order in which windows are to be activated. If you press
ALT+TAB, you will see a graphical representation of the Z list.



7



Displays the window as a minimized window. The active window remains active.



8



Displays the window in its current state. The active window remains active.



9



Activates and displays the window. If the window is minimized or
maximized, the system restores it to its original size and position. An
application should specify this flag when restoring a minimized window.



10



Sets the show-state based on the state of the program that started the application.


Si fijamos el valor de  waitOnReturn a True, el script vbs esperará a que finalice la ejecución que le acabamos de pedir antes de proseguir con la siguiente instrucción.















Monday, November 16, 2009

VBScript: procedimientos y otras curi...

VBScript: procedimientos y otras curiosidades


Procedimientos


Los procedimientos son un mecanismo para la reutilización de código, y también para su simplificación.

Visual Basic Script tiene tres tipos de procedimiento para favorecer la reutilización de código:
  1. subrutinas: ejecutan algo y ya está (p.e. borrar un directorio). Los parámetros se le pasan sin paréntesis.
  2. funciones: ejecutan algo y devuelven un valor(p.e. borrar un directorio y devolver true si se ha borrado correctamente, y false en cualquier otro caso). Los parámetros se le pasan entre paréntesis.
  3. eventos: son un tipo especial de subrutina que se ejecuta cuando se da una determinada condición como p.e. pulsar un botón o pasar por encima de un texto.


Ejemplo de función:

WScript.Echo “Has introducido el nombre “ & getName()



Function getName()
  Dim tmpName
  tmpName = “”
  Do While tmpName = “”
    tmpName = InputBox(“Introduce un nombre: ”)
  Loop
  getName = tmpName
End Function

(también existe:  Exit Function )


Ejemplo de subrutina:

showError "No se ha podido crear el fichero, compruebe que tiene permisos","Error de ejecución"

Sub showError(errorMessage,title)
  MsgBox “Input Error: “ & errorMessage,, title
End Sub




Información útil acerca del propio script o de su entorno

Alguna información útil que podemos recabar del script puede ser: la ruta completa desde la que se ejecuta, el nombre del script mismo, los argumentos que le hemos pasado.

los argumentos que le hemos pasado:
Set theArgs = WScript.Arguments

la ruta completa de ejecución:
WScript.ScriptFullName

el nombre del script:
WScript.ScriptName

Ejemplo de uso:

wscript.echo wscript.ScriptFullName
wscript.echo wscript.scriptname
wscript.echo wscript.arguments.count
for each elemento in wscript.arguments
 wscript.echo cstr(elemento)
next

La ruta completa de ejecución suele ser útil para poder acceder a ficheros de configuración o de datos que estén en el mismo directorio que nuestro script.