El Blog de Gualtrysoft

Windows 2000/2003/2008, Active Directory, VBScript, Hyper-V, PowerShell y todo aquello interesante a la hora de usar, configurar y administrar Windows Server. También tenemos longanizas…

Dos Scripts VBScript Para Cambiar La Letra De Unidad De Un CD-ROM

Posted by urpiano en Jueves 18 \18\UTC enero \18\UTC 2007

Cambiar la letra de un CD-ROM no es posible hacerlo con VBScript directamente en los sistemas operativos pre Windows Server 2003. Se puede usar el comando del sistema operativo mountvol.exe. Con un script VBScript podremos realizar tareas de revisión del sistema operativo para ver si se cambiará la letra del CD-ROM, una vez cumplidas determinadas condiciones e invocar mountvol.exe. Pero esto tiene sus pegas, principalmente la incapacidad de hacerlo en remoto y la obligatoriedad de ejecutar el script como administrador local del equipo. En Windows Server 2003, sin embargo, se puede puede utilizar WMI para realizar esta tarea, lo que nos permite realizarla en remoto y además lanzar el script como usuario normal suminstrando las credenciales de un usuario administrador local del equipo destino. Aquí veremos los dos scripts, el que permite hacerlo usando mountvol.exe y el que utiliza WMI.

¡¡OJO!! Realizar un cambio de letra de unidad a un equipo es algo que afecta a todos los usuarios de ese equipo, mientras que cada usuario puede tener sus propias unidades de red montadas. Esto quiere decir que hay que estudiar muy bien qué nueva letra se asigna a la unidad de CD-ROM para no "pisar" una letra de unidad de red de otro usuario distinto al que lanza el script y que no existe en el momento de la ejecución del script en el perfil del usuario que lo lanza y sí en el de ese usuario. Esto es muy importante si queremos cambiar las letras en remoto, pues generalmente lo haremos con un administrador del dominio.

Script usando mountvol.exe

El presente script nos permite cambiar a una letra recibida como parámetro, en el equipo local, la letra de unidad de aquel CD-ROM que tenga como letra una recibida como parámetro. La sintaxis es:

{wscript | cscript [//nologo]} cambia-letra-a-cdrom-local.vbs <letra actual>: <letra nueva>:

Siendo:

  • letra actual (requerido): la letra del CD-ROM que queremos cambiar. Si hay más CD-ROMs no se verán afectados, así como si sólo hay uno y no tiene esa letra, no se verá afectado.
  • letra nueva (requerido): la letra que se asignará al CD-ROM que tiene por letra de unidad letra actual.

Ejemplos:

– Cambiamos a F: el CD-ROM de letra D: usando wscript:

wscript cambia-letra-a-cdrom-local.vbs d: f:

– Cambiamos a F: el CD-ROM de letra D: usando cscript:

cscript cambia-letra-a-cdrom-local.vbs d: f:

Nota: el script revisa que la letra de destino esté libre, y en el caso de estar en uso no será cambiada la letra al CD-ROM.

    'cambiar-letra-a-cdrom-local.vbs
'
'El presente script nos permite cambiar a una letra recibida como
'parámetro, en el equipo local, la letra de unidad de aquel CD-ROM
'que tenga como letra una recibida como parámetro. La sintaxis es:
'
'{wscript | cscript [//nologo]} cambia-letra-a-cdrom-local.vbs 
'                                    <letra actual>: <letra nueva>:
'
'Siendo:
'
'letra actual (requerido): la letra del CD-ROM que queremos cambiar.
'             Si hay más CD-ROMs no se verán afectados, así como si
'             sólo hay uno y no tiene esa letra, no se verá afectado.

'letra nueva (requerido): la letra que se asignará al CD-ROM que
'             tiene por letra de unidad letra actual.
'
'Ejemplos:
'
'- Cambiamos a F: el CD-ROM de letra D: usando wscript:
'
'wscript cambiar-letra-a-cdrom-local.vbs d: f:
'
'- Cambiamos a F: el CD-ROM de letra D: usando cscript:
'
'cscript cambiar-letra-a-cdrom-local.vbs d: f:
'
'Nota: el script revisa que la letra de destino esté libre, y en el
'caso de estar en uso no será cambiada la letra al CD-ROM.
'
'© Fernando Reyes - Enero de 2007

'Exigimos la declaración de variables
Option Explicit

'Constantes para la forma de consultar con
'WQL al servicio WMI
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20

'Declaración de variables
Dim obj_ServicioWMI, col_CDROMs, obj_CDROM
Dim bol_ExisteCDROM, lng_Devolucion
Dim str_Comando, str_Letra, str_LetraNueva

'Revisamos que se hayan pasado los parámetros
'imprescindibles, esto es, letra a cambiar y 
'nueva letra
If Not WScript.Arguments.Unnamed.Count = 2 Then

    Call s_Ayuda("Error 1: número de argumentos erróneo")
    WScript.Quit 1
    
'Revisamos que se trate de letras válidas (por encima de C
ElseIf Not f_EsLetra(WScript.Arguments.Unnamed(0)) _
Or Not f_EsLetra(WScript.Arguments.Unnamed(1)) Then

    Call s_Ayuda("Error 2: nombre de letra de unidad no válida")
    WScript.Quit 2
    
'Todo correcto, recogemos los dos parámetros de letras
'de unidad
Else

    str_Letra = WScript.Arguments.Unnamed(0)
    str_LetraNueva = WScript.Arguments.Unnamed(1)
    
End If

'Conectamos con el servicio WMI del equipo local
Set obj_ServicioWMI = GetObject("winmgmts:\.rootCIMV2")


'Comprobamos que no esté en uso la letra que queremos poner
If f_ExisteLetra(str_LetraNueva, obj_ServicioWMI) Then

        WScript.Echo vbcrlf & vbcrlf & _
        "Error 3: la nueva letra de unidad ya está en uso"
    Set obj_ServicioWMI = Nothing
    WScript.Quit 3
    
End If


'Creamos una colección de objetos CD-ROM del equipo
Set col_CDROMs = obj_ServicioWMI.ExecQuery( _
                  "SELECT * FROM Win32_CDROMDrive", "WQL", _
                  wbemFlagReturnImmediately + wbemFlagForwardOnly)
    
'Iniciamos a False el control de si existe o no el CD-ROM de letra
'la recibida como parámetro
bol_ExisteCDROM = False

'Recorremos los CD-ROMs del equipo
For Each obj_CDROM In col_CDROMs
        
    'Verificamos que se trata de la letra que queremos cambiar
    If UCase(str_Letra) = UCase(obj_CDROM.Drive) Then

        'Como el CD-ROM existe, ponemos a True la booleana de
        'control
        bol_ExisteCDROM = True
        
        'Creamos una instrucción FOR que se encargue de obtener
        'el nombre del volumen con una llamada:
        'mountvol.exe /L letra:
        'y use ese nombre para establecer la nueva letra con
        'una llamada:
        'mountvol.exe /D letra: nombre_volumen
        str_Comando = "FOR /F %V IN ('mountvol.exe " & _
                      str_Letra & " /L') DO (" & _
                      "mountvol.exe " & str_Letra & _
                      " /D & mountvol.exe " & _
                      str_LetraNueva & " %V)"
                 
        'Ejecutamos el comando llamando a la función
        'de ejecución de comandos Shell
        lng_Devolucion = f_Cmd(str_Comando)

        If lng_Devolucion = 0 Then
        
            WScript.Echo vbCrLf & vbCrLf & _
                         "CD-ROM " & str_Letra & _
                         " cambiado a " & _
                         str_LetraNueva & _
                         " con éxito"
                         
        Else
        
            WScript.Echo vbCrLf & vbCrLf & _
                         "Error 4: No se ha podido cambia" & _
                         "r la letra. Causa más probable," & _
                         " falta de permisos del usuario"
                          
            Set obj_CDROM = Nothing
            Set col_CDROMs = Nothing
            Set obj_ServicioWMI = Nothing
            
            WScript.Quit 4
            
        End If
        
    End If
    
Next

'Si no se ha encontrado el CD-ROM mostramos un mensaje
'indicativo
If Not bol_ExisteCDROM Then

    WScript.Echo vbCrLf & vbCrLf & _
             "Error 5: No existe el CD-ROM de " & _
             "letra " & str_Letra
                 
    Set obj_CDROM = Nothing
    Set col_CDROMs = Nothing
    Set obj_ServicioWMI = Nothing
    
    WScript.Quit 5

End If

Set obj_CDROM = Nothing
Set col_CDROMs = Nothing
Set obj_ServicioWMI = Nothing


Function f_EsLetra(str_Letra)
'Esta función recibe una cadena y comprueba que se trate de
'un nombre de unidad válido. Para considerar válido el nombre
'de unidad, consideramos que debe tener una longitud de dos
'caracteres y que debe ser una letra entre C y Z seguida por
'el caracter de dos puntos (Ejemplo: F:)

    Dim obj_RE

    'Si la longitud no es dos, es que no es un nombre de
    'letra válido
    If Len(str_Letra)<>2 Then
    
        f_EsLetra = False
        Exit Function
        
    End If
    
    'Creamos un objeto RegularExpression
    Set obj_RE = New RegExp

    'Establecemos como patrón el primer caracter una letra
    'entre C y Z y el segundo el caracter de dos puntos
    obj_RE.Pattern = "[C-Z]:"
    
    'La función devuelve el resultado del método test
    'del objeto RegularExpression para la letra recibida

    'como parámetro puesta en mayúsculas 
    f_EsLetra = obj_RE.Test(UCase(str_Letra))

    '¡¡Caca fuera!! :-Þ
    Set obj_RE = Nothing

End Function

Function f_ExisteLetra(str_Letra, obj_ServicioWMI)
'Esta función nos permite averiguar si la letra de unidad
'recibida como parámetro está ya asignada a un volumen
'en el equipo al que estamos conectados a su servicio WMI,
'conexión establecida por el objeto recibido como parámetro

    Dim str_Letras
    Dim col_Discos
    Dim obj_Disco

    'Primero vamos a obtener las letras de unidad de los
    'discos lógicos, por medio de una consulta WQL
    Set col_Discos = obj_ServicioWMI.ExecQuery("Select * " & _
                                      "from Win32_LogicalDisk")

    'Recorremos los discos lógicos
    For Each obj_Disco in col_Discos

        'Vamos concatenando las diferentes letras de unidad
        'de los discos lógicos
        str_Letras = str_Letras & obj_Disco.DeviceID
    
    Next

    'Ahora obtendremos la lista de letras de unidad asigandas
    'a las unidades de red, por medio de otra consulta WQL
    Set col_Discos = obj_ServicioWMI.ExecQuery("Select * " & _
                                "from Win32_MappedLogicalDisk")

    'Recorremos las unidades de red
    For Each obj_Disco in col_Discos
    
        str_Letras = str_Letras & obj_Disco.DeviceID
    
    Next

    'Comprobamos si aparece la letra de unidad pasada como
    'parámetro entre las letras recogidas tanto en discos
    'lógicos como unidades de red
    If InStr(1, str_Letras, str_Letra, 1)>1 Then
    
        'Si aparece devolvemos True
        f_ExisteLetra = True
        
    Else
    
        'Si no aparece devolvemos False
        f_ExisteLetra = False
        
    End If

    'Seamos pulcros y no dejemos zurraspas :-)
    Set obj_Disco = Nothing
    Set col_Discos = Nothing

End Function

Function f_Cmd(str_Comando)
'Esta función lanza el comando recibido como parámetro
'como si desde una ventana de comandos fuese lanzado
'la devolución es el resultado de la llamada en la ventana
'de comandos: 0 si es exitosa y 1 si hay error

	Dim str_Shell  'Alberga la cadena que permite lanzar
	               'la ventana de comandos predeterminada
				   '(COMSPEC)
	Dim obj_Shell  'Contiene un objeto Shell
	
	'Creamos un objeto Shell
	Set obj_Shell = CreateObject ("Wscript.Shell")
	
	'Obtenemos la cadena que lanza la ventana de comandos 
	'predeterminada
	str_Shell = obj_Shell.Environment("Process").Item("COMSPEC")
	
	'Lanzamos el comando por medio de una llamada al método Run
	'del objeto Shell
	f_Cmd = obj_Shell.Run(str_Shell & " /c """ & str_Comando & """", 0,True)
	
End Function


Sub s_Ayuda(str_Texto)

    WScript.Echo vbCrLf & vbCrLf & str_Texto & vbCrLf &vbCrLf

    WScript.Echo "cambiar-letra-a-cdrom-local.vbs"

    WScript.Echo "Este script nos permite cambiar a una letra " & _
                 "recibida como parámetro, en el equipo local," & _
                 " la letra de unidad de aquel CD-ROM que teng" & _
                 "a como letra una recibida como parámetro. La" & _
                 " sintaxis es:"
    WScript.Echo ""
    WScript.Echo "{wscript | cscript [//nologo]} cambiar-letra-" & _
                 "a-cdrom-local.vbs <letra actual>: <letra nueva>:"
    WScript.Echo ""
    WScript.Echo "Siendo:"
    WScript.Echo ""
    WScript.Echo "    - letra actual (requerido): la letra del" & _
                 " CD-ROM que queremos"
    WScript.Echo "                  cambiar. Si hay más CD-ROM" & _
                 "s no se verán" 
    WScript.Echo "                  afectados, así como si sól" & _
                 "o hay uno y no tiene"
    WScript.Echo "                  esa letra, no se verá afectado."
    WScript.Echo ""
    WScript.Echo "    - letra nueva (requerido): la letra que " & _
                 "se asignará al CD-ROM"
    WScript.Echo "                  que tiene por letra de uni" & _
                 "dad letra actual."
    WScript.Echo ""
    WScript.Echo "Ejemplos:"
    WScript.Echo ""
    WScript.Echo "- Cambiamos a F: el CD-ROM de letra D: usand" & _
                 "o wscript:"
    WScript.Echo ""
    WScript.Echo "wscript cambiar-letra-a-cdrom-local.vbs d: f:"
    WScript.Echo ""
    WScript.Echo "- Cambiamos a F: el CD-ROM de letra D: usand" & _
                 "o cscript:"
    WScript.Echo ""
    WScript.Echo "cscript cambiar-letra-a-cdrom-local.vbs d: f:"

    WScript.Echo "Nota: el script revisa que la letra de desti" & _
                 "no esté libre, y en el caso de estar en uso " & _
                 "no será cambiada la letra al CD-ROM."

End Sub
    
  

 

Script usando WMI (sólo Windows Server 2003)

El presente script no permite cambiar la letra de unidad de CD-ROM a uno o varios equipos, es decri, que trabaja en local y en remoto. Se basa en usar el método Change de la clase Win32_Volume; al tratarse de una clase sólo presente en Windows Server 2003, este script no funcionará con versiones de Windows Pre Windows Server 2003.

Sintaxis:

{wscript | cscript [//nologo]} cambiar-letra-a-cdrom.vbs [[/E:equipos] | [/L:fichero-equipos]] [/C:usuario_conexion] l1: l2:

Siendo:

  • l1: requerido. Letra de unidad del CD-ROM a cambiar.
  • l2: requerido. Letra de unidad que se debe establecer en el CD-ROM.
  • /E: opcional. Lista de equipos a los que se quiere cambiar la letra del CD-ROM. Esta lista son los nombres de los equipos separados por comas. Si se omite este parámetro y también el parámetro /L, se realizará en el equipo local.
  • /L: opcional. Nombre de un fichero de texto en el que está la lista de equipos a los que se debe cambiar la letra del CD-ROM. Los nombres deben ser NetBios y ha de ir un equipo por línea. Si se omite este parámetro y también el parámetro /E, se realizará en el equipo local.
  • /U: opcional. Nombre del usuario que se utilizará para conectar con el servicio WMI del equipo. En caso de omitirse se utilizará el usuario que lanza el script.
  • /C: opcional. Cuando está establecido el parámetro U, este parámetro nos permite especificar la contraseña del usuario que conectará con el servicio WMI. Si no está especificado el parámetro U se ignorará. Si está establecido el parámetro U y este parámetro es omitido, el script presentará una ventana de Internet Explorer donde entrar la contraseña. Es recomendable no usar este parámetro, pues implica que se teclea la contraseña y alguien puede verla; como el usuario debe tener derechos administrativos, es peligroso que tengamos la la contraseña expuesta. Al usar una ventana de IE para teclear la contraseña, esto se realiza en una caja de texto de tipo password, quedando enmascarada, protegida de ojos indiscretos.
  • /?: opcional. Muestra la ayuda en línea.

Nota: si se incluyen los parámetros /E y /L a la vez, prevalecerá el parámetro /L

Ejemplos:

– Cambiamos la letra D: por F: en el equipo local

wscript cambiar-letra-a-cdrom.vbs d: f:

– Cambiamos la letra D: por F: en los equipos pippin, merry y sam

cscript //nologo cambiar-letra-a-cdrom.vbs /E:pippin,merry,sam D: F:

– Cambiamos la letra D: por F: en los equipos de la lista que hay en el fichero c:Listadosequipos-de-hobbiton.txt. Se realizará el cambio con el usuario ComarcaFrodo

cscript cambiar-letra-a-cdrom.vbs
/L:c:Listadosequipos-de-hobbiton.txt /U:ComarcaFrodo D: F:



'cambiar-letra-a-cdrom.vbs
'
'Script VBScript que cambia de letra una unidad de CD-ROM
'
'Sintaxis:
'
'{wscript | cscript [//nologo]} cambiar-letra-a-cdrom.vbs 
'[[/E:equipos] | [/L:fichero-equipos]] 
'[/U:usuario_conexion [/C:contraseña]] l1: l2:
'
'Siendo:
'
'    - l1: requerido. Letra de unidad del CD-ROM a cambiar.
'    - l2: requerido. Letra de unidad que se debe establecer en el 
'                     CD-ROM.
'    - /E: opcional. Lista de equipos a los que se quiere cambiar 
'                    la letra del CD-ROM. Esta lista son los nombres
'                    de los equipos separados por comas. Si se omite
'                    este parámetro y también el parámetro /L, se 
'                    realizará en el equipo local.
'    - /L: opcional. Nombre de un fichero de texto en el que está
'                    la lista de equipos a los que se debe cambiar
'                    la letra del CD-ROM. Los nombres deben ser 
'                    NetBios y ha de ir un equipo por línea. Si se
'                    omite este parámetro y también el parámetro
'                    /E, se realizará en el equipo local.
'    - /U: opcional. Nombre del usuario que se utilizará para conectar
'                    con el servicio WMI del equipo. En caso de
'                    omitirse se utilizará el usuario que lanza el
'                    script.
'    - /C: opcional. Cuando está establecido el parámetro U, este 
'                    parámetro nos permite especificar la contraseña
'                    del usuario que conectará con el servicio WMI.
'                    Si no está especificado el parámetro U se 
'                    ignorará. Si está establecido el parámetro U
'                    y este parámetro es omitido, el script presentará
'                    una ventana de Internet Explorer donde entrar la
'                    contraseña. Es recomendable no usar este parámetro,
'                    pues implica que se teclea la contraseña y alguien
'                    puede verla; como el usuario debe tener derechos
'                    administrativos, es peligroso que tengamos la
'                    la contraseña expuesta. Al usar una ventana de IE
'                    para teclear la contraseña, esto se realiza en
'                    una caja de texto de tipo password, quedando
'                    enmascarada, protegida de ojos indiscretos.
'    - /?: opcional. Muestra la ayuda en línea.
'Nota: si se incluyen los parámetros /E y/L a la vez, prevalecerá
'      el parámetro /L
'
'Ejemplos:
'
'- Cambiamos la letra D: por F: en el equipo local
'
'wscript cambiar-letra-a-cdrom.vbs d: f:
'
'- Cambiamos la letra D: por F: en los equipos pippin, merry y sam
'
'cscript //nologo cambiar-letra-a-cdrom.vbs /E:pippin,merry,sam D: F:
'
'- Cambiamos la letra D: por F: en los equipos de la lista que hay en
'  el fichero c:Listadosequipos-de-hobbiton.txt. Se realizará el
'  cambio con el usuario ComarcaFrodo
'
'cscript cambiar-letra-a-cdrom.vbs /L:c:Listadosequipos-de-hobbiton.txt
' /U:ComarcaFrodo D: F:

'ATENCION: Este script sólo funciona en Windows 2003, no en 2000/XP,
'debido a que no existe la clase Win32_Volume en esos SOs

'© Fernando Reyes - Enero de 2007

'**************  Cuerpo del Script *****************************
'Exigimos la declaración de variables
Option Explicit

'Declaración de variables
Dim str_Equipo, str_Letra, str_LetraNueva
Dim str_Usuario, str_Clave, arr_Equipos
Dim str_Resumen, str_Devolucion
   
'Si se pide la ayuda en línea, mostrarla es lo único que se hará
If WScript.Arguments.Named.Exists("?") Then

    Call s_Ayuda("|*********************|" & vbCrLf & _
                 "|*       Ayuda       *|" & vbCrLf & _
                 "|*********************|")
    WScript.Quit 0
    
End If
  

'Revisamos que se hayan pasado los parámetros
'imprescindibles, esto es, letra a cambiar y 
'nueva letra
If Not WScript.Arguments.Unnamed.Count = 2 Then

    Call s_Ayuda("Error 1: número de argumentos erroneo")
    WScript.Quit 1
    
'Revisamos que se trate de letras válidas (por encima de C
ElseIf Not f_EsLetra(WScript.Arguments.Unnamed(0)) _
Or Not f_EsLetra(WScript.Arguments.Unnamed(1)) Then

    Call s_Ayuda("Error 2: nombre de letra de unidad no válida")
    WScript.Quit 2
    
'Todo correcto, recogemos los dos parámetros de letras
'de unidad
Else

    str_Letra = WScript.Arguments.Unnamed(0)
    str_LetraNueva = WScript.Arguments.Unnamed(1)
    
End If

'Vemos ahora si hemos recogido lista de equipo
If WScript.Arguments.Named.Exists("E") _
Or WScript.Arguments.Named.Exists("L") Then
   
    'Primero miramos si está el parámetro L, fichero con
    'la lista de equipo, y de existir procesaremos los
    'equipos que contenga. De esta manera hacemos que 
    'sea ignorado parámetro E, si está presente
    If WScript.Arguments.Named.Exists("L") Then
    
        'Obtenemos la lista de equipos desde le fichero, 
        'verificando que la función que lo lee devuelve
        'True, pues si devuelve False es que no se ha podido
        'abrir el fichero y por tanto debemos terminar
        'el script
        If Not f_LeeFichero(WScript.Arguments.Named("L"), _
                            str_Equipo) Then

            WScript.Echo vbCrLf & vbCrLf & _
                         "Error 3: No se pudo abrir el " & _
                         "fichero con la lista de equipos"
            WScript.Quit 3
             
        Else
        
            'Se pudo abrir el fichero; hacemos Split considerando
            'la como como separador para así tener la lista como
            'un array
            arr_Equipos = Split(str_Equipo,",")
            
        End If
        
    Else
              
            'Cargamos la lista haciendo Split y considerando la coma
            'como separador de elementos
            arr_Equipos = Split(WScript.Arguments.Named("E"),",")
            
    End If
   
Else
   
    arr_Equipos = Array(".")
       
End If
   
'Miramos si se ha recibido el parámetro de usuario
If WScript.Arguments.Named.Exists("U") Then
   
    'Como se ha recibido, lo recogemos
    str_Usuario = WScript.Arguments.Named("U")

    'Miramos si se ha recibido contraseña
    If WScript.Arguments.Named.Exists("C") Then
    
        'si se ha recibido lo recogemos
        str_Clave = WScript.Arguments.Named("C")
        
    Else
    
        'Como no se ha recibido, llamamos a la función
        'que pedirá al usuario que entre la contraseña
        str_Clave= f_EntrarClave("\fernandor-fcom" & _
                             "partidousuario-conexion.htm")
                             
    End If
   
'No se ha recibido parámetro de usuario, dejamos las
'variables vacías
Else
   
    str_Usuario = ""
    str_Clave = ""
       
End If

'Iniciamos la variable que irá almacenando los resultados
'del proceso; será usada para presentar el resumen al final
str_Resumen = vbCrLf & vbCrLf & _
              "Nom. equipo" & vbTab & "Resultado" & vbCrLf & _
              "============================" & vbCrLf

'Recorremos la lista de nombres de equipos
For Each str_Equipo In  arr_Equipos

    'Vaciamos la variable con la devolución del resultado
    'del equipo anterior
    str_Devolucion = ""
    
    'Llamamos al procedimiento encargado de cambiar la letra
	Call s_ProcesaEquipo(str_Letra, str_LetraNueva, _
	                     str_Equipo, str_Usuario, _
	                     str_Clave, str_Devolucion)
	
	'Si la devolución viene vacía es porque no se ha encontrado
	'la letra de unidad; reflejamos esto en la devolución
	If Len(str_Devolucion) = 0 Then _
	             str_Devolucion = str_Equipo & vbTab & _
	             "Unidad " & str_Letra & " no presente"
	             
	'Añadimos el resultado del equipo actual al resumen
	str_Resumen = str_Resumen & str_Devolucion & vbCrLf
	
Next

'Mostramos el resumen
WScript.Echo str_Resumen

'**************  Fin del Cuerpo del Script **********************

'************* Inicio de Funciones y Procedimientos *************   
Sub s_ProcesaEquipo(str_Letra, str_LetraNueva, _
                    str_Equipo, str_Usuario, _
                    str_Clave, str_Devolucion)
'Este procedimiento se encarga de cambiar la letra del CD-Rom
'Los parámetros que recibe son la letra que se debe cambiar,
'la letra que se debe establecer en su lugar, el nombre del
'equipo en el que se debe realizar el cambio, el nombre de usuario
'que se conectará al servicio WMI del equipo, la contraseña de
'dicho usuario y una variable usada de salida para devolver
'el resultado del proceso


    'Constantes para la forma de consultar con
    'WQL al servicio WMI
    Const wbemFlagReturnImmediately = &h10
    Const wbemFlagForwardOnly = &h20
   
    'Declaración de variables
    Dim obj_ServicioWMI, col_CDROMs, obj_CDROM
    Dim col_Volumenes, obj_Volumen

    'Llamamos a la función que nos permite cargar el objeto
    'servicio WMI. Si la función devuelve False es que no se
    'ha podido crear
    If Not f_ServicioWMI(obj_ServicioWMI, _
                         str_Usuario, _
                         str_Clave, _
                         str_Equipo) Then
                     
        'Lanzamos el mensaje de que ha habido un error en la conexión
        'al servicio WMI
        Wscript.Echo vbcrlf & vbcrlf & _
                     "Error 4: error al conectar con el servicio WMI"
    
        'Terminamos el script con el código de error 4
        WScript.Quit 4
    
    End If
      
    'Creamos una colección de objetos CD-ROM del equipo
    Set col_CDROMs = obj_ServicioWMI.ExecQuery( _
                      "SELECT * FROM Win32_CDROMDrive", "WQL", _
                      wbemFlagReturnImmediately + wbemFlagForwardOnly)
    

    'Recorremos los CD-ROMs del equipo
    For Each obj_CDROM In col_CDROMs
        
        'Verificamos que se trata de la letra que queremos cambiar
        If UCase(str_Letra) = UCase(obj_CDROM.Drive) Then

            'Comprobamos primero que la letra que queremos asignar
            'está libre en el sistema
            If f_ExisteLetra(str_LetraNueva,obj_ServicioWMI) Then
            
                str_Devolucion = str_Equipo & vbTab & _
                                "No se cambió a la letra " & _
                                str_LetraNueva & " por ya estar " & _
                                "asignada a otro volumen"
                Exit For
                
            End If

            'Creamos ahora una colección de volúmenes del CD-ROM
            'por medio de una consulta WQL para poder cambiar su
            'letra. Aquí estña el motivo de que el script sólo
            'funcione con Windows 2003, pues la clase W32_Volume
            'no existe ni en XP ni en Windows 2000
            Set col_Volumenes = obj_ServicioWMI.ExecQuery _
             ("Select * from Win32_Volume Where Name = '" & _
                   str_Letra & "\'")

            'Recorremos los volúmenes del (al ser un CD-ROM sólo
            'hay un volumen) CD-ROM
            For Each obj_Volumen in col_Volumenes
        
                'Indicamos la nueva letra de unidad
                obj_Volumen.DriveLetter = str_LetraNueva
                
                'Establecemos la nueva letra de unidad
                obj_Volumen.Put_
                
                'Recogemos el cambio en la devolucion
                str_Devolucion = str_Equipo & vbTab & "CD-ROM " & _
                                 str_Letra & " cambiado a " & _
                                 str_LetraNueva
             
            Next

        End If

    Next
    
    'Limpiadita de culete :-Þ
    Set obj_Volumen = Nothing
    Set col_Volumenes = Nothing
    Set obj_CDROM = Nothing
    Set col_CDROMs = Nothing
    Set obj_ServicioWMI = Nothing

End Sub 's_ProcesaEquipo


Function f_EntrarClave(str_HTML)
'El propósito de esta función es el proveer al usuario de una caja
'de texto en la que teclear una contraseña sin revelarla, pues
'la caja de texto es de tipo password. Para ello se crea una página
'web que es cargada en un Internet Explorer y se recoge de éste
'la contraseña tecleada y se convierte en la devolucion de la función.
'La ruta y nombre de la página es recibida como parámetro por la
'función, lo que permite reutilizar esta función en más scripts y
'personalizar la página para cada script, lo único que debe ser igual
'en todas las páginas que se quieran utilizar es que el botón debe
'llamarse Aceptar, el control oculto AceptarPulsado y la caja de texto
'Clave.

'Esta función está basada en:
'http://www.microsoft.com/technet/scriptcenter/guide/sas_ent_lppm.mspx?mfr=true

'En el ejemplo de TechNet se pone una ruta local (c:carpetafichero.asp)
'para la ubicación del fichero. Esto no es correcto cuando estamos de
'XP SP2 en adelante, pues la navegación segura interfiere con el script,
'Ya que contiene un script VBScript. Para evitar esto, yo lo que hago
'es situar el fichero en una carpeta compartida y acceder a él con su
'ruta UNC; de esta manera es tratado como de la zona de intranet y no
'hay problemas. También se podría colocar en un servidor Web que fuese
'de la intranet o de los sitios de confianza y referirse a él por su
'ruta http

    'Declaramos variables
    Dim obj_IE

    'Creamos un objeto Internet Explorer
    Set obj_IE = WScript.CreateObject _
              ("InternetExplorer.Application", "IE_")
              
    'Cargamos el navegador con la página recibida como parámetro
    obj_IE.Navigate "file:///" & str_HTML
    
    'Con este bucle esperamos a que la página esté completamente cargada
    Do

        WScript.Sleep 10
    
    Loop Until obj_IE.ReadyState = 4    
    
    'Establecemos propiedades del navegador
    obj_IE.ToolBar = 0
    obj_IE.StatusBar = 0
    obj_IE.Width = 400
    obj_IE.Height = 250
    obj_IE.Left = 0
    obj_IE.Top = 0
    obj_IE.Visible = 1
    
    'En este bucle esperamos a que se haya pulsado el botón
    '"Aceptar"
    Do While (obj_IE.Document.All.AceptarPulsado.Value = "")
    
        WScript.Sleep 250
        
    Loop

    'Recogemos la contraseña entrada
    str_Clave = obj_IE.Document.All.Clave.Value
    
    'Cerramos el navegador
    obj_IE.Quit
    
    'Esperamos a que esté cerrado
    WScript.Sleep 250
    
    'Establecemos la contraseña como devolución de la función
    f_EntrarClave = str_Clave  
    
    'Limpiadita de culito :-)
    Set obj_IE = Nothing

End Function 'f_EntrarClave


Function f_ServicioWMI(obj_ServicioWMI, str_Usuario, _
                       str_Clave, str_Equipo)
'Esta función permite conectar con el servicio WMI de un equipo.
'La conexión puede ser realizada directamente por el usuario
'que ha lanzado el script o por otro usuario cuyas credenciales
'son recibidas como parámetros. La función recibe como parámetro
'un objeto que será utilizado como parámetro de salida, siendo
'creado por la función como objeto de servicio WMI del equipo
'recibido como parámetro
    
    Dim obj_LocalizadorWMI                                                
    Dim lng_Respuesta


    'Si hemos recibido nombre de usuario, debemos conectar 
    'al servicio WMI del equipo como el usuario
    'recibido
    If Len(str_Usuario) > 0 Then
        
        'Para poder especificar unas credenciales alternativas,
        'debemos crear primero un localizador WMI
        Set obj_LocalizadorWMI = CreateObject( _
                                  "WbemScripting.SWbemLocator")
        
        'Establecemos control de errores
        On Error Resume Next
        'Conectamos con el servicio WMI del equipo con las 
        'credenciales pasadas
        Set obj_ServicioWMI = obj_LocalizadorWMI.ConnectServer( _
                                       str_Equipo, "rootcimv2", _
                                       str_Usuario, str_Clave)


        'Si se ha producido algún error...
        If Err.Number <> 0 Then
    
            'Lo primero es vaciar la variable con el localizador WMI
            Set obj_LocalizadorWMI = Nothing
        
            'Mostramos el error
            WScript.Echo vbCrLf  & vbCrLf & _
                         Err.Number & ": " & Err.Description
                         
            
            'Vaciamos el objeto Err
            Err.Clear
            
            'Devolvemos False 
            f_ServicioWMI = False
            
            'Salimos de la función
            Exit Function

        End If

    Else
            
        'Podemos conectar directamente con el servicio WMI del equipo 
        'sin necesidad de utilizar el localizador WMI ya que no hay 
        'que hacerlo con otras credenciales distintas a las del 
        'usuario que lanza el script
        Set obj_ServicioWMI = GetObject("winmgmts:\" & str_Equipo & _
                                        "rootCIMV2")
    
        'si se ha producido algún error...
        If Err.Number <> 0 Then

            'Mostramos el error
            WScript.Echo Err.Number & ": " & Err.Description & _
                         vbCrLf & vbCrLf
            
            'Vaciamos el objeto Err
            Err.Clear
            
            'Devolvemos False 
            f_ServicioWMI = False
            
            'Salimos de la función
            Exit Function

        End If
        
    End If

    'No se han producido errores, devolvemos True
    f_ServicioWMI = True
    
    'Limpieza de culito :-)
    Set obj_LocalizadorWMI = Nothing
    
End Function 'f_ServicioWMI

Function f_LeeFichero(str_Fichero, str_Contenido)
'Esta función recibe una ruta y nombre de fichero de
'texto, y una variable usada como salida para almacenar
'el contenido del fichero. Devuelve True si hubo éxito
'al leer el fichero y False en caso contrario
 
    Dim obj_FS, obj_TS
    
    'Creamos un objeto FileSysteObject
    Set obj_FS = CreateObject("scripting.filesystemobject")
    
    'Establecemos control de errores
    On Error Resume Next
    
    'Cargamos el fichero en el objeto TextStream
    Set obj_TS = obj_FS.OpenTextFile(str_Fichero, 1)
    
    'Si no ha habido errores...
    If Err.Number = 0 Then
    
        'Ponemos el contenido del fichero en la variable de
        'salida, sustituyendo los saltos de línea por comas,
        'preparando la jugada para el uso de Split
        str_Contenido = Replace(obj_TS.ReadAll,vbCrLf,",")
        
        'Como ha habido éxito la función devuelve True
        f_LeeFichero = True
        
        'Cerramos el fichero
        obj_TS.Close
        
    Else
    
        'Ha habido un error a la hora de abrir el fichero.
        'Mostrammos el número y descripción del error
        WScript.Echo "Error " & Err.Number & _
                     ": " & Err.Description
                     
        'Como ha habido error la función devuelve False
        f_LeeFichero = False 
        
        'Limpiamos errores
        Err.Clear           
        
    End If
    
    'Cleaning butt :-)
    Set obj_TS = Nothing
    Set obj_FS = Nothing

End Function


Sub s_Ayuda(str_Texto)
'Este procedimiento muestra la ayuda en línea del script

    'Mostramos un mensaje con la ayuda
    WScript.Echo vbCrLf & vbCrLf & str_Texto & vbCrLf & _
                 vbCrLf
    WScript.Echo "cambiar-letra-a-cdrom.vbs"
    WScript.Echo ""
    WScript.Echo "Script VBScript que cambia de letra " & _
             "una unidad de CD-ROM"
    WScript.Echo ""
    WScript.Echo "Sintaxis:"
    WScript.Echo ""
    WScript.Echo "{wscript | cscript [//nologo]} cambiar-" & _
             "letra-a-cdrom.vbss [[/E:equipos] | [/L:" & _
             "fichero-equipos]] [/U:usuario_conexion] l1: l2:"
    WScript.Echo ""
    WScript.Echo "Siendo:"
    WScript.Echo ""
    WScript.Echo "    - l1: requerido. Letra de unidad del" & _
             " CD-ROM a cambiar."
    WScript.Echo ""
    WScript.Echo "    - l2: requerido. Letra de unidad que" & _
             " se debe establecer en el CD-ROM."
    WScript.Echo ""
    WScript.Echo "    - /E: opcional. Lista de equipos a lo" & _
             "s que se quiere cambiar la letra del"
    WScript.Echo "                    CD-ROM. Esta lista so" & _
             "n los nombres de los equipos separados por comas."
    WScript.Echo "                    Si se omite este pará" & _
             "metro y también el parámetro /L, se realizará "
    WScript.Echo "                    en el equipo local."
    WScript.Echo ""
    WScript.Echo "    - /L: opcional. Nombre de un fichero " & _
             "de texto en el que está la lista de"
    WScript.Echo "                    equipos a los que se " & _
             "debe cambiar la letra del CD-ROM. Los nombres" & _
             " deben"
    WScript.Echo "                    ser NetBios y ha de i" & _
             "r un equipo por línea. Si se omite este parámetro"
    WScript.Echo "                    y también el parámetr" & _
             "o /E, se realizará en el equipo local."
    WScript.Echo ""
    WScript.Echo "    - /U: opcional. Nombre del usuario qu" & _
             "e se utilizará para conectar con el"
    WScript.Echo "                    servicio WMI del equi" & _
             "po. En caso de omitirse se utilizará el usuario"
    WScript.Echo "                    que lanza el script."
    WScript.Echo ""
    WScript.Echo "    - /C: opcional. Cuando está estableci" & _
             "do el parámetro U, este"
    WScript.Echo "                    parámetro nos permite" & _
             " especificar la contraseña"
    WScript.Echo "                    del usuario que conec" & _
             "tará con el servicio WMI."
    WScript.Echo "                    Si no está especifica" & _
             "do el parámetro U se"
    WScript.Echo "                    ignorará. Si está est" & _
             "ablecido el parámetro U"
    WScript.Echo "                    y este parámetro es o" & _
             "mitido, el script presentará"
    WScript.Echo "                    una ventana de Intern" & _
             "et Explorer donde entrar la"
    WScript.Echo "                    contraseña. Es recome" & _
             "ndable no usar este parámetro,"
    WScript.Echo "                    pues implica que se t" & _
             "eclea la contraseña y alguien"
    WScript.Echo "                    puede verla; como el " & _
             "usuario debe tener derechos"
    WScript.Echo "                    administrativos, es p" & _
             "eligroso que tengamos la"
    WScript.Echo "                    la contraseña expuest" & _
             "a. Al usar una ventana de IE"
    WScript.Echo "                    para teclear la contr" & _
             "aseña, esto se realiza en"
    WScript.Echo "                    una caja de texto de " & _
             "tipo password, quedando"
    WScript.Echo "                    enmascarada, protegid" & _
             "a de ojos indiscretos."
    WScript.Echo ""
    WScript.Echo "    - /?: opcional. Muestra la ayuda en línea."
    WScript.Echo ""
    WScript.Echo "Nota: si se incluyen los parámetros /E y/" & _
             "L a la vez, prevalecerá el parámetro /L"
    WScript.Echo ""
    WScript.Echo "Ejemplos:"
    WScript.Echo ""
    WScript.Echo "- Cambiamos la letra D: por F: en el equi" & _
             "po local"
    WScript.Echo ""
    WScript.Echo "wscript cambiar-letra-a-cdrom.vbs d: f:"
    WScript.Echo ""
    WScript.Echo "- Cambiamos la letra D: por F: en los equi" & _
             "pos pippin, merry y sam"
    WScript.Echo ""
    WScript.Echo "cscript //nologo cambiar-letra-a-cdrom.vbs" & _
             " /E:pippin,merry,sam D: F:"
    WScript.Echo ""
    WScript.Echo "- Cambiamos la letra D: por F: en los equi" & _
             "pos de la lista que hay en el fichero c:L" & _
             "istadosequipos-de-hobbiton.txt. Se realiz" & _
             "ará el cambio con el usuario ComarcaFrodo"
    WScript.Echo ""
    WScript.Echo "cscript cambiar-letra-a-cdrom.vbs /L:c:Li" & _
             "stadosequipos-de-hobbiton.txt /U:Comarca" & _
             "Frodo D: F:"

End Sub 's_Ayuda

Function f_EsLetra(str_Letra)
'Esta función recibe una cadena y comprueba que se trate de
'un nombre de unidad válido. Para considerar válido el nombre
'de unidad, consideramos que debe tener una longitud de dos
'caracteres y que debe ser una letra entre C y Z seguida por
'el caracter de dos puntos (Ejemplo: F:)

    Dim obj_RE

    'Si la longitud no es dos, es que no es un nombre de
    'letra válido
    If Len(str_Letra)<>2 Then
    
        f_EsLetra = False
        Exit Function
        
    End If
    
    'Creamos un objeto RegularExpression
    Set obj_RE = New RegExp

    'Establecemos como patrón el primer caracter una letra
    'entre C y Z y el segundo el caracter de dos puntos
    obj_RE.Pattern = "[C-Z]:"
    
    'La función devuelve el resultado del método test
    'del objeto RegularExpression para la letra recibida
    'como parámetro puesta en mayúsculas 
    f_EsLetra = obj_RE.Test(UCase(str_Letra))

    '¡¡Caca fuera!! :-Þ
    Set obj_RE = Nothing

End Function

Function f_ExisteLetra(str_Letra, obj_ServicioWMI)
'Esta función nos permite averiguar si la letra de unidad
'recibida como parámetro está ya asignada a un volumen
'en el equipo al que estamos conectados a su servicio WMI,
'conexión establecida por el objeto recibido como parámetro

    Dim str_Letras
    Dim col_Discos
    Dim obj_Disco

    'Primero vamos a obtener las letras de unidad de los
    'discos lógicos, por medio de una consulta WQL
    Set col_Discos = obj_ServicioWMI.ExecQuery("Select * " & _
	                                    "from Win32_LogicalDisk")

    'Recorremos los discos lógicos
    For Each obj_Disco in col_Discos

        'Vamos concatenando las diferentes letras de unidad
        'de los discos lógicos
        str_Letras = str_Letras & obj_Disco.DeviceID
    
    Next

    'Ahora obtendremos la lista de letras de unidad asigandas
    'a las unidades de red, por medio de otra consulta WQL
    Set col_Discos = obj_ServicioWMI.ExecQuery("Select * " & _
	                             "from Win32_MappedLogicalDisk")

    'Recorremos las unidades de red
    For Each obj_Disco in col_Discos
    
        str_Letras = str_Letras & obj_Disco.DeviceID
    
    Next

    'Comprobamos si aparece la letra de unidad pasada como
    'parámetro entre las letras recogidas tanto en discos
    'lógicos como unidades de red
    If InStr(1, str_Letras, str_Letra, 1)>1 Then
    
        'Si aparece devolvemos True
        f_ExisteLetra = True
        
    Else
    
        'Si no aparece devolvemos False
        f_ExisteLetra = False
        
    End If

    'Seamos pulcros y no dejemos zurraspas :-)
    Set obj_Disco = Nothing
    Set col_Discos = Nothing

End Function
'************* Fin de Funciones y Procedimientos *************   

2 comentarios to “Dos Scripts VBScript Para Cambiar La Letra De Unidad De Un CD-ROM”

  1. Eduardo said

    valdría esto para windows 2000?
    estoy intentando conseguir que un usuario no administrador pueda cambiar letras de unidades. ¿alguien sabe como lo podría conseguir?

  2. urpiano said

    Eduardo,

    Como puedes ver en mi post, sólo se puede hacer con Windows Server 2003; con sistemas anteriores es necesario usar mountvol.exe, es decir, el primer script. Podrías lanzarlo como administrador con RunAs

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

 
A %d blogueros les gusta esto: