Libraries/Bootloader/Includes/Bootloader.Grub2.psm1

<#
.SYNOPSIS
Search for a grub configuration
 
.DESCRIPTION
Search into local partition for a grub.cfg file.
Default search for a "grub.cfg" file. If config name is overriden, use -Filename to search for custom filename.
 
.EXAMPLE
Find-OSBootloaderGrub2Cfg -Path "/boot"
 
.EXAMPLE
Find-OSBootloaderGrub2Cfg -Path "/boot" -Filename "mygrub.cfg"
 
.NOTES
General notes
#>

function Find-OSBootloaderGrub2Cfg {
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        # Path to start search
        [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Path,
        # Custom filename to search for
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][string]$Filename = "grub.cfg",
        # Search as far as MaxDepth deep
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][uint32]$MaxDepth = 3
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        $grubcfg = Get-ChildItem -Path $Path $Filename -Recurse -Depth $MaxDepth -ErrorAction SilentlyContinue
        return ${grubcfg}?.fullname
    }

    End {
        Write-LeaveFunction
    }
}
function Get-OSBootloaderGrub2DefaultBoot {
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        [Alias('ConfigFile')]
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][string]$Grub2Cfg = "/boot/Grub2/Grub2.cfg"
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        $rc = (Get-Content $Grub2Cfg | select-string "^LABEL") | ForEach-Object { $_ -match "^LABEL\s*(?<label>\w+)" }
        if ($rc) {
            return $Matches.label
        } else {
            return $null
        }
    }

    End {
        Write-LeaveFunction
    }
}

function Set-OSBootloaderGrub2DefaultBoot {
    [CmdletBinding()]
    [OutputType([System.Boolean])]
    Param (
        [Alias('ConfigFile')]
        [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][string]$Grub2Cfg = "/boot/Grub2/Grub2.cfg",
        [Parameter(Mandatory = $true, ValueFromPipeLine = $false)][string]$label
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        $Grub2 = (Get-Content $Grub2Cfg -Raw) -replace "^DEFAULT .*", "DEFAULT $label"
        $Grub2 | Out-File $Grub2Cfg
        return $?
    }

    End {
        Write-LeaveFunction
    }
}

function Get-OSBootloaderGrub2BootEntries {
    [CmdletBinding()]
    [OutputType([String])]
    Param (
        # Custom filename to search on
        [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Filename,

        # Show all entries label
        [Parameter(Mandatory = $false, ParameterSetName = 'ALL')][switch]$All
    )
    Begin {
        Write-EnterFunction
    }

    Process {
        $menuEntries = @()
        # $submenuEntries = @()
        if (Test-FileExist $Filename) {
            # parse grub.cfg
            # To extract correct §, we need to read the file with -Raw parameter
            # (?ms) sets regex options m (treats ^ and $ as line anchors) and s (makes . match \n (newlines) too`.
            # ^## .*? matches any line starting with ## and any subsequent characters *non-greedily* (non-greedy is '.*?' set of characters at the end of pattern).
            # -AllMatches to get... well... all matches
            $content = Get-Content -Raw $Filename | Select-String -Pattern '(?ms)^menuentry .*?^}$' -AllMatches
            # edevel("MESSAGES = " + $MESSAGES.Matches[0])
            # Write-Debug "MESSAGE = $MESSAGE"
            foreach ($msg in $content.Matches) {
                $menuEntry = [PSCustomObject]@{}
                $menuEntry | Add-Member -MemberType NoteProperty -name "Bootloader" -Value "grub2"
                $menuEntry | Add-Member -MemberType NoteProperty -name "Filename" -Value $Filename
                if ($msg.value -match "^menuentry '(?<label>.*?)' .*") {
                    $menuEntry | Add-Member -MemberType NoteProperty -name "Label" -Value $Matches.label
                }
                if ($msg.value -match "`n\s*linux\s*(?<kernel>.*)") {
                    $menuEntry | Add-Member -MemberType NoteProperty -name "kernel" -Value $Matches.kernel
                }
                if ($msg.value -match "`n\s*initrd\s*(?<initrd>.*)") {
                    $menuEntry | Add-Member -MemberType NoteProperty -name "initrd" -Value $Matches.initrd
                }
                $menuEntries += $menuEntry
            }
        } else {
            return $null
        }

        return $menuEntries
    }

    End {
        Write-LeaveFunction
    }
}