2013-05-22 3 views
7

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

Это существенно меняет, как я бы секционирования развертывания окна, как изменения разделов макета и формата. (GPT против MBR и т.д.)

У меня есть один рабочий, который является адаптацией this 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() 
} 

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

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

ответ

-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" 

} 
+0

не следует ли я в WinPE, чтобы начать с. Когда я нахожусь в PE, я был загружен UEFI или Legacy BIOS. – RogerWilco

1

Это не менее Hacky, в том смысле, он все равно будет требовать от Interop PowerShell, но код Interop может быть аккуратнее, если вы используете (или можете позвонить): GetFirmwareType().

Это возвращает зарегистрированный номер FIRMWARE_TYPE, зарегистрированный here. Я не могу поверить, что обе функции представлены в Windows 8 и экспортируются kernel32.dll, что документация Microsoft указывает на «использование фиктивной переменной»!

Внутренний, GetFirmwareType звонки NtQuerySystemInformation. Я буду копаться в том, что он делает, но я не думаю, что это обязательно будет просвещением.

К сожалению, это работает только для PE4 (Windows 8), поскольку эти функции были добавлены только тогда.

-1

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

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

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

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

+0

Это не поможет. Среда WinPE (установщик), скорее всего, будет работать против пустых жестких дисков, а наличие определенных типов разделов на диске не гарантирует, что текущая система может загрузиться с них (диск, возможно, был пересажен из другой системы). –

1

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

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

Я никогда нет систем UEFI, чтобы проверить его, но эта статья кажется подразумевает, что есть значение реестра вы можете запросить под PE сказать, в каком режиме он был загружен в:

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