我正在寻找一种方法来可靠地检测我何时启动 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()
}
为了得到一个简单的旗帜,这似乎相当于顶部。
有没有人知道是否有更好的方法来完成这项工作?
答案 0 :(得分:2)
到目前为止,最简单的方法是在PowerShell上运行:
$(Get-ComputerInfo).BiosFirmwareType
答案 1 :(得分:1)
从某种意义上说,它仍然需要来自powershell的互操作,但如果您使用(或可以调用)GetFirmwareType()
,则互操作代码可能更整洁。
这将返回记录here的FIRMWARE_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下查询它以告诉它在哪种模式下启动:
答案 4 :(得分:0)
$env:firmware_type
不确定,因为它支持哪个版本。
在我的测试中返回UEFI
和Legacy
。
但是,这是完全安装的,请注意已确认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,如果是引导分区,并且具有指定的类型,请确定它们是否是内部的。
希望这有帮助。