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 las particiones de los discos de un clúster de Windows Server 2008

Posted by urpiano en Jueves 7 \07\UTC octubre \07\UTC 2010

Esta función de PowerShell lista las particiones de los discos de un clúster de Windows Server 2008. Se puede lanzar directamente desde un nodo del clúster o en remoto especificando el nombre de un nodo del clúster; cuando se hace en remoto, se pueden especificar credenciales alternativas para la conexión. El listado se puede ver por pantalla o exportarlo a un fichero de valores separados por tabulador (ideal para ser abierto por Excel). Sólo tiene sentido usarlo con Windows Server 2008 y no con Windows Server 2008 R2, pues éste último tiene Cmdlets específicos para administrar un clúster.

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-ClusterDiskInventory
    
SINOPSIS
    Lista las particiones de los discos de un clúster de Windows 2008.
    
SINTAXIS
    Get-ClusterDiskInventory [[-Nodo] ] [[-Fichero] ] [[-Credencial] ] []
    
DESCRIPCIÓN
    Este Cmdlet permite obtener un listado de todas las particiones de los
    discos de un clúster de Windows Server 2008. Para ello realiza consultas
    WMI. Con Windows 2008 R2 existen Cmdlets para clúster, cosa que no sucede
    con Windows 2008, de ahí el que haber desarrollado este Cmdlet.

PARÁMETROS
    -Nodo 
        Nombre o IP del nodo del clúster al que se consultará. Si se omite, se
        consulta el equipo local (obviamente, debe pertenecer a un clúster para que
        funcione la consulta).
        
    -Fichero 
        Si se pasa este modificador los resultados se guardarán en el fichero de
        valores separados por tabuladores (ideal para ser abierto con Excel) 
        especificado.
        
    -Credencial 
        Objeto PsCredential (obtenido de ejecutar Get-Credential) o nombre de
        usuario con el que se conectará al nodo remoto. En caso de pasarse el nombre
        de usuario, se solicitará la contraseña, en caso de pasarse un objeto
        PsCredential ésta no será solicitada. Si el nodo consultado es el equipo
        local se ignorará este parámetro, pues no se puede conectar 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 --------------------------
    
    C:\PS>Get-ClusterDiskInventory
    
    Muestra por pantalla las particiones de los discos del clúster al que
    pertenece el nodo desde el que se ejecuta.
 
    -------------------------- EJEMPLO 2 --------------------------
    
    C:\PS>Get-ClusterDiskInventory -Nodo N01HVTIA
    
    Muestra por pantalla las particiones de los discos del clúster al que
    pertenece el nodo N01HVTIA.
 
    -------------------------- EJEMPLO 3 --------------------------
    
    C:\PS>Get-ClusterDiskInventory -Nodo N01HVTIA -Fichero d:\DiskCluster.tab
    
    Guarda en un fichero de valores separados por tabuladores un listado con las
    particiones de los discos del clúster al que pertenece el nodo N01HVTIA.

    -------------------------- EJEMPLO 4 --------------------------
    
    C:\PS>Get-ClusterDiskInventory -Nodo N01HVTIA -Fichero d:\DiskCluster.tab -Credential TIA\Mortadelo
    
    Guarda en un fichero de valores separados por tabuladores un listado con las
    particiones de los discos del clúster al que pertenece el nodo N01HVTIA. Se
    conectará a WMI como el usuario TIA\Mortadelo, pidiendo que se entre la
    contraseña.
    
    -------------------------- EJEMPLO 5 --------------------------
    
    C:\PS>$Credencial = Get-Credential
    
    Get-ClusterDiskInventory -Nodo N01HVTIA -Fichero d:\DiskCluster.tab -Credential $Credencial
    
    Guarda en un fichero de valores separados por tabuladores un listado con las
    particiones de los discos del clúster al que pertenece el nodo N01HVTIA. Se
    conectará a WMI como el usuario cuyas credenciales están en la variable
    $Credential, obtenida con Get-Credential.

Este es el código del Cmdlet:

Function Get-ClusterDiskInventory([string]$Nodo, `
                                  [string] $Fichero,
                                  $Credencial)
{
    # Montamos el comando que trae la lista de discos del clúster. Primero
    # especificamos la clase (MSCluster_Disk) y el espacio de nombres (
    # root/MSCluster)
    $Comando = "Get-WmiObject MSCluster_Disk -Namespace root/MSCluster"
    # Si queremos consultar un nodo distinto del local lo agregamos al comando
    If($Nodo.Length -gt 0)
    {
        # Para poder conectar al espacio de nombres MSCluster, es necesario que
        # el tipo de autehticación sea PacketPrivacy
        $Comando = "$Comando -ComputerName $Nodo -Authentication PacketPrivacy"
    }
    # Si queremos unas credenciales distintas de las locales, lo agregamos al
    # comando
    If($Credencial -ne $null)
    {
        # 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(($Credencial.GetType()).Name -ne "PsCredential")
        {
            $Credencial = Get-Credential $Credencial
        }
        # Agregamos las credenciales
        $ComandoSinCredenciales = $Comando
        $Comando = "$Comando -Credential `$Credencial"
    }
    # 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
    {
        $Discos = 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")
        {
            # Marcamos una booleana que no informa que se trata del equipo local
            $Local = $true
            # Restituimos el comando para que sea sin pedir credenciales
            $Comando = $ComandoSinCredenciales
            # Volvemos a invocar el comando para obtener los discos del clúster
            $Discos = Invoke-Expression $Comando
        }
    }
    # restituimos la acción que estaba configurada para los errores que no
    # interrumpen
    $ErrorActionPreference = $AccionError
    #Iniciamos la salida de la función cuando es por fichero
    $Salida = @()
    
    # Recorremos uno a uno los discos
    ForEach($Disco In $Discos)
    {
        # Obtenemos el identificador de disco, necesario para enlazar discos con
        # particiones por medio de la clase de asociación entre ambos, que
        # es la clase MSCluster_DiskToDiskPartition
        $ID = $Disco.ID
        
        # Montamos el filtro de la consulta WMI usando el ID del disco
        $Filtro = "GroupComponent = """"MSCluster_Disk.ID=`'$ID`'"""""
        
        # Iniciamos el comando especificando clase (
        # MSCluster_DiskToDiskPartition) y espacio de nombres (root/MSCluster)
        $Comando = "Get-WmiObject MSCluster_DiskToDiskPartition "
        $Comando = "$Comando -Namespace root/MSCluster"
        # Si queremos consultar un nodo distinto del local lo agregamos al
        # comando
        If($Nodo.Length -gt 0)
        {
            # Para poder conectar al espacio de nombres MSCluster, es necesario 
            # que el tipo de autehticación sea PacketPrivacy
            $Comando = `
                    "$Comando -ComputerName $Nodo -Authentication PacketPrivacy"
        }
        # Si queremos unas credenciales distintas de las locales, lo agregamos
        # al comando, eso sí, si no se trata del equipo local
        If($Credencial -ne $null -and $Local -ne $true)
        {
            $Comando = "$Comando -Credential `$Credencial"
        }
        # Agregamos el filtro al comando
        $Comando = "$Comando -Filter ""$Filtro"""
        # Vaciamos la variable con la ruta de la partición
        $Enlaces = $null
        # Obtenemos los enlaces a del disco a sus partitiones
        $Enlaces = Invoke-Expression $Comando
        ForEach($Enlace In $Enlaces)
        {
            # Continuación obtendremos el objeto de la clase
            # MSCluster_DiskPartition correspondiente al disco actual, gracias
            # al enlace que hemos obtenido con MSCluster_DiskToDiskPartition
            $Comando = "Get-WmiObject MSCluster_DiskPartition"
            # Agregamos el espacio de nombres
            $Comando = "$Comando -Namespace root/MSCluster"
            # Si queremos consultar un nodo distinto del local lo agregamos al
            # comando
            If($Nodo.Length -gt 0)
            {
                $Comando = `
                    "$Comando -ComputerName $Nodo -Authentication PacketPrivacy"
            }
            # Si queremos unas credenciales distintas de las locales, las
            # agregamos al comando, eso sí, si no se trata del equipo local
            If($Credencial -ne $null -and $Local -ne $true)
            {
                $Comando = "$Comando -Credential `$Credencial"
            }
            # Obtenemos la ruta de la partición con la Propiedad PartComponent;
            # esta ruta es la que nos permite enlazar con la clase
            # MSCluster_DiskPartition
            $Ruta = $Enlace.PartComponent
            # A la hora de usar la ruta de la partición, debemos quitarle el
            # significado al slash inverso, poniéndolo doble (Por ejemplo "\TIA" 
            # se convierte en "\\TIA")
            $Ruta = $Ruta -replace ("\\","\\")
            # A la hora de usar la ruta de la partición, debemos quitarle el
            # significado a las dobles comillas, poniéndolas dobles (Por ejemplo  
            # '"TIA"' se convierte en '""TIA""')
            $Ruta = $Ruta -replace ("""","""""")
            # Montamos el filtro
            $Filtro = "__RELPATH = `'$Ruta`'"
            # Agregamos el filtro al comando
            $Comando = "$Comando -Filter ""$Filtro"""
            # Ejecutamos el comando para obtener la partición
            $Particion = Invoke-Expression $Comando
            # Creamos el objeto que se agregará a la salida de la función
            $Devolucion = New-Object PsObject
            # A continuación le agregamos las propiedades de Ruta de partición,
            # Nombre de disco, etiqueta de la partición, espacio total, espacio
            # ocupado, espacio libre, tanto por ciento de espacio ocupado y tanto
            # por ciento de espacio libre.
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name Ruta `
                        -Value $Particion.Path
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name NombreDisco `
                        -Value $Disco.Name
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name IdDisco `
                        -Value $Disco.ID
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name Etiqueta `
                        -Value $Particion.VolumeLabel
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name MBTotales `
                        -Value $Particion.TotalSize
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name MBLibres `
                        -Value $Particion.FreeSpace
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name MBOcupados `
                        -Value ($Particion.TotalSize - $Particion.FreeSpace)
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name PorcenOcupado `
                        -Value (($Particion.TotalSize - $Particion.FreeSpace)/ `
                                $Particion.TotalSize)
            Add-Member -InputObject $Devolucion `
                        -MemberType NoteProperty `
                        -Name PorcenLibre `
                        -Value ($Particion.FreeSpace / $Particion.TotalSize)
            # Si hay que exportar a fichero, agregamos el objeto a la salida
            If($Fichero.Length -gt 0)
            {
                # Agregamos el objeto a la salida de la función
                $Salida += $Devolucion
            }
            # Como no se exporta a CSV, se muestra por pantalla el objeto
            Else
            {
                $Devolucion
            }
        }
    }
    # Si hay que exportar a fichero la salida lo hacemos
    If($Fichero.Length -gt 0)
    {
        # Ordenamos los objetos por nombre de disco
        $Salida = $Salida | Sort-Object -Property Disco
        # Exportamos a fichero
        $Salida | Export-Csv $Fichero -NoTypeInformation -Delimiter "`t"
    }
 
#.SYNOPSIS
#   Lista las particiones de los discos de un clúster de Windows 2008.
#.DESCRIPTION
#   Este Cmdlet permite obtener un listado de todas las particiones de los
#   discos de un clúster de Windows Server 2008. Para ello realiza consultas
#   WMI. Con Windows 2008 R2 existen Cmdlets para clúster, cosa que no sucede
#   con Windows 2008, de ahí el que haber desarrollado este Cmdlet.
#.PARAMETER Nodo
#   Nombre o IP del nodo del clúster al que se consultará. Si se omite, se
#   consulta el equipo local (obviamente, debe pertenecer a un clúster para que
#   funcione la consulta).
#.PARAMETER Credencial
#   Objeto PsCredential (obtenido de ejecutar Get-Credential) o nombre de
#   usuario con el que se conectará al nodo remoto. En caso de pasarse el nombre
#   de usuario, se solicitará la contraseña, en caso de pasarse un objeto
#   PsCredential ésta no será solicitada. Si el nodo consultado es el equipo
#   local se ignorará este parámetro, pues no se puede conectar a WMI del equipo
#   local con credenciales alternativas.
#.PARAMETER Fichero
#   Si se pasa este modificador los resultados se guardarán en el fichero de
#   valores separados por tabuladores (ideal para ser abierto con Excel) 
#   especificado.
#.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
#     Get-ClusterDiskInventory
#
#   Muestra por pantalla las particiones de los discos del clúster al que
#   pertenece el nodo desde el que se ejecuta.
#.EXAMPLE
#     Get-ClusterDiskInventory -Nodo N01HVTIA
#
#   Muestra por pantalla las particiones de los discos del clúster al que
#   pertenece el nodo N01HVTIA.
#.EXAMPLE
#     Get-ClusterDiskInventory -Nodo N01HVTIA -Fichero d:\DiskCluster.tab
#
#   Guarda en un fichero de valores separados por tabuladores un listado con las
#   particiones de los discos del clúster al que pertenece el nodo N01HVTIA.
#.EXAMPLE
#     Get-ClusterDiskInventory -Nodo N01HVTIA -Fichero d:\DiskCluster.tab -Credential TIA\Mortadelo
#
#   Guarda en un fichero de valores separados por tabuladores un listado con las
#   particiones de los discos del clúster al que pertenece el nodo N01HVTIA. Se
#   conectará a WMI como el usuario TIA\Mortadelo, pidiendo que se entre la
#   contraseña.
#.EXAMPLE
#     $Credencial = Get-Credential
#     Get-ClusterDiskInventory -Nodo N01HVTIA -Fichero d:\DiskCluster.tab -Credential $Credencial
#
#   Guarda en un fichero de valores separados por tabuladores un listado con las
#   particiones de los discos del clúster al que pertenece el nodo N01HVTIA. Se
#   conectará a WMI como el usuario cuyas credenciales están en la variable
#   $Credential, obtenida con Get-Credential.
}

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: