Skip to main content

Using Text Based Logs with Windows PowerShell (7 of 8)


Day 7: Creating an object template
 
Yesterday we extracted a dynamic list of property names from our log file.  Today we will complete step 3: Create an object that contains all possible property names.
The object that we are creating is going to contain all of our properties with values set to $Null.  That way we will have a template without any restrictions on the data type that the properties will hold.
    Function New-EmptyObject
    {
    Param ($PropList)
    # Creates an empty object to be used for each instance of the final
    # object. This ensures a consistent set of members for the object.
       
        $Obj = New-Object -TypeName psobject
      
        # Change the type name.
        $Obj.pstypenames.insert(0,'Custom.LogObject')
      
        ForEach ($P in $Proplist.Prop)
        {
            $Obj | Add-Member -NotePropertyName "$($P)" `
                              -NotePropertyValue $Null
        } # End: ForEach ($P in $Proplist.Prop)
     
        # Return the object to the calling statement.
        Write-Output $Obj
    } # End Function New-EmptyObject
 
Here we are feeding the function New-EmptyObject our $Proplist object.  The function creates an empty object called $Obj and then changes the object type from System.Management.Automation.PSCustomObject  to Custom.LogObject.  Custome.LogObject is our own, unique object type. Next each property from the $PropList is added as a property of the object with a value set to $Null.  Once this is completed, the object is returned and stored as $EmptyObject.
 
Here is the code:
 
Function Import-MyLog2
{
    # -----------------------------------------------------------------------
    Function Get-Log
    {
    # Reads the log file into memory.  Will display an error if the
    # file cannot be found.
 
        Try
        {
            Get-Content -path "\\Server1\Log\Data2.txt" `
                        -ErrorAction Stop |
            Write-Output
        }
        Catch
        {
            Write-Error "The data file is not present"
            BREAK
        }
    } # End: Function Get-Log
    # -----------------------------------------------------------------------
    Function Get-RecordIndex
    {
    Param ($Log)
    # Determines the index number of where each record starts and ends.
    # Returns an object with the start and end index number of
    # each record.
 
        # Array to hold all of the objects.
        $Object = @()
       
        # Find the start of each record.
        For($X=0;$X -lt $Log.Count; $X++)
        {
            If($Log[$X] -like "Server Blade #* Information:")
            {
 
                $Obj = New-Object -TypeName PSObject
                $Obj | Add-Member -NotePropertyName "Start" `
                                  -NotePropertyValue $X
                $Obj | Add-Member -NotePropertyName "End" `
                                  -NotePropertyValue $Null
                $Object += $Obj
            }
        } # End: For($X=0;$X -lt $Log.Count; $X++)
 
        # Derive the end of each record.
        For ($X = 0; $X -lt $Object.Count - 1; $X++)
        {
            $Object[$X].End = $Object[$X+1].Start -1
        } # End: For ($X = 0; $X -lt $Object.Count; $X++)
 
        # Add the final End value as the end of the log file.
        $Object[$Object.count-1].End = $Log.count
 
        # Return the object to the calling statement.
        Write-Output $Object
       
    } # End: Function Get-RecordIndex
    # -----------------------------------------------------------------------
    Function Format-PropertyName
    {
    Param ($Name)
    # Used to get the proper name format for the list of properties and also
    # While creating the actual data for the final objects.
 
        $Value = $Name.Trim()
        $Pos = $Value.IndexOf(":")
        Write-Output $Value.Substring(0,$Pos).Replace(" ","")
               
    } # End: Function Format-PropertyName
    # -----------------------------------------------------------------------
    Function Get-PropertyList
    {
    Param($RecordIndex, $Log)
    # To help build a more flexible object, we need to identify possible
    # property names.  This function will cycle through each record and use
    # a rule to identify the name of a property.  Our rule is any string
    # other than the string that starts the record that starts with blank
    # characters, has text, and the it will end at the first ":".  All spaces
    # in the property names will also be removed.
       
        # Array to hold all of the objects.
        $Object = @()
 
        ForEach ($R in $RecordIndex)
        {
            For ($X=$R.Start+1;$X -lt $R.End;$X++)
            {
 
                # Examine only lines from the record that are not blank.
                If (($Log[$X].length -gt 0) -and ($Log[$X] -like "*:*"))
                {
                    $Obj = New-Object -TypeName PSObject
                    $Obj | Add-Member -MemberType NoteProperty `
                                      -Name "Prop" `
                                      -Value (Format-PropertyName -Name $Log[$X])
                   $Object += $Obj                
                }
            } # End: For ($X=$R.Start;$X -lt $R.End;$X++)
        } # End: ForEach ($R in $RecordIndex)
 
        # Add the "Slot" property to record the slot number.
        $Obj = New-Object -TypeName PSObject
        $Obj | Add-Member -MemberType NoteProperty `
                            -Name "Prop" `
                            -Value "Slot"
        $Object += $Obj
        # Filter the list of protential properties to make sure that they
        # are all unique.
        $Object = $Object | Select-Object -Property Prop -Unique
 
        # Return the object to the calling statement.
        Write-Output $Object
 
    } # End: Function Get-PropertyList
    # -----------------------------------------------------------------------
    Function Get-Record
    {
    Param ($Log,$RecordIndex)
       
        # Array to hold all of the objects.
        $Object = @()
 
        ForEach($R in $RecordIndex)
        {
            $Obj = New-Object -TypeName PSObject
            $String = $Null
            For($X=$R.Start;$X -lt $R.End; $X++)
            {
                $String += $Log[$X]
            }
            $Object += $String  
        }
       
        # Return the object to the calling statement.
        Write-Output $Object
 
    } # End: Function Get-Record
    # -----------------------------------------------------------------------
    Function New-EmptyObject
    {
    Param ($PropList)
    # Creates an empty object to be used for each instance of the final
    # object. This ensures a consistent set of members for the object.
       
        $Obj = New-Object -TypeName psobject
      
        # Change the type name.
        $Obj.pstypenames.insert(0,'Custom.LogObject')
      
        ForEach ($P in $Proplist.Prop)
        {
            $Obj | Add-Member -NotePropertyName "$($P)" `
                              -NotePropertyValue $Null
        } # End: ForEach ($P in $Proplist.Prop)
     
        # Return the object to the calling statement.
        Write-Output $Obj
    } # End Function New-EmptyObject
    # -----------------------------------------------------------------------
    # Load the log into memory
    $Log = Get-Log
 
    # Extract the records
    $RecordIndex = Get-RecordIndex -Log $Log
 
    # Extract the propertyl list.
    $PropList = Get-PropertyList -RecordIndex $RecordIndex -Log $Log
 
    # Create an empty object to use as our template using our $PropList.
    $EmptyObj = New-EmptyObject -PropList $PropList
    $EmptyObj # This line will be removed.  It shows our current progress.
 
} #End: Function Import-MyLog1
 
Here is our output:
 
ServerBladeType                  :
Type                             :
Manufacturer                     :
ProductName                      :
PartNumber                       :
SystemBoardSparePartNumber       :
SerialNumber                     :
UUID                             :
ServerName                       :
AssetTag                         :
ROMVersion                       :
CPU1                             :
CPU2                             :
Memory                           :
NIC1                             :
NIC2                             :
NIC3                             :
NIC4                             :
iSCSI1                           :
iSCSI2                           :
Mezzanine2                       :
Port1                            :
Port2                            :
ManagementProcessorInformation   :
Name                             :
FirmwareVersion                  :
IPAddress                        :
MACAddress                       :
PowerManagementControllerVersion :
FLBAdapter1                      :
EthernetFlexNIC(NIC1)LOM1        :
EthernetFlexNIC(NIC3)LOM1        :
EthernetFlexNIC(NIC5)LOM1        :
EthernetFlexNIC(NIC7)LOM1        :
EthernetFlexNIC(NIC2)LOM1        :
EthernetFlexNIC(NIC4)LOM1        :
EthernetFlexNIC(NIC6)LOM1        :
EthernetFlexNIC(NIC8)LOM1        :
Slot                             :  
 
 
Tomorrow we will finish up and tie everything together.

Comments

Popular posts from this blog

Adding a Comment to a GPO with PowerShell

As I'm writing this article, I'm also writing a customization for a PowerShell course I'm teaching next week in Phoenix.  This customization deals with Group Policy and PowerShell.  For those of you who attend my classes may already know this, but I sit their and try to ask the questions to myself that others may ask as I present the material.  I finished up my customization a few hours ago and then I realized that I did not add in how to put a comment on a GPO.  This is a feature that many Group Policy Administrators may not be aware of. This past summer I attended a presentation at TechEd on Group Policy.  One organization in the crowd had over 5,000 Group Policies.  In an environment like that, the comment section can be priceless.  I always like to write in the comment section why I created the policy so I know its purpose next week after I've completed 50 other tasks and can't remember what I did 5 minutes ago. In the Group Policy module for PowerShell V3, th

Return duplicate values from a collection with PowerShell

If you have a collection of objects and you want to remove any duplicate items, it is fairly simple. # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   # Remove the duplicate values. $Set1 | Select-Object -Unique 1 2 3 4 5 6 7 What if you want only the duplicate values and nothing else? # Create a collection with duplicate values $Set1 = 1 , 1 , 2 , 2 , 3 , 4 , 5 , 6 , 7 , 1 , 2   #Create a second collection with duplicate values removed. $Set2 = $Set1 | Select-Object -Unique   # Return only the duplicate values. ( Compare-Object -ReferenceObject $Set2 -DifferenceObject $Set1 ) . InputObject | Select-Object – Unique 1 2 This works with objects as well as numbers.  The first command creates a collection with 2 duplicates of both 1 and 2.   The second command creates another collection with the duplicates filtered out.  The Compare-Object cmdlet will first find items that are diffe

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.