Classes/osobject.class.ps1


class osObject {

    ####################
    ## ATTRIBUTES ##
    ####################

    # Platform on which the OS is running
    [ValidateSet('unknown', 'unix', 'windows', IgnoreCase = $true)]
    [string]$platform = "unknown"

    # kernel used by OS
    [ValidateSet('unknown', 'darwin', 'linux', 'unix', 'win32', 'winnt', 'macos', IgnoreCase = $true)]
    [string]$kernel = "unknown"

    # kernel version
    [string]$kernelVersion = $null

    # user-friendly name for platform
    # this attribute is the name of the mainstream OS
    # e.g. Windows / MacOS / Linux at the moment
    [ValidateSet('unknown', 'Linux', 'MacOS', 'Windows', IgnoreCase = $true)]
    [string]$mainstream = "unknown"

    # [ValidateSet('unknown', 'debian', 'slackware', 'redhat', 'arch', 'android', 'macos', 'windowsXP', 'windowsVista', 'Windows7', 'windows10', IgnoreCase = $true)]
    [string]$family = "unknown"

    # distrib
    # distribution name for Unix/Linux family
    # 'windowsFamily', 'WindowsProfessional', 'windowsEnterprise', 'WindowsServer', 'WindowsPE' for windows family
    # can be Debian Ubuntu Mint *BSD etc...
    [string]$distrib = "unknown"

    # edition
    # Edition of operating system if available
    # For Windows, can be "Home" (or "Family"), "Professionnal", "Enterprise"
    # For Ubuntu, can be "Kubuntu", "Lubuntu", "Xubuntu"
    [string]$edition = ""

    # installType
    # installation type of OS. Use to make a difference between Desktop and Server
    [ValidateSet($null, 'unknown', 'Desktop','Server','PreOS', IgnoreCase = $true)]
    [string]$installType = "unknown"

    # version number
    # ex. "16.04.3" for Ubuntu 16.04
    # ex. "6.3" for Windows 8
    # ex. "10" for Windows 10
    [string]$version = ""

    # release number
    # ex. "16.04" for Ubuntu 16.04
    # ex. "1607" for Windows 10 Anniversary Update
    [string]$releaseId = $null

    # productName
    # long and offcial product name from manufacturer
    # ex. "Ubuntu 16.04.5 LTS"
    # ex. "Windows 10 Enterprise 2016 LTSB"
    [string]$productName = ""

    # codeName
    # short and official code name from manufacturer
    # ex. "xenial"
    # ex. "Redstone 1" for Anniversary Update
    # Windows codeNames can be found
    # . @url https://en.wikipedia.org/wiki/List_of_Microsoft_codenames
    # . @url https://en.wikipedia.org/wiki/Windows_10#Updates_and_support
    [string]$codeName = ""

    # longCodeName
    # long and official code name from manufacturer
    # ex. "Xenial Xerus"
    # ex. "Anniversary Update"
    [string]$longCodeName = ""

    # arch
    # architecture of OS installed (not CPU one)
    [ValidateSet('unknown', 'x86', 'x64', 'arm32', 'arm64', IgnoreCase = $true)]
    [string]$arch

    # online
    # true if OS is currently running
    [switch]$Online = $true

    # root
    # root folder of disk containing OS
    [string]$Root = "/"

    # systemRoot
    # root folder of OS on disk (from the OS point of view)
    # for online OS, $Root and $SystemRoot are the same
    # for offline OS, $Root is the location of OS from the running OS, $SystemRoot is the location from the offline OS
    # '/' on Unix/Linux systems
    # 'c:\Windows' on Windows systems (can be C:\winnt on older systems)
    [string]$SystemRoot = "/"

    # well known files
    $files = @{}

    # well known special folders
    $folders = @{}

    ####################
    ## CONSTRUCTORS ##
    ####################
    constructor () {
        # Write-PwShFwOSDevel "Loading [" + $this.GetType() + "]"
    }

    osObject () {
        $this.constructor()
    }

    osObject ([string]$Root) {
        $this.constructor()
        $this.Root = $Root
    }

    # # Methods
    # [Boolean] Fill ([int]$volume)
    # { return $false }

    # [Boolean] Drink ([int]$amount)
    # { return $false }

    #############
    ## METHODS ##
    #############

    [void] loadDictionaries () {
        $this.loadDictionaries($false)
    }

    [void] loadDictionaries ([bool]$Force) {
        if ($this.online) {
            # with fullyQualifiedName we are able to load Modules from devel folder
            # and I forgot that Dictionaries folder is not included in PsModulePath at install time
            $dict = "Dict.OS"
            Load-Module -Policy Optional -FullyQualifiedName "$PSScriptRoot/../Dictionaries/$dict/$dict.psd1" -Force:$Force
            $dict = (get-culture).TextInfo.ToTitleCase("Dict." + $this.platform)
            Load-Module -Policy Optional -FullyQualifiedName "$PSScriptRoot/../Dictionaries/$dict/$dict.psd1" -Force:$Force
            $dict = (get-culture).TextInfo.ToTitleCase("Dict." + $this.platform + "." + $this.kernel)
            Load-Module -Policy Optional -FullyQualifiedName "$PSScriptRoot/../Dictionaries/$dict/$dict.psd1" -Force:$Force
            $dict = (get-culture).TextInfo.ToTitleCase("Dict." + $this.platform + "." + $this.kernel + "." + $this.family)
            Load-Module -Policy Optional -FullyQualifiedName "$PSScriptRoot/../Dictionaries/$dict/$dict.psd1" -Force:$Force
            $dict = (get-culture).TextInfo.ToTitleCase("Dict." + $this.platform + "." + $this.kernel + "." + $this.family + "." + $this.distrib)
            Load-Module -Policy Optional -FullyQualifiedName "$PSScriptRoot/../Dictionaries/$dict/$dict.psd1" -Force:$Force
            $dict = (get-culture).TextInfo.ToTitleCase("Dict." + $this.platform + "." + $this.kernel + "." + $this.family + "." + $this.distrib + "." + $this.releaseId)
            Load-Module -Policy Optional -FullyQualifiedName "$PSScriptRoot/../Dictionaries/$dict/$dict.psd1" -Force:$Force
        } else {
            eerror("Dictionnaries can be loaded only for currently running OS.")
            eerror("Try to call this function from the online OS object.")
        }
    }

    ## getName
    ## @return (string) a short and non official name of OS mainly forged by Distrib + releaseId
    ## @example "Ubuntu 16.04"
    ## @example "Windows 7"
    ## @example "Windows 10"
    [string] getName () {
        if ($this.releaseId) {
            return $this.distrib + " " + $this.releaseId
        } else {
            return $this.distrib
        }
    }

    ## getShortName
    ## @brief build a short name with no space
    ## @return (string) a short and non official name of OS mainly forged by Distrib + releaseId + arch
    ## @example "Ubuntu1604x86"
    ## @example "Raspbian94arm32"
    ## @example "Windows7x64"
    ## @example "Windows101607x64"
    [string] getShortName () {
        return $this.distrib + ($this.releaseId -replace '.', '') + $this.arch.ToLower()
    }

    ####################
    ## STATIC METHODS ##
    ####################
    static [string]identifyOsPlatform ([string]$Root) {
        $obj = "unknown"
        if (dirExist($Root + "/etc")) {
            $obj = "unix"
        } elseif (dirExist($Root + "/Windows")) {
            $obj = "windows"
        } else {
            ewarn("Neither $Root/etc or $Root/Windows found -> unknown platform. Is there an OS on this root ('" + $Root + '") ?')
        }
        return $obj
    }

    static [string]identifyOsKernel ([string]$Root) {
        return "undefined"
    }

    static [string]identifyOsFamily ([string]$Root) {
        return "undefined"
    }

    static [string]identifyOsDistrib ([string]$Root) {
        return "undefined"
    }

    static [string]identifyOsReleaseid ([string]$Root) {
        return "undefined"
    }

    # static [string]identifyOsFamily ([string]$Root, [string]$platform) {
    # $obj = "unknown"
    # switch ($platform.ToLower()) {
    # 'unix' {
    # if (fileExist($Root + "/etc/os-release")) {
    # $obj = "linux"
    # } else {
    # ewarn("No /etc/os-release found -> unknown unix family. Is there an OS on this root ('" + $Root + '") ?')
    # }
    # }
    # 'windows' {
    # if (dirExist($Root + "/Windows/System32")) {
    # $obj = "windows"
    # } else {
    # ewarn("No /Windows/System32 found -> unknown windows family. Is there an OS on this root ('" + $Root + '") ?')
    # }
    # }
    # default {
    # $obj = 'unknown'
    # }
    # }
    # return $obj
    # }
}