Я написал сценарий 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
попробовал и написал, но запутался, чтобы продолжить



Примечание:
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 создать выходные данные в формате 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. Вы обнаружите, что PowerShell — гораздо более функциональный язык, и то, что вы можете сделать с его помощью довольно легко, может оказаться практически невозможным в пакетном коде. Если это возможно, я рекомендую вообще перейти на PowerShell.
Да, это правда. я уже знаю, что powershell более продвинут, современен и многофункциональен, чем пакетный. многие вещи сложно сделать в пакетном режиме, как эту работу, но легко в PowerShell. Когда я что-то делаю в Powershell, мне интересно попробовать это в пакетном режиме. это сложно, не так просто, как в powershell.
Здесь дела обстоят не так. Мы помогаем вам решить конкретную проблему с вашим пакетным скриптом после того, как вы его написали и запустили. Мы не предлагаем бесплатную услугу конвертации кода, и несправедливо ожидать, что люди станут вашими личными наставниками.