Как определить, загрузилась ли WinPE(4) из UEFI или BIOS?

Я ищу способ надежно определить, когда я загружаюсь в WinPE 4 (powershell) (или WinPE 3 (vbs) в качестве альтернативы), загрузился ли я из системы UEFI или BIOS? (без запуска стороннего исполняемого файла, поскольку я нахожусь в ограниченной среде)

Это значительно меняет способ разделения развертывания Windows по мере изменения макета и формата разделов. (GPT против MBR и т. д.)

У меня есть работающая адаптация этого C++ код в powershell v3, но он кажется довольно хакерским :

## Check if we can get a dummy flag from the UEFI via the Kernel
## [Bool] check the result of the kernel's fetch of the dummy GUID from UEFI
## The only way I found to do it was using the C++ compiler in powershell
Function Compile-UEFIDectectionClass{
    $win32UEFICode= @'
    using System;
    using System.Runtime.InteropServices;

    public class UEFI
    {
       [DllImport("kernel32.dll")]
       public static extern UInt32 GetFirmwareEnvironmentVariableA([MarshalAs(UnmanagedType.LPWStr)] string lpName, [MarshalAs(UnmanagedType.LPWStr)] string lpGuid, IntPtr pBuffer, UInt32 nSize); 

       public static UInt32 Detect()
       {
            return GetFirmwareEnvironmentVariableA("", "{00000000-0000-0000-0000-000000000000}", IntPtr.Zero, 0);
       }
    }
    '@

Add-Type $win32UEFICode
}


## A Function added just to check if the assembly for 
## UEFI is loaded as is the name of the class above in C++.
Function Check-IsUEFIClassLoaded{
     return ([System.AppDomain]::CurrentDomain.GetAssemblies() | % { $_.GetTypes()} | ? {$_.FullName -eq "UEFI"}).Count 
}

## Just incase someone was to call my code without running the Compiled code run first
If (!(Check-IsUEFIClassLoaded)){
    Compile-UEFIDectectionClass
}

## The meat of the checking.
## Returns 0 or 1 ([BOOL] if UEFI or not)
Function Get-UEFI{
    return [UEFI]::Detect()
}

Это кажется слишком чрезмерным только для того, чтобы получить простой флаг.

Кто-нибудь знает, есть ли лучший способ сделать это?


person RogerWilco    schedule 22.05.2013    source источник


Ответы (6)



Самый простой способ — запустить PowerShell:

$(Get-ComputerInfo).BiosFirmwareType
person Giovanni Bassi    schedule 03.02.2020
comment
У меня это работает на WinPE v10.1.18362.1 для Windows 10 v1903, хотя, как ни странно, на v10.1.17763.1 для v1809 Get-ComputerInfo вылетает с ошибкой CimSessionOptions instance is invalid: unsupported protocol or unrecognized custom option. Verify parameter passed to the CimSessionOptions(string) constructor and/or parameters passed to the CimSessionOptions.SetCustomOption(string, string) or CimSessionOptions.SetCustomOption(string, int) method. - person Lance U. Matthews; 04.02.2020
comment
Я протестировал его на Windows 10 10.0.18363.628 (1909) и Server Core 10.0.17763.914 (1809). - person Giovanni Bassi; 05.02.2020
comment
Недостатком $(Get-ComputerInfo -Property BiosFirmwareType).BiosFirmwareType является то, что он довольно медленный (кажется, что он заполняет много вещей, которые затем выбрасываются). - person NiKiZe; 04.11.2020

Это может быть немного поздно, но если кто-то знает, что они работают в WinPE, следующий код должен работать:

$isuefi = (Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Control).PEFirmwareType -eq 2
person Alyssa Haroldsen    schedule 12.07.2014

$env:firmware_type

Не уверен, с какой версии это поддерживается. Возвращает UEFI и Legacy в моих тестах.

Однако это при полной установке, обратите внимание на подтвержденное существование в WinPE.

person NiKiZe    schedule 04.11.2020

Похоже, что в среде PE есть папка, специфичная для среды PE. Кроме того, переменная %TargetDir% описана здесь, свойство TARGETDIR.

Наконец, вы можете проверить, работаете ли вы с X: также должна быть папка с образом boot.wim, который вы можете проверить. Я полагаю, что путь будет X:\Sources\Boot.wim, но проверьте дважды.

if ( Test-Path "%TargetDir%\Windows\wpeprofiles" ) {

     Write-host "You're in Windows PE"

}
person tkrn    schedule 12.06.2013
comment
Дело не в том, нахожусь ли я в WinPE с самого начала. Когда я нахожусь в PE, я был загружен с помощью UEFI или Legacy BIOS. - person RogerWilco; 12.06.2013

Я не знаю, поможет ли это (на основе решения С#), но:

Win32_DiskPartition имеет свойства «Загрузочный» (логическое значение), «BootPartition» (логическое значение) и «Тип» (строка). Для моей системы UEFI «Тип» возвращается как строка «GPT: Система».

Теперь для всех Win32_DiskPartitions, которые являются загрузочными, являются загрузочными разделами и имеют указанный тип, определите, являются ли какие-либо из них внутренними.

Надеюсь это поможет.

person awp2513    schedule 29.08.2013
comment
Это не поможет. Среда WinPE (установщик), скорее всего, будет работать с пустыми жесткими дисками, и наличие определенных типов разделов на диске не гарантирует, что текущая система сможет загрузиться с них (диск мог быть перенесен из другой системы). - person nobody; 30.05.2014
comment
Нет ничего, что делало бы недействительным наличие GPT на диске, даже если он был загружен в режиме EFI. Точно так же диск, разделенный загрузочным разделом FAT32, может быть загружен в режиме EFI даже без GPT, а некоторые прошивки даже поддерживают NTFS. Единственное, что обеспечивает правильность этого, - это установка Windows, но есть и другие способы, кроме установки Windows, для получения окон на диске. - person NiKiZe; 04.11.2020