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 obtener información sobre la memoria física de un equipo

Posted by urpiano en Miércoles 3 \03\UTC noviembre \03\UTC 2010

Esta función de PowerShell obtiene información sobre la memoria física de un equipo, local o remoto, en base a una consulta WMI a la clase Win32_PhysicalMemory. La función permite recibir el nombre del equipo a mirar por encaminamiento, lo que permite encaminar toda un conjunto de equipos y obtener un listado de memoria física.

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-PhysicalMemory

SINOPSIS
    Devuelve información sobre la memoria física de la máquina.

SINTAXIS
    Get-PhysicalMemory [[-ComputerName] &String&] [[-Credential] &Object&] [&CommonParameters&]

DESCRIPCIóN
    Este Cmdlet permite obtener información sobre la memoria física de la
    máquina recibida como parámetro o de la máquina local si se omite este
    parámetro. La información es obtenida procesando la clase WMI
    Win32_PhysicalMemory del espacio de nombres root/CIMv2. La función permite
    especificar las credenciales con las que se conectará a WMI, credenciales
    que serán ignoradas en el caso del equipo local, pues no se puede acceder a
    WMI con credenciales alternativas desde el equipo local.

    La devolución de la función consiste en objetos cuyas propiedades son:
       - Equipo:  Nombre del equipo del que se obtiene información de la memoria
                  física.
       - Modulos: Recuento de tipos de módulos que hay en la máquina, por tamaño
                  expresado en MegaBytes. El formato de este campo es
                  (tamaño1*nºmódulos)MB;(tamaño2*nºmódulos)MB;....
       - TotalMB: Tamaño total de la memoria, obtenido al sumar el tamaño de los
                  los módulos que la integran.
       - Error:   Si se produce un error al intentar obtener la información,
                  esta propiedad contiene el error que se produjo. Si no se
                  produjo error, el valor de esta propiedad es $null

    La función permite canalización, admitiendo como entrada nombres o IPs de
    equipos

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 el
        equipo local, las credenciales serán ignoradas, pues no se puede conectar
        a WMI del equipo local con credenciales alternativas. Tiene también los
        alias "Usuario","U","Credenciales" y "Cred".

    
        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-PhysicalMemory

    Muestra por pantalla la memoria física del equipo local.

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

    PS >Get-PhysicalMemory -ComputerName Mortadelo-PC

    Muestra por pantalla la memoria física del equipo de nombre Mortadelo-PC.

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

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

    Muestra por pantalla la memoria física del equipo de nombre Mortadelo-PC,
    conectando a WMI con el usuario TIA\Bacterio; se solicitará la contraseña
    de dicho usuario.

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

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

    Muestra por pantalla la memoria física 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 5 --------------------------

    PS >$Usuario = Get-Credential

    PS >"Mortadelo-PC","Filemon-PC" | Get-PhysicalMemory -Usuario $Usuario
    Muestra por pantalla la memoria física 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 6 --------------------------

    PS >$Usr = Get-Credential

    PS >Get-Content c:\Equipos.txt | Get-PhysicalMemory -U $Usr | Export-CSV c:\Mem.csv
    Este ejemplo muestra una manera muy útil de usar esta función. Guarda, en el
    fichero de valores separados por coma c:\Mem.csv, un listado con la memoria
    física  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-PhysicalMemory([parameter(position=0,
                               ValueFromPipeLine=$True,
                               HelpMessage="Nombre de equipo.")]
                        [Alias("Equipo","Sistema","E","C","S")]
                        [String]$ComputerName = "$($env:ComputerName)",
                    [parameter(Position=1,
                             Mandatory=$false,
                             HelpMessage="Credenciales de usuario de conexión")]
                        [Alias("Usuario","U","Credenciales","Cred")]
                        $Credential)
{
    Begin
    {
        $Devolucion = @()
    }
    Process
    {
        # 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 $Credential
        }
        # 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)"}
        # Iniciamos el comando que obtendrá la memoria física del equipo
        # consultando WMI, en concreto la clase Win32_PhysicalMemory del espacio
        # de nombres CIMv2
        $Comando = "Get-WmiObject Win32_PhysicalMemory"
        $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 módulos de
        # memoria, interceptando errores
        Try
        {
            # Obtenemos los módulos de memoria del equipo
            $Modulos = Invoke-Expression $Comando
            # Iniciamos el Hash del recuento, en el que las claves serán los
            # diferentes tamaños, en MB, de los módulos y el valor será el
            # número de módulos de cada tamaño
            $Recuento = @{}
            # Recorremos los módulos
            ForEach($Modulo In $Modulos)
            {
                # Si ya está como clave el tamaño del módulo actual, sumamos uno
                # al valor de la clave
                If($Recuento.Keys -contains ($Modulo.Capacity/1mb))
                {
                    $Recuento.(($Modulo.Capacity/1mb))++
                }
                # Como no existe esa clave, la agregamos con valor uno
                Else
                {
                    $Recuento += @{($Modulo.Capacity/1mb) = 1}
                }
            }
            # Creamos el objeto devolución de la función
            $Resultado = New-Object PsObject
            # Iniciamos la variable que contendrá el total de capacidad de los
            # módulos
            $Total = 0
            # Iniciamos el resumen
            $Resumen = ""
            # Recorremos los elementos del Hash de tamaños
            ForEach($Clave In $Recuento.Keys)
            {
                # Agregamos al total el producto de la clave (que es el tamaño
                # del tipo de módulo) por el valor (que es el número de módulos
                # del tamaño reflejado por la clave)
                $Total = $Total + ($Clave * $Recuento.($Clave))
                # Agregamos al resumen el tamaño de módulo y el número de
                # módulos y agregamos un punto y coma; la idea es que se
                # presente como una cadena de este estilo:
                # (1024*2)MB;(2048*2)MB
                $Resumen = "$Resumen($Clave*$($Recuento.($Clave)))MB;"
            }
            # Si se ha obtenido devolución, sobre el último punto y coma, por
            # ello lo quitamos
            If($Resumen.Length -gt 0)
            {
                $Resumen = $Resumen.SubString(0,$Resumen.Length-1)
            }
            # Agregamos a la devolución el nombre del equipo
            Add-Member -InputObject $Resultado `
                       -MemberType NoteProperty `
                       -Name Equipo `
                       -Value $ComputerName
            # Agregamos el resumen de módulos
            Add-Member -InputObject $Resultado `
                       -MemberType NoteProperty `
                       -Name Modulos `
                       -Value $Resumen
            # Agregamos el tamaño total en MB
            Add-Member -InputObject $Resultado `
                       -MemberType NoteProperty `
                       -Name TotalMB `
                       -Value $Total
            # Agregamos un nulo como error
            Add-Member -InputObject $Resultado `
                       -MemberType NoteProperty `
                       -Name Error `
                       -Value $null
            $Devolucion += $Resultado
        }
        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
                $Modulos = Invoke-Expression $Comando
                # Iniciamos el Hash del recuento, en el que las claves serán
                # los diferentes tamaños, en MB, de los módulos y el valor 
                # será el número de módulos de cada tamaño
                $Recuento = @{}
                # Recorremos los módulos
                ForEach($Modulo In $Modulos)
                {
                    # Si ya está como clave el tamaño del módulo actual,
                    # sumamos uno al valor de la clave
                    If($Recuento.Keys -contains ($Modulo.Capacity/1mb))
                    {
                        $Recuento.(($Modulo.Capacity/1mb))++
                    }
                    # Como no existe esa clave, la agregamos con valor uno
                    Else
                    {
                        $Recuento += @{($Modulo.Capacity/1mb) = 1}
                    }
                }
                # Creamos el objeto devolución de la función
                $Resultado = New-Object PsObject
                # Iniciamos la variable que contendrá el total de capacidad
                # de los módulos
                $Total = 0
                # Iniciamos el resumen
                $Resumen = ""
                # Recorremos los elementos del Hash de tamaños
                ForEach($Clave In $Recuento.Keys)
                {
                    # Agregamos al total el producto de la clave (que es el
                    # tamaño del tipo de módulo) por el valor (que es el
                    # número de módulos del tamaño reflejado por la clave)
                    $Total = $Total + ($Clave * $Recuento.($Clave))
                    # Agregamos al resumen el tamaño de módulo y el número
                    # de módulos y agregamos un punto y coma; la idea es que
                    # se presente como una cadena de este estilo:
                    # (1024*2)MB;(2048*2)MB. Esto reflejaría dós módulos de
                    # 1 GB y 2 de 2 GB.
                    $Resumen = "$Resumen($Clave*$($Recuento.($Clave)))MB;"
                }
                # Si se ha obtenido devolución, sobre el último punto y
                # coma, por ello lo quitamos
                If($Resumen.Length -gt 0)
                {
                    $Resumen = $Resumen.SubString(0,$Resumen.Length-1)
                }
                # Agregamos a la devolución el nombre del equipo
                Add-Member -InputObject $Resultado `
                           -MemberType NoteProperty `
                           -Name Equipo `
                           -Value $ComputerName
                # Agregamos el resumen de módulos
                Add-Member -InputObject $Resultado `
                           -MemberType NoteProperty `
                           -Name Modulos `
                           -Value $Resumen
                # Agregamos el tamaño total en MB
                Add-Member -InputObject $Resultado `
                           -MemberType NoteProperty `
                           -Name TotalMB `
                           -Value $Total
                # Agregamos un nulo como error
                Add-Member -InputObject $Resultado `
                           -MemberType NoteProperty `
                           -Name Error `
                           -Value $null
                $Devolucion += $Resultado
            }
            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 resumen de módulos
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Modulos `
                        -Value $null
                # Agregamos el tamaño total en MB
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name TotalMB `
                        -Value $null
                # Agregamos el error que se produjo
                Add-Member -InputObject $Resultado `
                        -MemberType NoteProperty `
                        -Name Error `
                        -Value $Error[0].Exception.Message
                $Devolucion += $Resultado
            }
        }
        # Restituimos la acción que estaba configurada para los errores que
        # no interrumpen
        $ErrorActionPreference = $AccionError
    }
    End
    {
        $Devolucion
    }
#.SYNOPSIS
#   Devuelve información sobre la memoria física de la máquina.
#.DESCRIPTION
#   Este Cmdlet permite obtener el información sobre la memoria física de la
#   máquina recibida como parámetro o de la máquina local si se omite este
#   parámetro. La información es obtenida procesando la clase WMI
#   Win32_PhysicalMemory del espacio de nombres root/CIMv2. La función permite
#   especificar las credenciales con las que se conectará a WMI, credenciales
#   que serán ignoradas en el caso del equipo local, pues no se puede acceder a
#   WMI con credenciales alternativas desde el equipo local.
#   
#   La devolución de la función consiste en objetos cuyas propiedades son:
#      - Equipo:  Nombre del equipo del que se obtiene información de la memoria
#                 física.
#      - Modulos: Recuento de tipos de módulos que hay en la máquina, por tamaño
#                 expresado en MegaBytes. El formato de este campo es
#                 (tamaño1*nºmódulos)MB;(tamaño2*nºmódulos)MB;....
#      - TotalMB: Tamaño total de la memoria, obtenido al sumar el tamaño de los
#                 los módulos que la integran.
#      - Error:   Si se produce un error al intentar obtener la información,
#                 esta propiedad contiene el error que se produjo. Si no se
#                 produjo error, el valor de esta propiedad es $null
#
#   La función permite canalización, admitiendo como entrada nombres o IPs de
#   equipos
#.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. Tiene también los
#   alias "Usuario","U","Credenciales" y "Cred".
#.NOTES
#   Desarrollado por Fernando Reyes López
#   Noviembre de 2010
#.LINK
#   http://freyes.svetlian.com -> Artículos de Fernando reyes
#.LINK
#   https://urpiano.wordpress.com -> El Blog de GualtrySoft
#.EXAMPLE
#     PS >Get-PhysicalMemory
#   Muestra por pantalla la memoria física del equipo local.
#.EXAMPLE
#     PS >Get-PhysicalMemory -ComputerName Mortadelo-PC
#   Muestra por pantalla la memoria física del equipo de nombre Mortadelo-PC.
#.EXAMPLE
#     PS >Get-PhysicalMemory -C Mortadelo-PC -Credential TIA\Bacterio
#   Muestra por pantalla la memoria física 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-PhysicalMemory -Cred TIA\Bacterio
#   Muestra por pantalla la memoria física 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-PhysicalMemory -Usuario $Usuario
#   Muestra por pantalla la memoria física 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-PhysicalMemory -U $Usr | Export-CSV c:\Mem.csv
#   Este ejemplo muestra una manera muy útil de usar esta función. Guarda, en el
#   fichero de valores separados por coma c:\Mem.csv, un listado con la memoria
#   física  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.
}

2 comentarios to “PowerShell: Cmdlet para obtener información sobre la memoria física de un equipo”

  1. […] y en otro sin ellas; un ejemplo de esta duplicidad de código lo podemos ver en el Cmdlet Get-PhysicalMemory que publiqué anteriormente. Este Cmdlet permite que en el script o función donde debamos […]

  2. […] Cmdlet p… on PowerShell: Cmdlet para invent…PowerShell: Cmdlet p… on PowerShell: Cmdlet para obtene…PowerShell: Cmdlet p… on PowerShell: Cmdlet para invoca…urpiano on Cómo Acceder A Un […]

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: