Создайте массив из вывода Bcdedit/Firmware

Я написал сценарий PowerShell для сохранения вывода в массивах.

function FWList {
    $FWStore = bcdedit /enum firmware
    $FWOS = ($FWStore | select-string identifier,device,path,description) -notmatch '{fwbootmgr}'
    for ( $n=0; $n -lt $FWOS.count; $n++ ) {
        if ( $FWOS[$n] -match 'identifier' ) {
            if ( $FWOS[$($n + 1 )] -match 'device' ) {
                [PsCustomObject]@{
                    des  = $FWOS[$($n + 3)].line.TrimStart('description').Trim()
                    id   = $FWOS[$n].line.Split()[-1]
                    path = $FWOS[$($n + 2)].line.Split()[-1]
                    dev  = $FWOS[$($n + 1)].line.Split()[-1]
                }
            } else {
            [PsCustomObject]@{
                    des  = $FWOS[$($n + 1)].line.TrimStart('description').Trim()
                    id   = $FWOS[$n].line.Split()[-1]
                }
            }
        }
    }
}

# Example Usage
FWList | Format-List #To show in List view
FWList | Format-Table #To show in Table view
(FWList)[1..3] | Foreach {$_.des}
Pause

Ниже приведен пример вывода команды bcdedit /firmware:

des  : Windows Boot Manager
id   : {bootmgr}
path : \EFI\Microsoft\Boot\bootmgfw.efi
dev  : partition=\Device\HarddiskVolume3

des : ATA HDD: ADATA SU650
id  : {ed2a2e5c-bb68-11ee-89e6-806e6f6e6963}

По какой-то причине я просто хотел переписать сценарий в пакетном режиме.

Я попробовал так, но не знаю, как продолжить...

Кто-нибудь может помочь?

@echo off
setlocal ENABLEDELAYEDEXPANSION
set "FWOSList=bcdedit /enum firmware ^| findstr "identifier description device path" ^| findstr /v "{fwbootmgr}""
set arr=0
for /F "usebackq tokens=1-4" %%a in ( `%FWOSList%` ) DO (
    if /I "%%a[%arr%]"= = "identifier" set ID[%arr%]=%%b
    set /a arr+=1

)
rem get description, identifier, device, path

Здесь дела обстоят не так. Мы помогаем вам решить конкретную проблему с вашим пакетным скриптом после того, как вы его написали и запустили. Мы не предлагаем бесплатную услугу конвертации кода, и несправедливо ожидать, что люди станут вашими личными наставниками.

Compo 28.02.2024 18:39

попробовал и написал, но запутался, чтобы продолжить

Mr.Key7 28.02.2024 18:46
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
2
89
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Примечание:

  • Чтобы вызов bcdedit /enum firmware, лежащий в основе вашего решения, увенчался успехом, его необходимо запустить из сеанса с повышенными правами. Следовательно, то же самое должно быть и с кодом ниже.

Судя по вашей собственной попытке с пакетным файлом, вы ищете только значения в строках, которые начинаются с identifier, за исключением строки, значение которой равно {fwbootmgr}.

@echo off & setlocal enableDelayedExpansion

:: Loop over all "identifier" lines of interest and store the 2nd
:: whitespace-separated token of each 
:: in individual ID[%ndx%] variables that emulate an array.
set i=0
for /f "usebackq tokens=2" %%a in (`
  bcdedit /enum firmware ^| findstr "^identifier " ^| findstr /v "{fwbootmgr}"
`) do set "ID[!i!]=%%a" & set /a i=i+1

:: Example processing:

:: Print all ID[%ndx%] variables that were created.
echo -- Resulting ID[%%ndx%%] variables:
set ID[

:: Target a specific variable, the 2nd one in this example.
set i=1
echo -- Value of ID[%i%]:
echo !ID[%i%]!

Примечание:

  • Если вам нужно убедиться, что ранее существовавшие переменные Item[%ndx%] не существуют, поместите перед вызовом for /f следующее:

    for /f "delims= = " %%i in ('Set Item[ 2^>NUL') do set "%%i = "
    

Если вы хотите захватить все значения в нескольких эмулируемых массивах, каждый из которых соответствует одному из свойств в выходных данных вашего кода PowerShell:

  • Эмуляция того, что делает код PowerShell в пакетном файле, была бы чрезвычайно громоздкой.

  • Поэтому вызовите код PowerShell из командного файла через powershell.exe, интерфейс командной строки Windows PowerShell.

    • Хотя можно использовать многострочные команды PowerShell из пакетного файла, для этого необходимо тщательное экранирование — см. этот ответ. Поэтому в приведенном ниже решении используется однострочное представление кода вашего вопроса.
  • Чтобы упростить анализ выходных данных для пакетного файла, дайте команду PowerShell создать выходные данные в формате CSV, используя ConvertTo-Csv.

@echo off & setlocal enableDelayedExpansion

set i=0
for /f "usebackq tokens=1-4 delims=," %%a in (`
  powershell -NoProfile -Command "function FWList { $FWStore = bcdedit /enum firmware; $FWOS = ($FWStore | select-string identifier,device,path,description) -notmatch '{fwbootmgr}'; for ( $n=0; $n -lt $FWOS.count; $n++ ) { if ( $FWOS[$n] -match 'identifier' ) { if ( $FWOS[$($n + 1 )] -match 'device' ) { [PsCustomObject]@{ des = $FWOS[$($n + 3)].line.TrimStart('description').Trim(); id = $FWOS[$n].line.Split()[-1]; path = $FWOS[$($n + 2)].line.Split()[-1]; dev = $FWOS[$($n + 1)].line.Split()[-1]; } } else { [PsCustomObject]@{ des = $FWOS[$($n + 1)].line.TrimStart('description').Trim(); id = $FWOS[$n].line.Split()[-1] } } } } }; FWList | ConvertTo-Csv -NoTypeInformation | select -Skip 1"
`) do set "DES[!i!]=%%~a" & set "ID[!i!]=%%~b" & set "PATH[!i!]=%%~c" & set "DEV[!i!]=%%~d" & set /a i=i+1

:: Example processing:

:: Print all "array variables" that were created.
echo -- Resulting DEV[%%ndx%%] variables:
set DES[
echo -- Resulting ID[%%ndx%%] variables:
set ID[
echo -- Resulting PATH[%%ndx%%] variables:
set PATH[
echo -- Resulting DEV[%%ndx%%] variables:
set DEV[

Код работает правильно. Спасибо за это. Это еще один метод, вызывающий powershell из пакета. но мне все еще любопытно, и я изучу это с помощью cmd, не вызывая powershell. Итак, у меня есть два варианта: метод powershell и пакетный метод.

Mr.Key7 28.02.2024 20:51

Рад это слышать, @Mr.Key7. Вы обнаружите, что PowerShell — гораздо более функциональный язык, и то, что вы можете сделать с его помощью довольно легко, может оказаться практически невозможным в пакетном коде. Если это возможно, я рекомендую вообще перейти на PowerShell.

mklement0 28.02.2024 20:56

Да, это правда. я уже знаю, что powershell более продвинут, современен и многофункциональен, чем пакетный. многие вещи сложно сделать в пакетном режиме, как эту работу, но легко в PowerShell. Когда я что-то делаю в Powershell, мне интересно попробовать это в пакетном режиме. это сложно, не так просто, как в powershell.

Mr.Key7 28.02.2024 21:08

Другие вопросы по теме