Dictionaries/Dict.OS/Includes/Bootloader/Includes/Bootloader.refind.psm1
<# .SYNOPSIS Search for a refind configuration .DESCRIPTION Search into local partition for a refind.conf file. Default search for a "refind.conf" file. If config name is overriden, use -Filename to search for custom filename. .EXAMPLE Find-OSBootloaderRefindCfg -Path "/boot" .EXAMPLE Find-OSBootloaderRefindCfg -Path "/boot" -Filename "myrefind.conf" .NOTES General notes #> function Find-OSBootloaderRefindCfg { [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 = "refind.conf", # Search as far as MaxDepth deep [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][uint32]$MaxDepth = 3 ) Begin { Write-PwShFwOSEnterFunction } Process { $filename = Get-ChildItem -Path $Path $Filename -Recurse -Depth $MaxDepth -ErrorAction SilentlyContinue return ${refindcfg}?.fullname } End { Write-PwShFwOSLeaveFunction } } <# .SYNOPSIS Get refind boot order .DESCRIPTION according to the documentation @url https://www.rodsbooks.com/refind/configfile.html the key is 'default_selection' from config file. but it can appear several times. .PARAMETER Filename Parameter description .PARAMETER Content Parameter description .EXAMPLE An example .NOTES General notes #> function Get-OSBootloaderRefindBootOrder { [CmdletBinding()] [OutputType([String])] Param ( [Alias('ConfigFile')] [Parameter(Mandatory = $false, ValueFromPipeLine = $false, ParameterSetName = 'FILENAME')][string]$Filename = "/boot/Refind/Refind.conf", [Parameter(Mandatory = $false, ValueFromPipeLine = $false, ParameterSetName = 'CONTENT')][array]$Content ) Begin { Write-PwShFwOSEnterFunction } Process { switch ($PSCmdlet.ParameterSetName) { 'FILENAME' { $Content = Get-OSBootloaderRefindArray -Filename $Filename } } # the key is 'default_selection' from config file. # but it can appear several times. # according to the help } End { Write-PwShFwOSLeaveFunction } } function Set-OSBootloaderRefindDefaultBoot { [CmdletBinding()] [OutputType([System.Boolean])] Param ( [Alias('ConfigFile')] [Parameter(Mandatory = $false, ValueFromPipeLine = $false)][string]$Filename = "/boot/Refind/Refind.conf", [Parameter(Mandatory = $true, ValueFromPipeLine = $false)][string]$label ) Begin { Write-PwShFwOSEnterFunction } Process { $Refind = (Get-Content $Filename -Raw) -replace "^DEFAULT .*", "DEFAULT $label" $Refind | Out-File $Filename return $? } End { Write-PwShFwOSLeaveFunction } } <# .SYNOPSIS Abalyze refind.conf file and return an object .DESCRIPTION Load a refind.conf file into an object. All parameters are kept as is. Menuentries are stored in an array. .EXAMPLE $refind = Get-OSBootloaderRefindObject -Filename /boot/Refind/Refind.conf .NOTES General notes #> function Get-OSBootloaderRefindObject { [CmdletBinding()] [OutputType([PSCustomObject])] Param ( # Full path to refind.conf to load [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Filename ) Begin { Write-PwShFwOSEnterFunction } Process { $refind = @{} # $content = (Get-Content $Filename | Select-String -Pattern "^[a-zA-Z_0-9]+" -AllMatches | Select-String "menuentry" -NotMatch) -replace '(^[a-zA-Z_0-9]+)', '${1} = ' | ConvertFrom-StringData # foreach ($key in $content.keys) { # $refind.Add($key, $content.$key) # } # $content = (Get-Content $Filename | Select-String -Pattern "^[a-zA-Z_0-9]+" -AllMatches | Select-String "menuentry" -NotMatch) -replace '(^[a-zA-Z_0-9]+)', '${1} = ' | ConvertFrom-StringData foreach ($line in (Get-Content $Filename)) { if ($line -match "^(?<key>[a-zA-Z_0-9]+)\s(?<value>.*)") { $key = $matches.key $value = $matches.value switch ($key) { 'menuentry' { continue } Default { if ($refind.$key) { if ($refind.$key -is [array]) { $refind.$key += $value } else { $oldValue = $refind.$key $refind.$key = @($oldValue, $value) } } else { $refind.$key = $value } } } } } # $entries = (Get-Content -Raw $Filename) -split '\r?\n\r?\n' -match '^menuentry' # $menuentries = @() # foreach ($entry in $entries) { # $menuentry = @{} # # flatten menuentry # $flatEntry = (($entry -split '\n' -replace '^\s+') -replace '\\', '/' | Select-String "^#" -NotMatch -AllMatches) -replace ' {' -replace '}' # # convert to hashtable # $hash = $flatEntry -replace '(^[a-zA-Z_0-9]+)', '${1} = ' | ConvertFrom-StringData # foreach ($key in $hash.keys) { # $menuentry.Add($key, $hash.$key) # } # $menuentries += $menuentry # } $menuentries = @() $entries = Get-Content -Raw $Filename | Select-String -Pattern '(?ms)^menuentry .*?^}$' -AllMatches # Write-PwShFwOSDevel "MESSAGES = " + $MESSAGES.Matches[0] # Write-PwShFwOSDebug "MESSAGE = $MESSAGE" foreach ($entry in $entries.Matches) { $menuEntry = @{} # save raw entry definition to lose nothing $menuEntry.raw = $entry.value if ($entry.value -match "^menuentry `"(?<label>.*?)`" .*") { $menuEntry.Label = $Matches.label } $options = $entry.value | Select-String -Pattern '\n\s+(?<k>[\S.]*)\s+(?<v>.*)' -AllMatches foreach ($option in $options.Matches) { if ($option.Groups['k'].Value -like "#*") { # this is a comment continue } $key = $option.Groups['k'].Value $value = $option.Groups['v'].Value if ($menuentry.$key) { if ($menuentry.$key -is [array]) { $menuentry.$key += $value } else { $oldValue = $menuentry.$key $menuentry.$key = @($oldValue, $value) } } else { $menuentry.$key = $value } } $menuEntries += [PSCustomObject]$menuEntry } $refind.menuentries = $menuentries return [PSCustomObject]$refind } End { Write-PwShFwOSLeaveFunction } } <# .SYNOPSIS Convert a refind.conf file into a usable object .DESCRIPTION Load a refind.conf file into an array. We can not convert to a hastable as keys can be declared multiple times. 'default_selection' for example or 'initrd'. .EXAMPLE Get-OSBootloaderRefindArray -ConfigurationFile /boot/EFI/refind/refind.conf .NOTES General notes #> function Get-OSBootloaderRefindArray { [CmdletBinding()] [OutputType([array])] Param ( # Full path to refind.conf to load [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Filename ) Begin { Write-PwShFwOSEnterFunction } Process { $refind = @() # $content = (Get-Content $Filename | Select-String -Pattern "^[a-zA-Z_0-9]+" -AllMatches | Select-String "menuentry" -NotMatch) -replace '(^[a-zA-Z_0-9]+)', '${1} = ' | ConvertFrom-StringData # foreach ($key in $content.keys) { # $refind += @{$key = $content.$key} # } foreach ($line in (Get-Content $Filename)) { # # keep comments # if ($line -match "^#") { # $refind += $line # } if ($line -match "^(?<name>[a-zA-Z_0-9]+)\s(?<value>.*)") { switch ($matches.name) { 'menuentry' { continue } Default { $refind += @{$matches.name = $matches.value} } } } } $entries = (Get-Content -Raw $Filename) -split '\r?\n\r?\n' -match '^menuentry' $menuentries = @() foreach ($entry in $entries) { $menuentry = @() foreach ($line in ($entry -split '\n' -replace '^\s+')) { if ($line -match "^(?<name>[a-zA-Z_0-9]+)\s(?<value>.*)") { switch ($matches.name) { 'menuentry' { $menuentry += @{$matches.name = $matches.value -replace ' {'} } Default { $menuentry += @{$matches.name = $matches.value} } } } } $menuentries += @(, $menuentry) } $entries = Get-Content -Raw $Filename | Select-String -Pattern '(?ms)^menuentry .*?^}$' -AllMatches # Write-PwShFwOSDevel "MESSAGES = " + $MESSAGES.Matches[0] # Write-PwShFwOSDebug "MESSAGE = $MESSAGE" foreach ($entry in $entries.Matches) { $menuEntry = @{} $menuEntry.Bootloader = "refind" $menuEntry.Filename = $Filename $options = $entry.value | Select-String -Pattern '\n\s+(?<k>[\S.]*)\s+(?<v>.*)' -AllMatches foreach ($option in $options.Matches) { $key = $option.Groups['k'].Value $value = $option.Groups['v'].Value if ($menuentry.$key) { if ($menuentry.$key -is [array]) { $menuentry.$key += $value } else { $oldValue = $menuentry.$key $menuentry.$key = @($oldValue, $value) } } else { $menuentry.$key = $value } } $menuEntries += $menuEntry } $refind += @{"menuentries" = $menuentries} return $refind } End { Write-PwShFwOSLeaveFunction } } function Get-OSBootloaderRefind { [CmdletBinding()] [OutputType([PSCustomObject])] Param ( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][string]$Filename ) Begin { Write-PwShFwOSEnterFunction } Process { [PSCustomObject]$refind = [PSCustomObject](Get-OSBootloaderRefindObject @PSBoundParameters) return $refind } End { Write-PwShFwOSLeaveFunction } } <# .SYNOPSIS Convert a refind configuration array to a form writable to a file .DESCRIPTION Convert a previously loader configuration in a form suitable to be written again .EXAMPLE $content | Out-OSBootloaderRefindConf | Out-File /boot/EFI/refind/refind.conf .NOTES General notes #> function Out-OSBootloaderRefindConf { [CmdletBinding()] [OutputType([String])] Param ( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)][array]$Content ) Begin { Write-PwShFwOSEnterFunction @" # # refind.conf # Please read refind.conf-sample in the same directory to get explanations # or consult official help @url https://www.rodsbooks.com/refind/configfile.html # "@ } Process { for ($i = 0; $i -lt $Content.Count; $i++) { foreach ($key in $Content[$i].keys) { switch ($key) { 'menuentries' { foreach ($menuentry in $Content.menuentries) { "" for ($j = 0; $j -lt $menuentry.Count; $j++) { foreach ($mkey in $menuentry[$j].keys) { switch ($mkey) { 'menuentry' { "" "menuentry $($menuentry[$j].$mkey) {" } Default { " $mkey $($menuentry[$j].$mkey)" } } } } "}" } } Default { "$key $($Content[$i].$key)" } } } } } End { "" Write-PwShFwOSLeaveFunction } } function Get-OSBootloaderRefindBootEntries { # [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-PwShFwOSEnterFunction # } # 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 # # Write-PwShFwOSDevel "MESSAGES = " + $MESSAGES.Matches[0] # # Write-PwShFwOSDebug "MESSAGE = $MESSAGE" # foreach ($msg in $content.Matches) { # $menuEntry = [PSCustomObject]@{} # $menuEntry | Add-Member -MemberType NoteProperty -name "Bootloader" -Value "refind" # $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*loader\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 # } # if ($msg.value -match "`n\s*options\s*(?<options>.*)") { # $menuEntry | Add-Member -MemberType NoteProperty -name "options" -Value $Matches.options # } # $menuEntries += $menuEntry # } # } else { # return $null # } # return $menuEntries # } # End { # Write-PwShFwOSLeaveFunction # } } |