Reputation: 81
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?
Upvotes: 8
Views: 8324
Reputation: 1432
$env:firmware_type
Not sure since what version this is supported.
Returns UEFI
and Legacy
in my tests.
However this is on full installation, Have note confirmed existence in WinPE
Upvotes: 1
Reputation: 839
The easieast way by far is to run on PowerShell:
$(Get-ComputerInfo).BiosFirmwareType
Upvotes: 2
Reputation: 3731
This may be a little late, but if one knows they are running in WinPE, the following code should work:
$isuefi = (Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Control).PEFirmwareType -eq 2
Upvotes: 1
Reputation: 11
I don't know if this will help (based on C# solution), but:
Win32_DiskPartition has the properties "Bootable" (bool), "BootPartition" (bool), and "Type" (string). For my UEFI system, "Type" comes back as the string "GPT: System".
Now, for all Win32_DiskPartitions that are bootable, are a boot partition, and have the specified type, determine if any of them are internal.
Hope this helps.
Upvotes: -2
Reputation:
It is no less hacky, in the sense it will still require interop from powershell, but the interop code might be neater if you use (or can call): GetFirmwareType()
.
This returns a FIRMWARE_TYPE
enumeration documented here. I can't believe given both functions are introduced in Windows 8 and exported by kernel32.dll that Microsoft's own documentation points you at "using a dummy variable"!
Internally, GetFirmwareType
calls NtQuerySystemInformation
. I will dig into what it is doing, but I do not think it is necessarily going to be enlightening.
Unfortunately, this only works for PE4 (Windows 8) since these functions were only added then.
Upvotes: 3
Reputation: 606
It looks like the PE environment has a folder that is specific to the PE environment. In addition, the variable %TargetDir% is described here, TARGETDIR property.
Lastly, you could check if you are running from X: There should be also a folder that has the boot.wim image you can check for. I believe the path would be X:\Sources\Boot.wim but double check.
if ( Test-Path "%TargetDir%\Windows\wpeprofiles" ) {
Write-host "You're in Windows PE"
}
Upvotes: -1