如何检测WinPE(4)是否已从UEFI或BIOS启动?

时间:2013-05-22 20:46:05

标签: c# powershell automation winpe efi

我正在寻找一种方法来可靠地检测我何时启动 WinPE 4(powershell)或WinPE 3(vbs)作为替代),我从UEFI或BIOS系统启动了吗?没有运行第三方exe,因为我在受限制的环境中

这会显着改变我在分区布局更改和格式时对Windows部署进行分区的方式。 (GPT与MBR等)

我有一个工作,它是PowerShell v3中this C++代码的改编版,但感觉非常糟糕:

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

为了得到一个简单的旗帜,这似乎相当于顶部。

有没有人知道是否有更好的方法来完成这项工作?

7 个答案:

答案 0 :(得分:2)

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

$(Get-ComputerInfo).BiosFirmwareType

答案 1 :(得分:1)

从某种意义上说,它仍然需要来自powershell的互操作,但如果您使用(或可以调用)GetFirmwareType(),则互操作代码可能更整洁。

这将返回记录hereFIRMWARE_TYPE枚举。我不敢相信,因为在Windows 8中引入了两个函数并且由kernel32.dll导出,Microsoft自己的文档指向“使用虚拟变量”!

在内部,GetFirmwareType调用NtQuerySystemInformation。我将深入研究它的作用,但我认为它不一定会具有启发性。

不幸的是,这仅适用于PE4(Windows 8),因为只添加了这些功能。

答案 2 :(得分:1)

这可能有点晚,但如果知道它们在WinPE中运行,则以下代码应该有效:

$isuefi = (Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Control).PEFirmwareType -eq 2

答案 3 :(得分:0)

我没有UEFI系统来测试它,但是这篇文章似乎暗示了一个注册表值,您可以在PE下查询它以告诉它在哪种模式下启动:

http://technet.microsoft.com/en-us/library/dn293283.aspx

答案 4 :(得分:0)

$env:firmware_type

不确定,因为它支持哪个版本。 在我的测试中返回UEFILegacy

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

答案 5 :(得分:-1)

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

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

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

     Write-host "You're in Windows PE"

}

答案 6 :(得分:-1)

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

Win32_DiskPartition具有“Bootable”(bool),“BootPartition”(bool)和“Type”(字符串)属性。对于我的UEFI系统,“Type”返回字符串“GPT:System”。

现在,对于所有可引导的Win32_DiskPartition,如果是引导分区,并且具有指定的类型,请确定它们是否是内部的。

希望这有帮助。