header1   header
header
header Register : : Login header
header
connector   connector
menuleft menuright
submenu   submenu
left
add-member help please.
Last Post 15 Mar 2010 03:12 PM by cameronove. 9 Replies.
Printer Friendly
  •  
  •  
  •  
  •  
  •  
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
ellis1884User is Offline
New Member
New Member
Posts:3
Avatar

--
10 Mar 2010 03:08 AM
    Hi all!,

    I am new to PS and I am trying to write a script that reads in a file (containing hostnames) to provide statistics of several items per machine (i.e hostname, IP, domain name, hdd space, memory, eventlogs etc)

    So far I can do this;

    gc C:\Scripts\serverlist.txt | % { $a = gwmi win32_computersystem -computername $_ } | ft name, domain

    However I want to pipe in more gwmis of the system apprently add-member is the correct logic,
    I have the following script, but I do not know why it is not working nor how to take the next step.

    gc C:\Scripts\serverlist.txt | % { $a = gwmi win32_computersystem -computername $_ | add-member NoteProperty hddsize -value (gwmi win32_logicaldisk -computername $_) } | ft name, domain, deviceid, freespace, size -auto



    update:

    I have manged to get the following to now "work"

    gc C:\Scripts\serverlist.txt | % { gwmi win32_computersystem -computername $_ | add-member NoteProperty freespace (gwmi win32_logicaldisk -computername $_).freespace -p | select -property name,freespace }

    it prints the hostname but for some reason the freespace is blank???

    any help greatly appreciated,

    chris
    PoSherLifeUser is Offline
    Basic Member
    Basic Member
    Posts:364
    Avatar

    --
    10 Mar 2010 08:31 AM
    try this one on for size:

    gc C:\Scripts\serverlist.txt | % {
    gwmi win32_logicaldisk -computername $_ | % {$space += $_.FreeSpace} ;`
    New-Object PSObject -Property @{
    Name = (gwmi win32_computersystem -computername $_).Name
    FreeSpace = $space
    }
    }

    The problem with your oneliner is that gwmi win32_logicaldisk returns multiple objects, not just one. You must have a % to add the totals of the .FreeSpace property.
    When at first you don't succeed Step-Into

    http://theposherlife.blogspot.com
    http://www.jandctravels.com

    PowerShell JediUser is Offline
    Basic Member
    Basic Member
    Posts:410
    Avatar

    --
    10 Mar 2010 12:30 PM

    Set-Alias inven Get-ComputerInventory -Scope global
    Function Get-ComputerInventory($ComputerName)
    {

    # ------ Computer Name --------
    if($ComputerName -eq '.'){$ComputerName = (get-WmiObject win32_computersystem -ComputerName $ComputerName).Name}
    $ComputerName = $ComputerName.ToUpper()
    # -----------------------------

    # --------- IP Address --------
    $ping = new-object System.Net.Networkinformation.Ping
    $PingResult = $ping.send($ComputerName);
    $IP = $PingResult.address.IPAddressToString
    # -----------------------------

    # --------- MAC Address -------
    $MAC = nbtstat -a $ComputerName | select-string "MAC Address"
    [string]$MAC = $MAC.ToString()
    [string]$MAC = $MAC.Substring(18)
    # -----------------------------

    # ------ Hard Drive -----------
    $HDrive = (get-wmiobject -class "Win32_DiskDrive"`
    -ComputerName $ComputerName).Size
    $HDrive = [math]::truncate($HDrive / 1GB)
    [string]$HDrive = $HDrive
    $HDrive = $HDrive + 'GB'
    # -----------------------------

    # ---------Free Space ---------
    $FreeHDSpace = (get-wmiobject –computername $ComputerName win32_logicaldisk -filter "drivetype=3").freespace
    [decimal]$FreeHDSpace = $FreeHDSpace
    $FreeHDSpace = [math]::truncate($FreeHDSpace / 1GB)
    [string]$FreeHDSpace = $FreeHDSpace
    $FreeHDSpace = $FreeHDSpace + 'GB
    # -----------------------------


    $Out = New-Object PSObject
    $out | add-member noteproperty ComputerName $ComputerName
    $out | add-member noteproperty IPAddress $IP
    $out | add-member noteproperty MACAddress $MAC
    $out | add-member noteproperty HardDrive $HDrive
    $out | add-member noteproperty FreeSpace $FreeHDSpace
    $out


    Function RemoveVars{

    $ErrorActionPreference="SilentlyContinue"
    Remove-Variable IP
    Remove-Variable MAC
    Remove-Variable HDrive
    Remove-Variable $FreeHDSpace
    }

    RemoveVars


    }# Get-ComputerInventory


    Usage:
    ----------------------------------------------

    $Computers = gc C:\Scripts\serverlist.txt

    $Computers | Get-ComputerInventory
    Or...
    $Computers | inven
    PoSH is a Automation Technology surfaced as a scripting language, not a "spice" ;-)
    PowerShell JediUser is Offline
    Basic Member
    Basic Member
    Posts:410
    Avatar

    --
    10 Mar 2010 12:40 PM
    Woops, I think Piping will only if you turn The function into an advanced function and specify "ValueFromPipeline=$true". The function would look like this...

    Function Global:Get-ComputerInventory
    {

    <#
    .Synopsis
    .Description
    .Parameter

    .Example
    PS> $Computers | Get-ComputerInventory

    .Link
    about_functions
    about_functions_advanced
    about_functions_advanced_methods
    about_functions_advanced_parameters

    .Notes
    NAME: Get-ComputerInventory
    AUTHOR:
    LASTEDIT:
    #Requires -Version 2.0
    #>

    [CmdletBinding()]
    param(
    [Parameter(Position=0, ValueFromPipeline=$true)]
    $ComputerName = "."
    )

    Process
    {

    # ------ Computer Name --------
    if($ComputerName -eq '.'){$ComputerName = (get-WmiObject win32_computersystem -ComputerName $ComputerName).Name}
    $ComputerName = $ComputerName.ToUpper()
    # -----------------------------

    # --------- IP Address --------
    $ping = new-object
    System.Net.Networkinformation.Ping
    $PingResult = $ping.send($ComputerName);
    $IP = $PingResult.address.IPAddressToString
    # -----------------------------

    # --------- MAC Address -------
    $MAC = nbtstat -a $ComputerName | select-string "MAC Address"
    [string]$MAC = $MAC.ToString()
    [string]$MAC = $MAC.Substring(18)
    # -----------------------------

    # ------ Hard Drive -----------
    $HDrive = (get-wmiobject -class "Win32_DiskDrive" -ComputerName $ComputerName).Size
    $HDrive = [math]::truncate($HDrive / 1GB)
    [string]$HDrive = $HDrive
    $HDrive = $HDrive + 'GB'
    # -----------------------------

    # ---------Free Space ---------
    $FreeHDSpace = (get-wmiobject –computername $ComputerName win32_logicaldisk -filter "drivetype=3").freespace
    [decimal]$FreeHDSpace = $FreeHDSpace
    $FreeHDSpace = [math]::truncate($FreeHDSpace / 1GB)
    [string]$FreeHDSpace = $FreeHDSpace
    $FreeHDSpace = $FreeHDSpace + 'GB'
    # -----------------------------


    $Out = New-Object PSObject
    $out | add-member noteproperty ComputerName $ComputerName
    $out | add-member noteproperty IPAddress $IP
    $out | add-member noteproperty MACAddress $MAC
    $out | add-member noteproperty HardDrive $HDrive
    $out | add-member noteproperty FreeSpace $FreeHDSpace
    $out


    Function RemoveVars{

    $ErrorActionPreference="SilentlyContinue"
    Remove-Variable IP
    Remove-Variable MAC
    Remove-Variable HDrive
    Remove-Variable $FreeHDSpace
    }

    RemoveVars

    }# Process


    }# Get-ComputerInventory
    PoSH is a Automation Technology surfaced as a scripting language, not a "spice" ;-)
    ellis1884User is Offline
    New Member
    New Member
    Posts:3
    Avatar

    --
    11 Mar 2010 01:07 AM
    Ok well thanks for the advice and scripts guys!!, but being a newbie I want to try (no offend) and go with my code (i know it make look sloppy to you guys).

    gc C:\Scripts\serverlist.txt | % { $a = new-object PSObject
    gwmi win32_computersystem -computername $_ | `
    add-member NoteProperty IPaddress (gwmi win32_networkadapterconfiguration -computername $_ | ?{$_.defaultipgateway -like "*.251"} ).IPAddress -p | `
    add-member NoteProperty HHD-Freespace (gwmi win32_logicaldisk -computername $_ -filter "deviceID = 'C:' " ).FreeSpace -p | `
    add-member NoteProperty HDD-Size (gwmi win32_logicaldisk -computername $_ -filter "deviceID = 'C:' " ).Size -p | `
    ##add-member NoteProperty HDD-Letter (gwmi win32_logicaldisk -computername $_ ).DeviceID -p | `
    add-member NoteProperty TotRAM (gwmi win32_computersystem -computername $_).TotalPhysicalMemory -p | `
    ##add-member NoteProperty AvaRAM (gwmi win32_perfformatteddata_perfos_memory -computername $_ ).availablembytes -p | `
    ##add-member NoteProperty AppLogs (get-eventlog application -newest 100 -computername $_ ).application | `
    select -property Name, Domain, IPAddress, HDD-Size, HHD-Freespace, HDD-Letter, TotRAM, AvaRAM, AppLogs }



    So far it will print the name/domain/IP/hddsize and freespace of that size- however I can only use this is i select a drive using -filter. The problem is the servers have multiple drives and obliously not all the same (some have many say C-->T) and some just have C;D;E
    clearly I could cheat and copy and past the same line and filter for each drive, but when you do not know what each server may have this idea is not good.

    Similarly I could not get the IP address to print (not for the life of me, UNLESS... I asked it to look at the default gateway object and if it returned a value of .251 as the last octet to pass the IP address (all our severs using .251 to get out).

    any more ideas once again appreciated, like I said I am new to scripting/powershell so its all good experience! :)
    PoSherLifeUser is Offline
    Basic Member
    Basic Member
    Posts:364
    Avatar

    --
    11 Mar 2010 07:05 AM
    1.) Many of the WMI classes you are calling have multiple objects and you must parse through each of them to get the information you need, as I stated in my previous post.

    2.) Each time you pass an object through the pipe ,"|", $_ is changed.  So, you should be using ";" instead when you want the same object passed through.

    3.) You are calling the same WMI object multiple times.  This will cause your script to run unnecessarily slow.  It is always best to create an object any time the data or object is used more than once.

    4.) Add-Member NoteProperty works ok, but the script can be much cleaner by creating a new PSObject and just setting the values as they are created.  It looks like you may have been attempting this, but just setting "$a = new-object PSObjec" doesn't do the job.

    With that behind us here is your script cleaned up.

     gc C:\Scripts\serverlist.txt | % {
        $disk = gwmi win32_logicaldisk -computername $_ -Filter "DriveType=3" ;
        $System = gwmi win32_computersystem -computername $_ ;
        New-Object PSObject -Property @{
            Name = $System.Name
            Domain = $System.Domain
            IPaddress = (gwmi win32_networkadapterconfiguration -computername $_ -Filter "IPEnabled='True'" | % {$_.IPAddress})
            HHDFreespace = ($disk | % {$_.FreeSpace})
            HDDSize = ($disk | % {$_.Size})
            HDDLetters = ($disk | % {$_.DeviceID})
            TotRAM = $System.TotalPhysicalMemory
            AvaRAM = (gwmi win32_perfformatteddata_perfos_memory -computername $_ ).availablembytes
            AppLogs = (get-eventlog application -newest 100 -computername $_ ).application
        } }

    ##EDIT##
    HDDFreespace, HDDLetters, and HDDSize I left as an array of objects.  If you want the Size and Freespace added together that should be fairly easy to do.
    When at first you don't succeed Step-Into

    http://theposherlife.blogspot.com
    http://www.jandctravels.com

    PowerShell JediUser is Offline
    Basic Member
    Basic Member
    Posts:410
    Avatar

    --
    11 Mar 2010 09:48 AM
    As I remember it, when I was learning powershell there were a several mental revelations/hurdles.

    The two I recommend spending time on first is...

    1.) Learn to output your data in a custom object. Powershell really wants your output to be an object. You will see once you figure this out you can just pipe you output to commands like Export-Clixml, Export-Csv, Out-GridView, etc...

    2.) They say code reuse is the holy grail of programing. Learning to build Functions or more exactly Advanced Functions will allow you to increase you Powershell output 10 fold. In my opinion EVERYTHING should be built into a function. Then you can just use oneliners. Heres a one of my onliners piping my custom Advanced Functions.

    Get-ComputerName -OS Server2003 -FromActiveDirctory | Get-Pingable | Get-ComputerInventory | Out-GridView

    Done!
    PoSH is a Automation Technology surfaced as a scripting language, not a "spice" ;-)
    PowerShell JediUser is Offline
    Basic Member
    Basic Member
    Posts:410
    Avatar

    --
    12 Mar 2010 01:15 PM
    Oh yah, I forgot to mention you put all of your custom functions in your profile.ps1 file.
    PoSH is a Automation Technology surfaced as a scripting language, not a "spice" ;-)
    cameronoveUser is Offline
    Basic Member
    Basic Member
    Posts:332
    Avatar

    --
    15 Mar 2010 02:45 PM
    I agree!!!

    I put almost everything into functions.

    And objects are super easy to create.  I.e. your $out object:

    The Formal way:

    $Out = New-Object PSObject
    $out | add-member noteproperty ComputerName $ComputerName
    $out | add-member noteproperty IPAddress $IP
    $out | add-member noteproperty MACAddress $MAC
    $out | add-member noteproperty HardDrive $HDrive
    $out | add-member noteproperty FreeSpace $FreeHDSpace
    $out

    The easy way:

    $Out = "" | Select ComputerName,IPAddress,MACAddress,HardDrive,FreeSpace

    Oh!  PowerShell is SOOOO cool!

    Check the object:

    $Out | gm

    Looks the same as the formal object.

    I didn't discover it, I saw it somewhere on this forum, but I use it all the time now.

    cameronoveUser is Offline
    Basic Member
    Basic Member
    Posts:332
    Avatar

    --
    15 Mar 2010 03:12 PM
    One last thought on objects.  If you are hesitant to use them because of all of the typing with add-member the shorten form should encourage you to use them.  The short form is really great for null objects.

    $Out = "" | Select name,age

    Creates an object with all properties but no data.

    If you want to use the short form to add data to the object try this:

    $Out = "" | select @{n='Name';e={"John Smith"}},@{n='Age';e={"40"}}

    That is really rough to type for me and now not really very short but you can see what is possible.

    I'd prefer to do this:
    $Out = New-Object PSObject -Property @{'Name'='John Smith';'Age'=40}

    You can use a hash table create the noteproperty and assign a value.

    Pretty cool huh?

    So using objects is very beneficial and really doesn't take as much energy to create as they may seem.

    You are not authorized to post a reply.


    Active Forums 4.3
    right
    footer   footer
    footer Sponsored by Quest Software • SAPIEN Technologies • Compellent • Microsoft Windows Server 2008 R2 footer
    footer   footer