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…

PowerShell: Cmdlet para inventariar los volúmenes de un equipo

Posted by urpiano en Lunes 25 \25\UTC octubre \25\UTC 2010

Esta función de PowerShell lista todos los volúmenes de un equipo, local o remoto, en base a una consulta WMI a la clase Win32_Volume, lo que implica que sólo funcionará en equipos posteriores a Windows XP (2003 en adelante). La función permite recibir el nombre del equipo a mirar por encaminamiento, lo que permite encaminar toda una lista de equipos y obtener un listado de sus volúmenes. La función requiere para su función otra función que está también en el código y que sirve para obtener el significado del entero que representa el tipo de volumen.

El Cmdlet incluye ayuda, pego a continuación la ayuda con modificador -Detailed (esta ayuda se basa en la prestación de ayuda basada en comentarios de PowerShell 2.0 ¿Qué todavía tienes la versión 1.0 y no la 2.0? ¿A qué esperas para instalarla si es mucho mejor?):

NOMBRE
    Get-Volume

SINOPSIS
    Lista los volúmenes de un equipo.


SINTAXIS
    Get-Volume [[-ComputerName] ] [[-Credential] ] [<CommonParam


DESCRIPCIÓN
    Este Cmdlet permite obtener un listado de todos los volúmenes de un equipo.
    Permite recibir el nombre del equipo por canalización. Para obtener el
    listado, conecta a WMI y consulta la clase Win32_Volume del espacio de
    nombres Root/CIMv2; esta conexión a WMI se puede hacer con credenciales
    alternativas.


PARÁMETROS
    -ComputerName 
        Nombre o IP del equipo al que se consultará. Tiene también los alias
        "Equipo","Sistema","E","C" y "S".

    -Credential 
        Nombre de usuario o credenciales completas del usuario con el que se
        conectara a WMI. En caso de pasarse sólo el nombre de usuario, se pedirá
        entrar la contraseña del mismo. Si se pasan credenciales y se consulta e
        equipo local, las credenciales serán ignoradas, pues no se puede conecta
        a WMI del equipo local con credenciales alternativas.

    
        Este cmdlet admite los parámetros comunes Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer y OutVariable. Para obtener más información, escriba:
        "get-help about_commonparameters".

    -------------------------- EJEMPLO 1 --------------------------

    PS >Get-Volume -ComputerName Mortadelo-PC

    Muestra por pantalla los volúmenes del equipo de nombre Mortadelo-PC.

    -------------------------- EJEMPLO 2 --------------------------

    PS >Get-Volume -C Mortadelo-PC -Credential TIA\Bacterio

    Muestra por pantalla los volúmenes del equipo de nombre Mortadelo-PC,
    conectando a WMI con el usuario TIA\Bacterio; se solicitará la contraseña
    de dicho usuario.

    -------------------------- EJEMPLO 3 --------------------------

    PS >"Mortadelo-PC","Filemon-PC" | Get-Volume -Cred TIA\Bacterio

    Muestra por pantalla los volúmenes de los equipos de nombre Mortadelo-PC y
    Filemon-PC, conectando a WMI con el usuario TIA\Bacterio; se solicitará la
    contraseña de dicho usuario.

    -------------------------- EJEMPLO 4 --------------------------

    PS >$Usuario = Get-Credential
    PS >"Mortadelo-PC","Filemon-PC" | Get-Volume -Usuario $Usuario

    Muestra por pantalla los volúmenes de los equipos de nombre Mortadelo-PC y
    Filemon-PC, conectando a WMI con el usuario establecido previamente con
    Get-Credential en la variable $Usuario.

    -------------------------- EJEMPLO 5 --------------------------

    PS >$Usr = Get-Credential
    PS >Get-Content c:\Equipos.txt | Get-Volume -U $Usr | Export-CSV c:\Vol.csv

    Este ejemplo muestra una manera muy útil de usar esta función. Guarda, en el
    fichero de valores separados por coma c:\Vol.csv, un listado con los
    volúmenes de los equipos listados en el fichero de texto c:\Equipos.txt, que
    contiene un nombre de equipo por línea, conectando a WMI con el usuario,
    establecido previamente con Get-Credential, en la variable $Usr.

Este es el código del Cmdlet:

Function Get-DriveType([Parameter(Mandatory=$True,
                                  ValueFromPipelineByPropertyName=$true)]
                           [int]$DriveType)
{
    Begin
    {
        # Iniciamos la devolución en Begin por si se han recibido varios objetos
        # Win32_Volume por canalización
        $Devolucion = @()
    }
    Process
    {
        # Analizamos el tipo y, en función del número recibido, agregamos a la
        # devolución el significado
        $Devolucion += Switch($DriveType)
                       {
                           1{"Indeterminado"}
                           2{"Extraíble"}
                           3{"Fijo"}
                           4{"Red"}
                           5{"CD/DVD"}
                           6{"RAM"}
                           Default{"Desconocido"}
                       }
    }
    End
    {
        # Realizamos la devolución
        $Devolucion
    }
#.SYNOPSIS
#   Devuelve el significado de la constante de tipo de disco recibida
#   como parámetro.
#.DESCRIPTION
#   Este Cmdlet permite obtener el significado de la constante de tipo de disco
#   (DriveType) de un objeto Win32_Volume (3, por ejemplo, significa disco fijo)
#
#   La función permite canalización, admitiendo como entrada objetos de WMI de
#   la clase Win32_Volume del espacio de nombres Root/CIMv2
#.NOTES
#   Desarrollado por Fernando Reyes López
#   Octubre de 2010
#.LINK
#   http://freyes.svetlian.com -> Artículos de Fernando reyes
#.LINK
#   https://urpiano.wordpress.com -> El Blog de GualtrySoft
#.EXAMPLE
#     PS >Get-DriveType 3
#   Muestra por pantalla el significado del tipo de volumen 3.
#.EXAMPLE
#     PS >Get-WmiObject Win32_Volume | Get-DriveType
#   Muestra por pantalla los significados de los números de tipo de volumen de
#   los volumenes del equipo local.
}
Function Get-Volume([parameter(Position=0,
                               ValueFromPipeLine=$True,
                               HelpMessage="Nombre de equipo.")]
                        [Alias("Equipo","Sistema","E","C","S")]
                        [String]$ComputerName = "$($env:ComputerName)",
                    [parameter(Position=2,
                             Mandatory=$false,
                             HelpMessage="Credenciales de usuario de conexión")]
                        [Alias("Usuario","U","Credenciales","Cred")]
                        $Credential)
{

    Begin
    {
        # Iniciamos la devolución de la función. El hacerlo en el bloque Begin
        # permite que se vaya poblando con las distintas devoluciones que se
        # produzcan en el bloque Process para luego ser devuelto todo en el
        # bloque End. Esto permite que si se reciben el nombre del equipo por
        # canalización, y esta canalización implica toda una lista de equipos,
        # se puedan volcar los resultados de todos los equipos, también por
        # canalización, a otro Cmdlet, por ejemplo Export-Csv, lo que nos daría
        # un listado de todos los volumenes de todos los equipos que se
        # recibieran en la canalización; si no se hiciera con Begin/Process/End
        # el fichero obtenido con Export-Csv tan solo contendría los volúmenes
        # del último equipo procesado.
        $Devolucion = @()
        # Si no se han pasado unas credenciales completas, si no sólo un nombre
        # de usuario, hay que llamar a Get-Credential para obtenerlas completas
        If($Credential -ne $null -and `
          ($Credential.GetType()).Name -ne "PsCredential")
        {
                $Credential = Get-Credential $Credencial
        }
    }
    Process
    {
        # Si se recibió como nombre de equipo un punto, esto implica el equipo
        # local; sustituimos el punto por el nombre de equipo
        If($ComputerName -eq "."){$ComputerName = "$($env:ComputerName)"}
        # Mostramos el nombre del equipo en proceso. Importante el uso de
        # Write-Host, para evitar que el texto mostrado forme parte de la
        # devolución del comando
        Write-Host "Procesando $ComputerName"
        # Iniciamos el comando que obtendrá la lista de volúmenes consultando
        # WMI, en concreto la clase Win32_Volume del espacio de nombres CIMv2
        $Comando = "Get-WmiObject Win32_Volume"
        $Comando = "$Comando -Namespace root/CIMv2"
        # Agregamos el nombre de equipo
        $Comando = "$Comando -ComputerName $ComputerName"
        # Si se han pasado credenciales
        If($Credential -ne $null)
        {
            # Agregamos las credenciales, guardando el comando sin ellas
            $ComandoSinCredenciales = $Comando
            $Comando = "$Comando -Credential `$Credential"
        }
        # Limpiamos la variable de errores
        $Error.Clear()
        # Nos guardamos la configuración existente ante los errores que no
        # interrumpen
        $AccionError = $ErrorActionPreference
        # Establecemos que los errores que no interrumpen sí lo hagan, así
        # podremos capturarlos con Try/Catch
        $ErrorActionPreference = "Stop"
        # Invocamos el comando montado para obtener la lista de discos,
        # interceptando errores
        Try
        {
            $Volumenes = Invoke-Expression $Comando
        }
        Catch
        {
            # Si el error producido es provocado porque se ha intentado pasar
            # credenciales al equipo local...
            If($Error[0].Exception.ErrorCode -eq "LocalCredentials")
            {
                # Restituimos el comando para que sea sin pedir credenciales
                $Comando = $ComandoSinCredenciales
                # Volvemos a invocar el comando para obtener los volúmenes
                $Volumenes = Invoke-Expression $Comando
            }
            Else
            {
                Write-Host "$ComputerName`: $($Error[0].Exception.Message)" `
                           -ForegroundColor Red
                # Como se produce error generaremos un resultado en el que
                # todo tendrá valor nulo excepto el nombre del equipo y el error
                # que se ha producido. Por tanto, creamos un objeto para el 
                # resultado
                $Resultado = New-Object PsCustomObject
                # Agregamos el nombre del equipo
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Equipo `
                        -Value $ComputerName
                # Agregamos el ID de volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name ID `
                        -Value $null
                # Agregamos el Tipo de volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Tipo `
                        -Value (Get-DriveType 0)
                # Agregamos la letra del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Letra `
                        -Value $null
                # Agregamos el tamaño del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Capacidad `
                        -Value $null
                # Agregamos el espacio libre del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name EspacioLibre `
                        -Value $null
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Ocupado `
                        -Value $null
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name PorcentOcupado `
                        -Value $null
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name PorcentLibre `
                        -Value $null
                # Agregamos eltamaño de bloque del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name ByteBloque `
                        -Value $null
                # Agregamos el sistema de archivos del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name FileSystem `
                        -Value $null
                # Agregamos el número de serie del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name NSerie `
                        -Value $null
                # Agregamos si el volumen es o no de sistema volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name DeSistema `
                        -Value $null
                # Agregamos si el volumen es o no de arranque
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name DeArranque `
                        -Value $null
                # Agregamos el error producido
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Error `
                        -Value $Error[0].Exception.Message
                # Agregamos el resultado a la devolución de la función
                $Devolucion += $Resultado
                # Vaciamos la colección de volumenes por si estamos recibiendo
                # los nombres de equipos por encaminamiento, para evitar que se
                # vuelvan a listar los volumenes del equipo procesado
                # previamente
                $Volumenes = $null
            }
        }
        # Restituimos la acción que estaba configurada para los errores que no
        # interrumpen
        $ErrorActionPreference = $AccionError
        # Recorremos la lista de volumenes obtenida, siempre y cuando no esté
        # vacía
        If($Volumenes.Count -gt 0)
        {
            ForEach($Volumen In $Volumenes)
            {
                # Iniciamos la devolución del volumen actual
                $Resultado = New-Object PsCustomObject
                # Agregamos el nombre del equipo
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Equipo `
                        -Value $Volumen.SystemName
                # Agregamos el ID de volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name ID `
                        -Value $Volumen.DeviceID
                # Agregamos el Tipo de volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Tipo `
                        -Value (Get-DriveType $Volumen.DriveType)
                # Agregamos la letra del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Letra `
                        -Value $Volumen.DriveLetter
                # Agregamos el tamaño del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Capacidad `
                        -Value $Volumen.Capacity
                # Agregamos el espacio libre del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name EspacioLibre `
                        -Value $Volumen.FreeSpace
                # Si el volúmen tiene tamaño (una unidad de CD/DVD sin disco, por
                # ejemplo, tendrá este valor nulo)...
                If($Volumen.Capacity -gt 0)
                {
                # Agregamos el espacio ocupado del volúmen
                    Add-Member -InputObject $Resultado `
                            -MemberType NoteProperty `
                            -Name Ocupado `
                            -Value ($Volumen.Capacity - $Volumen.FreeSpace)
                # Agregamos el tanto por ciento de espacio ocupado del volúmen
                    Add-Member -InputObject $Resultado `
                            -MemberType NoteProperty `
                            -Name PorcentOcupado `
                            -Value (($Volumen.Capacity - $Volumen.FreeSpace) `
                                        /$Volumen.Capacity)
                # Agregamos el tanto por ciento de espacio libre del volúmen
                    Add-Member -InputObject $Resultado `
                            -MemberType NoteProperty `
                            -Name PorcentLibre `
                            -Value ($Volumen.FreeSpace / $Volumen.Capacity)
                }
                # Si el volumen no tiene tamaño, tanto el espacio ocupado como
                # los porcentajes de espacio ocupado y espacio libre se
                # agregaran como nulos
                Else
                {
                    Add-Member -InputObject $Resultado `
                            -MemberType NoteProperty `
                            -Name Ocupado `
                            -Value $null
                    Add-Member -InputObject $Resultado `
                            -MemberType NoteProperty `
                            -Name PorcentOcupado `
                            -Value $null
                    Add-Member -InputObject $Resultado `
                            -MemberType NoteProperty `
                            -Name PorcentLibre `
                            -Value $null
                }
                # Agregamos eltamaño de bloque del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name ByteBloque `
                        -Value $Volumen.BlockSize
                # Agregamos el sistema de archivos del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name FileSystem `
                        -Value $Volumen.FileSystem
                # Agregamos el número de serie del volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name NSerie `
                        -Value $Volumen.SerialNumber
                # Agregamos si el volumen es o no de sistema volúmen
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name DeSistema `
                        -Value $Volumen.SystemVolume
                # Agregamos si el volumen es o no de arranque
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name DeArranque `
                        -Value $Volumen.BootVolume
                # Agregamos que no se ha producido error
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Error `
                        -Value $null
                # Agregamos el resultado a la devolución
                $Devolucion += $Resultado
            }
        }
    }
    End
    {
        # Se produce la devolución de la función
        $Devolucion
    }
#.SYNOPSIS
#   Lista los volúmenes de un equipo.
#.DESCRIPTION
#   Este Cmdlet permite obtener un listado de todos los volúmenes de un equipo.
#   Permite recibir el nombre del equipo por canalización. Para obtener el
#   listado, conecta a WMI y consulta la clase Win32_Volume del espacio de
#   nombres Root/CIMv2; esta conexión a WMI se puede hacer con credenciales
#   alternativas.
#.PARAMETER ComputerName
#   Nombre o IP del equipo al que se consultará. Tiene también los alias
#   "Equipo","Sistema","E","C" y "S".
#.PARAMETER Credential
#   Nombre de usuario o credenciales completas del usuario con el que se
#   conectara a WMI. En caso de pasarse sólo el nombre de usuario, se pedirá
#   entrar la contraseña del mismo. Si se pasan credenciales y se consulta el
#   equipo local, las credenciales serán ignoradas, pues no se puede conectar
#   a WMI del equipo local con credenciales alternativas.
#.NOTES
#   SO requerido: Windows 2003 o posterior. Windows 2000/XP da el error "Clase
#   no válida" por tratarse de SOs que no tienen la clase Win32_Volume
#
#   Desarrollado por Fernando Reyes López
#   Octubre de 2010
#.LINK
#   http://freyes.svetlian.com -> Artículos de Fernando reyes
#.LINK
#   https://urpiano.wordpress.com -> El Blog de GualtrySoft
#.EXAMPLE
#     PS >Get-Volume -ComputerName Mortadelo-PC
#   Muestra por pantalla los volúmenes del equipo de nombre Mortadelo-PC.
#.EXAMPLE
#     PS >Get-Volume -C Mortadelo-PC -Credential TIA\Bacterio
#   Muestra por pantalla los volúmenes del equipo de nombre Mortadelo-PC,
#   conectando a WMI con el usuario TIA\Bacterio; se solicitará la contraseña
#   de dicho usuario.
#.EXAMPLE
#     PS >"Mortadelo-PC","Filemon-PC" | Get-Volume -Cred TIA\Bacterio
#   Muestra por pantalla los volúmenes de los equipos de nombre Mortadelo-PC y
#   Filemon-PC, conectando a WMI con el usuario TIA\Bacterio; se solicitará la
#   contraseña de dicho usuario.
#.EXAMPLE
#     PS >$Usuario = Get-Credential
#     PS >"Mortadelo-PC","Filemon-PC" | Get-Volume -Usuario $Usuario
#   Muestra por pantalla los volúmenes de los equipos de nombre Mortadelo-PC y
#   Filemon-PC, conectando a WMI con el usuario establecido previamente con
#   Get-Credential en la variable $Usuario.
#.EXAMPLE
#     PS >$Usr = Get-Credential
#     PS >Get-Content c:\Equipos.txt | Get-Volume -U $Usr | Export-CSV c:\Vol.csv
#   Este ejemplo muestra una manera muy útil de usar esta función. Guarda, en el
#   fichero de valores separados por coma c:\Vol.csv, un listado con los
#   volúmenes de los equipos listados en el fichero de texto c:\Equipos.txt, que
#   contiene un nombre de equipo por línea, conectando a WMI con el usuario,
#   establecido previamente con Get-Credential, en la variable $Usr.
}

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: