Dictionaries/Dict.OS/Dict.OS.psm1

# List here the name of the package to add to system
# this variable is used in Install-Dependencies() and Remove-Dependencies()
$Script:PackageList = ""

# common message to display when calling not-yet-overriden function
$Script:WarningMessage = @(
                            "The function {0}() is not yet overriden for the currently running OS.",
                            "Please add an issue on the project's gitlab or submit a pull-request."
                        )

$Script:NS = (get-item $PSCommandPath).basename

<#
 
  ####### ######
 ## ## ## ##
 ## ## ##
 ## ## ######
 ## ## ##
 ## ## ## ##
  ####### ######
 
#>

<#
.SYNOPSIS
Install dependencies to unlock full PWSH functionnalities
 
.DESCRIPTION
PWSH can make use of some binaries that are not included in distro at install time.
This function can install them all at once.
#>

function Install-Dependencies {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$string = ""
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | ForEach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Remove dependencies from current system
 
.DESCRIPTION
Cleanly remove dependencies
# TODO add this function to the uninstall process
#>

function Remove-Dependencies {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$string = ""
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Mount-Iso should mount an .iso file somewhere on the filesystem
 
.DESCRIPTION
Mount-Iso should take care if Iso file is already mounted.
If not, it should try to mount it in a temp directory.
It must return absolute path name of mountpoint or $false if something went wrong
 
.EXAMPLE
Mount-Iso -File /path/to/cdrom.iso
Mount the iso '/path/to/cdrom.iso' into the filesystem
 
.EXAMPLE
Mount-Iso -File /path/to/cdrom.iso -To /mnt/myiso
Mount the iso '/path/to/cdrom.iso' into the /mnt/myiso directory
 
.OUTPUTS
Absolute pathname of the mountpoint of the iso file
 
#>

function Mount-Iso {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$File = "",
    # [string]$To = $null
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Dismount-Iso should unmount an .iso file from the filesystem
 
.DESCRIPTION
Dismount-Iso should simply unmount iso file and clean mountpoint
 
.EXAMPLE
Dismount-Iso -File /path/to/cdrom.iso
Dismount the iso '/path/to/cdrom.iso' from the filesystem
 
.EXAMPLE
Dismount-Iso -From /mnt/myiso
Dismount the iso from the /mnt/myiso directory
 
.OUTPUTS
$true on success, $false otherwise
 
#>

function DisMount-Iso {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$File = "",
    # [string]$To = $null
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Mount-Hive should mount a Windows registry hive file somewhere on the current registry tree.
 
.DESCRIPTION
Under Windows Operating System :
  - Mount-Hive should take care if the Hive file is already mounted.
  - Mount-Hive should mount the requested hive under HKLM\__HIVENAME
  - It should return the absolute mountpoint of the hive file (e.g. HKLM\__HIVENAME)
 
Under Unix/Linux Operating System using libguestfs (hivex*) :
  - Mount-Hive should just resolve path and return absolute path to hive file
 
It must return absolute path to mounted hive or $false if something went wrong
 
.EXAMPLE
Mount-Hive -File C:\Windows\System32\config\SOFTWARE
Should do nothing as this hive is probably already mounted (except under WinPE)
 
.EXAMPLE
Mount-Hive -File X:\Windows\System32\config\SOFTWARE
Should mount the hive SOFTWARE under the current HKLM hive.
 
.EXAMPLE
Mount-Hive -Path X:\Windows -Hive
 
.OUTPUTS
Absolute pathname or the mountpoint of the Hive file
 
.NOTES
 
#>

function Mount-Hive {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$File = "",
    # [string]$To = $null
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Dismount-Hive should unmount an .Hive file from the filesystem
 
.DESCRIPTION
Dismount-Hive should simply unmount Hive file and clean mountpoint
 
.EXAMPLE
Dismount-Hive -File /path/to/install.Hive
Dismount the Hive '/path/to/install.Hive' from the filesystem
 
.EXAMPLE
Dismount-Hive -From /mnt/myHive
Dismount the Hive file from the /mnt/myHive directory
 
.OUTPUTS
$true on success, $false otherwise
 
.NOTES
For the moment, dismounting en Windows Image will discard any changes
 
#>

function DisMount-Hive {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$File = "",
    # [string]$To = $null
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Mount-Wim should mount a .wim file somewhere on the filesystem
 
.DESCRIPTION
Mount-Wim should take care if the WIM file is already mounted.
If not, it should try to mount it in a temp directory.
It must return absolute path name of mountpoint or $false if something went wrong
 
.EXAMPLE
Mount-Wim -File /path/to/install.wim
Mount the wim '/path/to/install.wim' into the filesystem
 
.EXAMPLE
Mount-Wim -File /path/to/install.wim -Index 3 -To /somewhere
Mount the 3rd image of th wim file '/path/to/install.wim' into the '/somewhere' directory of the filesystem
 
.OUTPUTS
Absolute pathname of the mountpoint of the wim file
 
.NOTES
For the moment, Windows Image are mounted read-only
 
#>

function Mount-Wim {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$File = "",
    # [string]$To = $null
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Dismount-Wim should unmount an .wim file from the filesystem
 
.DESCRIPTION
Dismount-Wim should simply unmount wim file and clean mountpoint
 
.EXAMPLE
Dismount-Wim -File /path/to/install.wim
Dismount the wim '/path/to/install.wim' from the filesystem
 
.EXAMPLE
Dismount-Wim -From /mnt/mywim
Dismount the wim file from the /mnt/mywim directory
 
.OUTPUTS
$true on success, $false otherwise
 
.NOTES
For the moment, dismounting en Windows Image will discard any changes
 
#>

function DisMount-Wim {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$File = "",
    # [string]$To = $null
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
Skeleton for Test-UserIsAdmin.
 
.DESCRIPTION
Test if a user (or current user) is admin
This function should take an uid or a username as argument.
 
.EXAMPLE
Test-UserIsAdmin
Test if currently logged on user have admin rights (= is root)
 
.EXAMPLE
Test-UserIsAdmin -username root
Test is user 'root' have admin rights
 
.OUTPUTS
$true is provided user is admin, $false otherwise
#>

function Test-UserIsAdmin {
    [CmdletBinding(DefaultParameterSetName="username")]Param (
        [Parameter(ParameterSetName = "username")]
        [Alias("user", "name", "login")]
        [string]$Username = $env:USER,
        [Parameter(ParameterSetName = "id")]
        [Alias("uid", "sid")]
        [string]$id = (id -u)
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
   }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
 
  ###### ####### ## ## ######## ## ## ######## ######## ########
 ## ## ## ## ### ### ## ## ## ## ## ## ## ##
 ## ## ## #### #### ## ## ## ## ## ## ## ##
 ## ## ## ## ### ## ######## ## ## ## ###### ########
 ## ## ## ## ## ## ## ## ## ## ## ##
 ## ## ## ## ## ## ## ## ## ## ## ## ##
  ###### ####### ## ## ## ####### ## ######## ## ##
 
#>


function Get-ComputerArch {
    [CmdletBinding()][OutputType([String])]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
        return "unknown"
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerDisk {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerDomain {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
        return "localdomain"
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerEthernet {
    [CmdletBinding()]Param (
        [switch]$localhost,
        [ValidateSet('Index', 'Name')]
        [string]$ListAvailable = 'Index'
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerFirmwareType {
    [CmdletBinding()][OutputType([String])]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
        return "BIOS"
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerManufacturer {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerModel {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerVersion {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
[NEEDS IMPLEMENTATION] Get the computer name
 
.DESCRIPTION
[NEEDS IMPLEMENTATION]
 
.PARAMETER localhost
request localhost's ComputerName
 
.EXAMPLE
$name = Get-ComputerName -Localhost
 
.NOTES
This function is a skeleton from Dict.OS module. If you see this help, it means this function
is not yet implemented for the OS you are running.
#>

function Get-ComputerName {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
        return "localhost"
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerSerialNumber {
    [CmdletBinding()]Param (
        [switch]$localhost
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

function Get-ComputerBootOrder {
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        # [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        $rc = $false
        $BootMode = Get-ComputerBootMode
        switch ($BootMode) {
            'BIOS' {
                $rc = Get-ComputerBootOrderBIOS @PSBoundParameters
            }
            'UEFI' {
                $rc = Get-ComputerBootOrderUEFI @PSBoundParameters
            }
        }
        return $rc
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

function Get-ComputerNextBoot {
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        # [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        $rc = $false
        $BootMode = Get-ComputerBootMode
        switch ($BootMode) {
            'BIOS' {
                $rc = Get-ComputerNextBootBIOS @PSBoundParameters
            }
            'UEFI' {
                $rc = Get-ComputerNextBootUEFI @PSBoundParameters
            }
        }
        return $rc
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
.SYNOPSIS
Configure computer to boot on user-asked partition
 
.DESCRIPTION
This function is a wrapper to further functions wether the computer booted in UEFI or BIOS mode.
 
.EXAMPLE
Set-ComputerNextBoot -Label "Windows"
 
.EXAMPLE
Set-ComputerNextBoot -MountPoint /boot
 
.EXAMPLE
Set-ComputerNextBoot -Disk sda -Part 1
 
.EXAMPLE
Set-ComputerNextBoot -Disk nvme0n1 -Part 'p1'
 
.EXAMPLE
Set-ComputerNextBoot -Device /dev/sda1
 
.EXAMPLE
Set-ComputerNextBoot -PXE
 
.NOTES
General notes
#>

function Set-ComputerNextBoot {
    [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = "UEFILABEL")]
    [OutputType([Boolean])]
    Param (
        # [switch]$Force,

        # # Label of an UEFI boot entry
        # [ArgumentCompleter({
        # param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
        # $uefi = Get-UEFIBootEntry
        # # $entry = $bcd.Keys | Where-Object { $bcd.$_.description -like "$wordToComplete*" }
        # # $bcd[$entry].description
        # $uefi.label -like "$wordToComplete*"
        # })]
        # [ValidateScript({
        # $uefi = Get-UEFIBootEntry
        # # $_ -in ($bcd.Values.description)
        # $_ -in ($uefi.label)
        # })]
        # [Parameter(Mandatory = $false, ParameterSetName = 'UEFILABEL')][string]$UefiLabel = "Windows Boot Manager",

        # # Label of the bootloader entry
        # # This can be used with any other options as the final active partition may contain a bootloader
        # [Parameter(Mandatory = $false, ParameterSetName = 'UEFILABEL')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'PARTLABEL')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'MOUNTPOINT')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'DISKPART')]
        # [Parameter(Mandatory = $true, ParameterSetName = 'BOOTLOADERLABEL')]
        # [string]$BootLoaderLabel, # = "Windows",

        # # Specify bootloader type
        # # specifying it will improve performance
        # # not specifying it will make script to search for all bootloaders and configure them
        # [ValidateSet('all', 'bcd', 'grub2', 'refind', 'syslinux')]
        # [Parameter(Mandatory = $true, ParameterSetName = 'BOOTLOADERLABEL')][string]$BootLoaderType,

        # # Label of the partition to configure
        # [Alias('Label', 'PartitionLabel', 'Volume')]
        # [Parameter(Mandatory = $true, ParameterSetName = 'PARTLABEL')][string]$PartLabel,

        # # MountPoint of a currently mounted volume or partition
        # [Alias('Letter', 'DriveLetter')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'MOUNTPOINT')][string]$MountPoint,

        # # Disk device name of the partition
        # [Parameter(Mandatory = $false, ParameterSetName = 'DISKPART')][string]$Disk,

        # # Partition number (can be several strings char since nvme disks. e.g. 'p1')
        # [Parameter(Mandatory = $false, ParameterSetName = 'DISKPART')][string]$PartNum,

        # # Full device address like in '/dev/sda1'
        # [Parameter(Mandatory = $false, ParameterSetName = 'DEVICE')][string]$Device,

        # # Boot PXE using IPv4 stack (only available with UEFI firmware)
        # [Alias('PXE')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'NETWORK')][switch]$PXEv4,

        # # Boot PXE using IPv6 stack (only available with UEFI firmware)
        # [Parameter(Mandatory = $false, ParameterSetName = 'NETWORK')][switch]$PXEv6,

        # # If BIOS/UEFI is password-protected, specify it here as a secureString
        # [Parameter(Mandatory = $false)][secureString]$Password

        # Label of the UefiEntry to configure
        [Alias('Efi', 'Uefi')]
        [ArgumentCompleter({
            param($Command, $Parameter, $WordToComplete, $CommandAst, $FakeBoundParams)
            $uefi = Get-UEFIBootEntry
            # $entry = $bcd.Keys | Where-Object { $bcd.$_.description -like "$wordToComplete*" }
            # $bcd[$entry].description
            $uefi.label -like "$wordToComplete*"
        })]
        [ValidateScript({
            $uefi = Get-UEFIBootEntry
            # $_ -in ($bcd.Values.description)
            $_ -in ($uefi.label)
        })]
        [Parameter(Mandatory = $true, ParameterSetName = 'UEFILABEL')]
        [string]$UefiLabel,

        # Label of the partition to configure
        # On legacy BIOS, it will activate correct partition
        # On UEFI, it will specify which partition is the EFI partition
        [Alias('PartitionLabel')]
        [Parameter(Mandatory = $false, ParameterSetName = 'UEFILABEL')]
        # [Parameter(Mandatory = $true, ParameterSetName = 'PARTLABEL')]
        [string]$PartLabel,

        # Label of the partition to configure
        # On legacy BIOS, it will activate correct partition
        # On UEFI, it will specify which partition is the EFI partition
        [Alias('PartitionUUID')]
        [Parameter(Mandatory = $false, ParameterSetName = 'UEFILABEL')]
        # [Parameter(Mandatory = $true, ParameterSetName = 'PARTUUID')]
        [string]$PartUUID,

        # Label of the bootloader to boot
        [Parameter(Mandatory = $false, ParameterSetName = 'UEFILABEL')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'PARTLABEL')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'PARTUUID')]
        [string]$BootLoaderLabel,

        # Type of the bootloader
        [Alias('BL', 'BootLoader')]
        [ValidateSet('auto', 'bcd', 'grub2', 'refind', 'syslinux')]
        [Parameter(Mandatory = $false, ParameterSetName = 'UEFILABEL')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'PARTLABEL')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'PARTUUID')]
        [string]$BootLoaderType = 'auto',

        # Boot PXE using IPv4 stack (only available with UEFI firmware)
        [Alias('PXE')]
        [Parameter(Mandatory = $false, ParameterSetName = 'NETWORK')][switch]$PXEv4,

        # Boot PXE using IPv6 stack (only available with UEFI firmware)
        [Parameter(Mandatory = $false, ParameterSetName = 'NETWORK')][switch]$PXEv6

        # If BIOS/UEFI is password-protected, specify it here as a secureString
        # [Parameter(Mandatory = $false)][secureString]$Password
    )
    Begin {
        Write-PwShFwOSEnterFunction
        $uefiEntry = $null
    }

    Process {
        $rc = $false
        $BootMode = Get-ComputerBootMode
        switch ($BootMode) {
            'BIOS' {
                # $rc = Set-ComputerNextBootBIOS @PSBoundParameters
                # activate correct partition
                # make target disk 1st boot
                # make bootloader label default choice in (all|bootloader) config file
            }
            'UEFI' {
                # $rc = Set-ComputerNextBootUEFI @PSBoundParameters
                # find UEFI label to boot by default
                switch ($PSCmdlet.ParameterSetName) {
                    'UEFILABEL' {
                        $uefiEntry = Get-UEFIBootEntry -UefiLabel $UefiLabel
                    }
                    'NETWORK' {
                        # try a set of values as manufacturer use their own
                        if ($PXEv4) {
                            # Dell
                            if ([string]::IsNullOrEmpty($uefiEntry)) {
                                $uefiEntry = Get-UEFIBootEntry -UefiLabel "Onboard NIC(IPV4)"
                            }
                        }
                        if ($PXEv6) {
                            # Dell
                            if ([string]::IsNullOrEmpty($uefiEntry)) {
                                $uefiEntry = Get-UEFIBootEntry -UefiLabel "Onboard NIC(IPV6)"
                            }
                        }
                        # Dell
                        if ([string]::IsNullOrEmpty($uefiEntry)) {
                            $uefiEntry = Get-UEFIBootEntry -UefiLabel "Onboard NIC"
                        }
                        # VMware
                        if ([string]::IsNullOrEmpty($uefiEntry)) {
                            $uefiEntry = Get-UEFIBootEntry -UefiLabel "EFI Network"
                        }
                    }
                    default {
                        $uefiEntry = Get-UEFIBootEntry -Current
                    }
                }
                # make UEFI label default choice in UEFI firmware
                if ($uefiEntry) {
                    if ($PSCmdlet.ShouldProcess($uefiEntry.description, "Set-ComputerUEFINextBoot")) {
                        $rc = $uefiEntry | Set-ComputerUEFINextBoot
                        if (!$rc) {
                            Write-Error "Cannot Set-ComputerUEFINextBoot."
                        }
                    }
                } else {
                    Write-Error "Cannot find a suitable UEFI entry."
                    return $false
                }
                # make bootloader label default choice in (all|bootloader) config file
                if ($BootLoaderLabel) {
                    if ($PartLabel) {
                        $Mountpoint = Mount-ComputerDiskPartition -PartLabel $PartLabel
                    }
                    if ($PartUUID) {
                        $Mountpoint = Mount-ComputerDiskPartition -PartUUID $PartUUID
                    }
                    if ($PSCmdlet.ShouldProcess($BootLoaderLabel, "Set-ComputerBootLoaderDefaultBoot")) {
                        Set-OSBootLoaderDefaultBoot -Label $BootLoaderLabel -OSBootloaderType $BootLoaderType -Mountpoint $Mountpoint
                    }
                }
            }
        }
        return $rc
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

<#
 
 ######## ####### ####### ######## ## ####### ### ######## ######## ########
 ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
 ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
 ######## ## ## ## ## ## ## ## ## ## ## ## ## ###### ########
 ## ## ## ## ## ## ## ## ## ## ######### ## ## ## ## ##
 ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
 ######## ####### ####### ## ######## ####### ## ## ######## ######## ## ##
 
#>


<#
.SYNOPSIS
Get all UEFI informations as an object
 
.DESCRIPTION
Long description
 
.NOTES
General notes
#>

function Get-UEFI {
    [CmdletBinding()]
    [OutputType([object])]
    Param (
        # [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        $uefi = [PSCustomObject]@{
            id = ""
            bootorder = @()
            bootcurrentid = ""
            timeout = 0
            entries = [PSCustomObject]@{}
        }
        $uefi.id = Get-UEFIId
        $uefi.bootcurrentid = (Get-UEFIBootCurrentEntry).id
        $uefi.bootorder = Get-UEFIBootOrder
        $uefi.timeout = Get-UEFIBootTimeout
        $uefi.entries = Get-UEFIBootEntry -All

        return $uefi
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}

# function Find-OSBootLoader {
# [CmdletBinding()]
# [OutputType([String])]
# Param (
# [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$string
# )
# Begin {
# Write-PwShFwOSEnterFunction
# }

# Process {
# return $string
# }

# End {
# Write-PwShFwOSLeaveFunction
# }
# }

<#
 
 ######## ######## ## ## ######## ######## ## ## ######## ########
 ## ## ## ## ## ## ## ### ## ## ##
 ## ## ## ## ## ## ## #### ## ## ##
 ###### ## ######### ###### ######## ## ## ## ###### ##
 ## ## ## ## ## ## ## ## #### ## ##
 ## ## ## ## ## ## ## ## ### ## ##
 ######## ## ## ## ######## ## ## ## ## ######## ##
 
#>


# function Get-EthernetObject {
# [CmdletBinding()]Param (
# [Parameter(ValueFromPipeLine = $true)]
# [string]$AdapterName,
# [ValidateSet('IPv4', 'IPv6')]
# [string]$Family = 'IPv4'
# )
# Begin {
# Write-PwShFwOSEnterFunction
# $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
# }
# }

# 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
# }

# End {
# Write-PwShFwOSLeaveFunction
# }
# }

# function Get-EthLinkStatus {
# [CmdletBinding(
# DefaultParameterSetName="INDEX"
# )]Param(
# # Parameter help description
# [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)]
# [int]$AdapterIndex = 1,

# [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)]
# [string]$AdapterName = "lo"
# )

# Begin {
# eenter($Script:NS + "\" + $MyInvocation.MyCommand)
# }

# Process {
# $Script:WarningMessage | Foreach-Object {
# ewarn($_ -f $MyInvocation.MyCommand)
# }
# return $false
# }

# End {
# eleave($Script:NS + "\" + $MyInvocation.MyCommand)
# }
# }

<#
.SYNOPSIS
[NEEDS IMPLEMENTATION] Get network adapter speed
 
.DESCRIPTION
[NEEDS IMPLEMENTATION] Ask OS for network adapter speed
 
.PARAMETER AdapterIndex
Adapter index
 
.PARAMETER AdapterName
Adapter name
 
.EXAMPLE
Get-EthSpeed -AdapterIndex 0
 
.EXAMPLE
Get-EthSpeed -AdapterName Ethernet0
 
.OUTPUTS
[uint32] return link speed in bytes per seconds
 
.NOTES
This function is a skeleton from Dict.OS module. If you see this help, it means this function
is not yet implemented for the OS you are running.
#>


function Get-EthSpeed {
    [CmdletBinding(
        DefaultParameterSetName="INDEX"
    )][OutputType([System.Int32])]Param(
        # Parameter help description
        [Parameter(ParameterSetName="INDEX",ValueFromPipeLine = $true)]
        [int]$AdapterIndex = 0,

        [Parameter(ParameterSetName="NAME",ValueFromPipeLine = $true)]
        [string]$AdapterName = "lo"
    )

    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
        return 0
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}


<#
 
    ### ######## ###### ## ## #### ## ## ######## ######
   ## ## ## ## ## ## ## ## ## ## ## ## ## ##
  ## ## ## ## ## ## ## ## ## ## ## ##
 ## ## ######## ## ######### ## ## ## ###### ######
 ######### ## ## ## ## ## ## ## ## ## ##
 ## ## ## ## ## ## ## ## ## ## ## ## ## ##
 ## ## ## ## ###### ## ## #### ### ######## ######
 
#>


<#
.SYNOPSIS
[NEEDS IMPLEMENTATION] Fake function for Expand-Cabinet as is an OS specific operation.
 
.DESCRIPTION
[NEEDS IMPLEMENTATION] The real function must be declared by the Dict/Dict.* modules.
 
.PARAMETER filename
Filename of the cabinet to extract
 
.NOTES
This function is a skeleton from Dict.OS module. If you see this help, it means this function
is not yet implemented for the OS you are running.
#>

function Expand-Cabinet {
    # [CmdletBinding()]Param (
    # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$filename,
    # [parameter(mandatory=$false, position=1, ValueFromRemainingArguments=$true)][string]$options
    # )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
.SYNOPSIS
[SKELETON] Reload environment variables from system registry
 
.DESCRIPTION
[NEED IMPLEMENTATION] Powershell compute environment variables at startup of powershell process. Update-Environment update variables from registry.
 
.EXAMPLE
Update-Environment
 
.NOTES
Source found @url https://stackoverflow.com/questions/14381650/how-to-update-windows-powershell-session-environment-variables-from-registry
#>


function Update-Environment {
    [CmdletBinding()]Param (
        # [Parameter(Mandatory = $true,ValueFromPipeLine = $true)][string]$string
    )
    Begin {
        # eenter($Script:NS + "\" + $MyInvocation.MyCommand)
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        # eleave($Script:NS + "\" + $MyInvocation.MyCommand)
    }
}

<#
 
 ######## ### ###### ## ## ###### ###### ## ## ######## ######## ## ## ## ######## ########
    ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
    ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
    ## ## ## ###### ##### ###### ## ######### ###### ## ## ## ## ## ###### ########
    ## ######### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
    ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
    ## ## ## ###### ## ## ###### ###### ## ## ######## ######## ####### ######## ######## ## ##
 
#>


<#
.SYNOPSIS
Create a new folder in the Operating System's task scheduler
 
.DESCRIPTION
Create a new folder in the Operating System's task scheduler daemon.
 
.PARAMETER FolderName
The name of the folder to create
 
.PARAMETER Root
An optional root folder to be the parent of the folder to create
 
.EXAMPLE
New-PwShFwScheduledTaskFolder -FolderName "MyDaemon"
 
.NOTES
On linux, this function just create an empty file under /etc/cron.d by default
#>

function New-PwShFwScheduledTaskFolder {
    [CmdletBinding()]
    [OutputType([Boolean])]
    [Alias('New-CronTaskFile')]
    Param (
        [Alias('Name')]
        [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$FolderName,
        [string]$Root = '\'
    )
    Begin {
        Write-PwShFwOSEnterFunction
    }

    Process {
        $Script:WarningMessage | Foreach-Object {
            ewarn($_ -f $MyInvocation.MyCommand)
        }
    }

    End {
        Write-PwShFwOSLeaveFunction
    }
}