PwSh.Fw.Computer.psm1


<#
.SYNOPSIS
Statically declare a new computer
 
.DESCRIPTION
Long description
 
.PARAMETER name
Parameter description
 
.PARAMETER Localhost
Parameter description
 
.EXAMPLE
An example
 
.NOTES
General notes
#>


function New-ComputerObject {
    [CmdletBinding()]Param (
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        $computer = [PSCustomObject]@{
            name = ""
            domain = ""
            fqdn = ""
            manufacturer = ""
            eth = @()
            interfaces = @()
            model = ""
            serial = ""
            firmware = ""
            version = ""
            arch = ""
            disks = @()
            partitions = @()
            ethByName = @{}
            ethByIndex = @()
        }
        return $computer
    }

    End {
        Write-LeaveFunction
    }
}

<#
.SYNOPSIS
Create a new [computer] object from an existing computer
 
.DESCRIPTION
Long description
 
.PARAMETER name
Parameter description
 
.PARAMETER Localhost
Parameter description
 
.EXAMPLE
An example
 
.NOTES
General notes
#>


function Get-Computer {
    [CmdletBinding()]Param (
    )
    Begin {
        Write-EnterFunction
        # we first need to known what OS we are running to load appropriate dictionaries
        $os = Get-OperatingSystem -Online
        $os | Load-Dictionaries -Prefix "Computer" -Path "$PSScriptRoot/Dictionaries"
        # $computer = @{}
        $computer = New-ComputerObject
    }

    Process {
        $computer.name = Get-ComputerName
        $computer.domain = Get-ComputerDomain
        $computer.fqdn = $computer.name + '.' + $computer.domain
        $computer.manufacturer = Get-ComputerManufacturer
        $computer.eth = Get-ComputerNetAdapter
        # $computer.interfaces = Get-ComputerNetAdapter
        $computer.model = Get-ComputerModel
        $computer.serial = Get-ComputerSerialNumber
        $computer.firmware = Get-ComputerFirmwareType
        $computer.version = Get-ComputerVersion
        $computer.arch = Get-ComputerArch
        $computer.disks = Get-ComputerDisk -All
        $computer.partitions = Get-ComputerDiskPartition -All
        # $computer.ethByName = @{}

        ForEach ($e in (Get-ComputerEthernet -ListAvailable 'Name')) {
            $computer.ethByName[$e] = @{}
            try {
                $computer.ethByName[$e]["IPv4"] = Get-EthernetObject -AdapterName $e -Family IPv4
            } catch {
                ewarn "On $e (IPv4):"
                ewarn $_
            }
            try {
                $computer.ethByName[$e]["IPv6"] = Get-EthernetObject -AdapterName $e -Family IPv6
            } catch {
                ewarn "On $e (IPv6):"
                ewarn $_
            }
            if ($computer.ethByName[$e]["IPv4"].default -eq $true) {
                $computer.ethByName["default"] = $computer.ethByName[$e]
            }
            if ($computer.ethByName[$e]) {
                $computer.ethByName[$e].ifindex = $computer.ethByIndex.Count
                $computer.ethByIndex += @($computer.ethByName[$e])
            }
        }
        # ForEach ($e in (

        return $computer
        # return [PwShFwComputer]::new($computer)
    }

    End {
        Write-LeaveFunction
    }
}

<#
.SYNOPSIS
Create a new [computer] object from an existing computer
 
.DESCRIPTION
Long description
 
.PARAMETER name
Parameter description
 
.PARAMETER Localhost
Parameter description
 
.EXAMPLE
An example
 
.NOTES
General notes
#>


function Get-ComputerClass {
    [CmdletBinding()]Param (
        [Parameter(ValueFromPipeLine = $true)][string]$name
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        . "$Global:PWSHFW_PATH/classes/disk/diskObject.ps1"
        . "$Global:PWSHFW_PATH/classes/ethernet/ethernetObject.ps1"
        . "$Global:PWSHFW_PATH/classes/computer/computerObject.ps1"

        $obj = [computer]::new($Localhost)
        if ($name) {
            $obj.name = $name
        }
        return $obj
    }

    End {
        # eleave($MyInvocation.MyCommand)
    }
}

function Get-EthernetObject {
    [CmdletBinding()]Param (
        [Parameter(ValueFromPipeLine = $true)]
        [string]$AdapterName,
        [ValidateSet('IPv4', 'IPv6')]
        [string]$Family = 'IPv4'
    )
    Begin {
        Write-EnterFunction
        # $eth = New-Object -TypeName PSObject -Property @{
        # # name of network interface
        # name = "lo"
        # # inner index in array eth
        # index = 0
        # # index of interface in operating system
        # ifIndex = 0
        # manufacturer = ""
        # model = ""
        # description = ""
        # mac = "aa:bb:cc:dd:ee:ff"
        # # link status of ethernet interface
        # # $false is link down
        # # $true is link up
        # link = $false
        # speed = 0
        # dhcpIpAddress = $null
        # ipaddress = [ipaddress]"0.0.0.0"
        # netmask = [ipaddress]"255.255.255.255"
        # broadcast = [ipaddress]"255.255.255.255"
        # gateway = [ipaddress]"0.0.0.0"
        # # the score for this interface to be the default
        # scoreDefault = 0
        # default = $false
        # }
        $eth = @{}
    }

    Process {
        $eth.name = $AdapterName
        $eth.ifindex = Get-EthIndex -AdapterName $AdapterName
        $eth.mac = Get-EthMacAddress -AdapterName $AdapterName
        $eth.link = Get-EthLinkStatus -AdapterName $AdapterName
        if ($eth.link -eq $true) {
            $eth.ipaddress = Get-EthIPAddress -AdapterName $AdapterName -Family:$Family
            $eth.netmask = Get-EthNetmask -AdapterName $AdapterName -Family:$Family
            $eth.broadcast = Get-EthBroadcast -AdapterName $AdapterName -Family:$Family
            $eth.gateway = Get-EthGateway -AdapterName $AdapterName -Family:$Family
        }

        # return $eth
        return [PwShFwEthernet]::new($eth)
    }

    End {
        Write-LeaveFunction
    }
}

<#
.SYNOPSIS
Convert a command output to a hashtable
 
.DESCRIPTION
Long description
 
.PARAMETER Command
command to invoke
 
.PARAMETER sep
separator char of key/value pair
 
.PARAMETER SkipFirstLines
skip the first lines
 
.EXAMPLE
dmidecode | New-HashtableFromCommand
 
.NOTES
General notes
#>

function New-HashtableFromCommand {
    [CmdletBinding()]Param (
        [string]$Command = "",
        [char]$sep = ":",
        [int]$SkipFirstLines = 0
    )
    Begin {
        eenter($MyInvocation.MyCommand)
    }

    Process {
        $hash = New-Object System.Collections.Hashtable
        Invoke-Expression -Command $command | Select-Object -Skip $SkipFirstLines | Foreach {
            # skip empty lines
            # if ($_.trim() -eq "") { continue }
            # # skip headers (lines that do not contains $sep char)
            # if ($_.IndexOf($sep) -eq -1) { continue }
            $key = $_.Split($sep)[0]
            # echo "key = $key"
            # if ($key -eq $null) { echo "key is null" }
            # if ($key -eq '') { echo "key is empty" }

            # handle null value
            $value = $_.Split($sep)[1]
            if ($value -eq $null) {
                $value = ""
            } else {
                $value = $value.Trim('" ')
            }

            # add key/value to hash
            # handle null keys and empty keys
            if ($key -ne $null -and $key -ne '' ) {
                # echo "value = $value"
                $hash.Add($key.Trim().ToLower(), $value)
                # $prevKey = $key
            # } else {
            # # maybe we are facing a multiline output,
            # # try to handle it, modifying previous key's value
            # $prevValue = $hash[$prevKey]
            # $newValue = $($prevValue + " | " + $value)
            # $hash[$prevKey] = $newValue
            }
        }

        return $hash
    }

    End {
        eleave($MyInvocation.MyCommand)
    }
}

function Load-ComputerDictionaries {
    [CmdletBinding()]
    [OutputType([void])]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="Load-Dictionaries is a more intuitive verb for this function.")]
    Param (
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Mainstream,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Platform,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Kernel,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Family,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Distrib,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$ReleaseId,
        [string]$Path = "$PSScriptRoot/Dictionaries",
        # Prefix to prepend to search for dictionaries
        [string]$Prefix,
        [Parameter()][switch]$Force
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        PwSh.Fw.OS\Load-Dictionaries @PSBoundParameters -Path "$PSScriptRoot/Dictionaries" -Prefix "Computer"
    }

    End {
        Write-LeaveFunction
    }
}

function Load-ComputerLibraries {
    [CmdletBinding()]
    [OutputType([void])]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="Load-Dictionaries is a more intuitive verb for this function.")]
    Param (
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Mainstream,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Platform,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Kernel,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Family,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$Distrib,
        [AllowNull()][AllowEmptyString()][Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)][string]$ReleaseId,
        [string]$Path = "$PSScriptRoot/Libraries",
        # Prefix to prepend to search for Libraries
        [string]$Prefix,
        [Parameter()][switch]$Force
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        PwSh.Fw.OS\Load-Dictionaries @PSBoundParameters -Path "$PSScriptRoot/Libraries" -Prefix "Computer"
    }

    End {
        Write-LeaveFunction
    }
}