8

I am looking for a way to reliably detect when I boot into WinPE 4 (powershell) (or WinPE 3 (vbs) as an alternative), have I booted from a UEFI or BIOS System? (without running a third party exe as I am in a restricted environment)

This significantly changes how I would be partitioning a windows deployment as the partitions layout changes and format. (GPT vs. MBR, etc)

I have one working that is an adaptation of this C++ code in powershell v3 but it feels pretty hack-ish :

## 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()
}

This seems pretty over the top just to get a simple flag.

Does anyone know if there is there a better way to get this done?

4

6 回答 6

3

它同样是 hacky,在某种意义上它仍然需要来自 powershell 的互操作,但是如果你使用(或可以调用)互操作代码可能会更整洁:GetFirmwareType()

这将返回此处FIRMWARE_TYPE记录的枚举。我不敢相信这两个函数都是在 Windows 8 中引入并由 kernel32.dll 导出的,微软自己的文档指出您“使用虚拟变量”!

在内部,GetFirmwareType调用NtQuerySystemInformation. 我会深入研究它在做什么,但我认为它不一定会很有启发性。

不幸的是,这仅适用于 PE4 (Windows 8),因为这些功能是在那时才添加的。

于 2013-07-11T14:32:41.977 回答
2

到目前为止,最简单的方法是在 PowerShell 上运行:

$(Get-ComputerInfo).BiosFirmwareType
于 2020-02-03T22:45:47.357 回答
1

这可能有点晚了,但如果知道它们在 WinPE 中运行,下面的代码应该可以工作:

$isuefi = (Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Control).PEFirmwareType -eq 2
于 2014-07-12T22:05:27.450 回答
0

$env:firmware_type

不知道从什么版本开始支持。返回UEFILegacy在我的测试中。

但是,这是完全安装的,请注意已确认 WinPE 中存在

于 2020-11-04T15:15:06.593 回答
-1

看起来 PE 环境有一个特定于 PE 环境的文件夹。此外,这里描述了变量 %TargetDir%,TARGETDIR 属性

最后,您可以检查您是否从 X 运行:应该还有一个文件夹,其中包含您可以检查的 boot.wim 映像。我相信路径是X:\Sources\Boot.wim但请仔细检查。

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

     Write-host "You're in Windows PE"

}
于 2013-06-12T12:00:51.120 回答
-3

我不知道这是否会有所帮助(基于 C# 解决方案),但是:

Win32_DiskPartition 具有属性“可引导”(布尔)、“引导分区”(布尔)和“类型”(字符串)。对于我的 UEFI 系统,“Type”作为字符串“GPT: System”返回。

现在,对于所有可引导、是引导分区并具有指定类型的 Win32_DiskPartition,确定它们中的任何一个是否是内部的。

希望这可以帮助。

于 2013-08-29T16:15:17.820 回答