I have a USB Flash drive that I use to boot to WinPE and then connect to the network. To do this I need to load the correct network drivers for whatever piece of hardware I am using. Over the years I have found that some similar drivers can interfere with each other if you just load them all. Also it takes quite a while for WinPE to load all the network drivers if I simply add them all into my boot.wim not to mention increasing the size of my boot.wim file. Over time, in order to support new PCs, notebooks and netbooks, I have had to add dozens of drivers. It is also quite a pain to have to open up the boot.wim file each time to add in each new driver.
What I use now is a way to add any new driver just by simply dropping the new Windows network driver into a folder under the \DRIVERS folder on my USB drive. When the boot.wim loads and WinPE starts, the startnet.cmd file now runs a vb script which gets the PCI IDs of all the network devices in the system. More code in startnet.cmd then searches through all the INF files in the \DRIVERS folder to find the matching INF file. Once found, it calls DRVLOAD to load the network driver.
If you are running WinPE v2 (Vista) then you need to add Vista drivers, if you are using WinPE v3 (Win7) then you can use Win7, or else try Vista drivers - they will usually work too.
Click to download a zip file containing the three files mentioned below.
Note: You will need to add both the Scripting (VBS) and MDAC&HTA component packages to your WinPE OS (using peimg or dism) - see the WAIK .chm file for details.
Here is how to set this up (assuming you have already made your winpe boot.wim file):
1. Mount your boot.wim using ImageX as follows:
mkdir c:\mount
imagex /mountrw c:\mywinpe\sources\boot.wim 1 C:\mount
Note: To do this you need to install the Windows WAIK and run an Admin command shell using the Start Menu WAIK command shell link or see here for a way to download imagex in just 30 seconds!
2. Now place getnic.vbs into C:\mount\windows\system32
on error resume next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Wscript.echo ListPCI(".")
Function ListPCI(strComputer)
On error resume next
Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkAdapter",,48)
strMsg = ""
i = 1
Q = chr(34)
For Each objItem in colItems
if mid(objitem.PnPDeviceID,1,7)="PCI\VEN" then
strPCIID = objItem.PNPDeviceID
strNAME = objItem.Name
strMsg=strMsg & vbcrlf & "REM " & strName
strMsg=strMsg & vbcrlf & "SET SHORT_NET" & i & "=" & Q & mid(strPCIID,1,21) & Q
strMsg=strMsg & vbcrlf & "SET LONG_NET" & i & "=" & Q & mid(strPCIID,1,37) & Q
strMsg=strMsg & vbcrlf & "SET LONGREV_NET" & i & "=" & Q & mid(strPCIID,1,44) & Q
i = i + 1
end if
Next
if strMsg = "" then
Set colItems = objWMIService.ExecQuery("Select * from Win32_PnPEntity where Name like '%Ethernet%' OR Name like 'Network'",,48)
i = 1
Q = chr(34)
For Each objItem in colItems
if mid(objitem.PnPDeviceID,1,7)="PCI\VEN" then
strPCIID = objItem.PNPDeviceID
strNAME = objItem.Name
strMsg=strMsg & vbcrlf & "REM " & strName
strMsg=strMsg & vbcrlf & "SET SHORT_NET" & i & "=" & Q & mid(strPCIID,1,21) & Q
strMsg=strMsg & vbcrlf & "SET LONG_NET" & i & "=" & Q & mid(strPCIID,1,37) & Q
strMsg=strMsg & vbcrlf & "SET LONGREV_NET" & i & "=" & Q & mid(strPCIID,1,44) & Q
i = i + 1
end if
Next
End If
ListPCI=strMsg
End Function
3. Now edit the C:\mount\windows\system32\startnet.cmd file to contain the following code (tip: if you have any problems, change the first line to @echo on so you can see the commands as they execute):
@echo off
REM start Network
x:\windows\system32\wpeutil.exe Initializenetwork
x:\windows\system32\netcfg -winpe
wpeinit -unattend=x:\windows\system32\unattend.xml
echo Getting PCI IDs of Network adaptors...
cscript /nologo getnic.vbs > nics.cmd
REM type nics.cmd
call nics.cmd > nul
REM example nics.cmd file contents shown below:
REM SET SHORT_NET1=PCI\VEN_8086&DEV_10C0
REM SET LONG_NET1=PCI\VEN_8086&DEV_10C0&SUBSYS_020D1028
REM SET LONGREV_NET1=PCI\VEN_8086&DEV_10C0&SUBSYS_020D1028&REV_02
REM SET SHORT_NET2=PCI\VEN_8086&DEV_10C0
REM SET LONG_NET2=PCI\VEN_8086&DEV_10C0&SUBSYS_020D1028
REM SET LONGREV_NET2=PCI\VEN_8086&DEV_10C0&SUBSYS_020D1028&REV_02
@echo Looking for \DRIVERS\DRIVERS.TAG file...
@for %%I in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do @if exist %%I:\DRIVERS\DRIVERS.TAG SET DRV=%%I
@if NOT "%DRV%"=="" (
@echo FOUND DRIVERS.TAG file in %DRV%, now loading drivers...
SET DRVA=
SET DRVB=
SET DRVC=
@for /D %%P in (%DRV%:\DRIVERS\*.*) do @for %%I in ("%%~fP\*.inf") do call :TESTINF %%~fI
)
@echo BEST MATCH=%DRVA%, NEXT MATCH=%DRVB%, LAST MATCH=%DRVC%
IF @%DRVA%%DRVB%%DRVC%==@ (
@Echo.
@ECHO **** WARNING: NO SUITABLE DRIVER FOUND - LOADING ALL DRIVERS! ****
@Echo.
@for /D %%P in (%DRV%:\DRIVERS\*.*) do @for %%I in ("%%~fP\*.inf") do drvload %%~fI
)
if NOT @%DRVA%==@ (
@ECHO LOADING %DRVA%...
DRVLOAD %DRVA%
if not errorlevel 1 (
SET DRVB=
SET DRVC=
)
)
if NOT @%DRVB%==@ (
@ECHO LOADING %DRVB%...
DRVLOAD %DRVB%
if not errorlevel 1 SET DRVC=
)
if NOT @%DRVC%==@ (
@ECHO LOADING %DRVC%...
DRVLOAD %DRVC%
)
REM restart network
REM netcfg –winpe
@echo.
@echo.
GOTO :EOF
:TESTINF
SET FNAME=%1
IF NOT EXIST %FNAME% goto :EOF
SET LONGREV_NET=%LONGREV_NET1%
SET LONG_NET=%LONG_NET1%
SET SHORT_NET=%SHORT_NET1%
call :TESTINF1
SET LONGREV_NET=%LONGREV_NET2%
SET LONG_NET=%LONG_NET2%
SET SHORT_NET=%SHORT_NET2%
call :TESTINF1
SET LONGREV_NET=%LONGREV_NET3%
SET LONG_NET=%LONG_NET3%
SET SHORT_NET=%SHORT_NET3%
call :TESTINF1
goto :EOF
:TESTINF1
SET TI=%LONGREV_NET%
if NOT @%TI%==@ (
@Echo Checking for %TI% in %FNAME%
find /I %TI% %FNAME% > nul
if NOT errorlevel 1 SET DRVA=%FNAME%
if NOT errorlevel 1 echo ***** FOUND MATCH IN %FNAME% *****
if NOT errorlevel 1 goto :EOF
)
SET TI=%LONG_NET%
if NOT @%TI%==@ (
find /I %TI% %FNAME% > nul
if NOT errorlevel 1 SET DRVB=%FNAME%
if NOT errorlevel 1 echo ***** FOUND MATCH IN %FNAME% *****
if NOT errorlevel 1 goto :EOF
)
SET TI=%SHORT_NET%
if NOT @%TI%==@ (
find /I %TI% %FNAME% > nul
if NOT errorlevel 1 SET DRVC=%FNAME%
if NOT errorlevel 1 echo ***** FOUND MATCH IN %FNAME% *****
)
goto :EOF
4. Create an Unattend.xml file in C:\mount\windows\system32\Unattend.xml with the following contents:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-Setup" processorArchitecture="x86"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<EnableNetwork>false</EnableNetwork>
<EnableFirewall>false</EnableFirewall>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64"
publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<EnableNetwork>false</EnableNetwork>
<EnableFirewall>false</EnableFirewall>
</component>
</settings>
</unattend>
This file suppresses loading of the network drivers and speeds up WinPE booting (particularly on WinPE v2). It is optional.
5. Save the changes by closing all Explorer windows and running the ImageX command:
imagex /unmount /commit c:\mount
6. Now create a \DRIVERS folder on your WinPE boot drive and copy any network drivers that you need into subfolders under that \DRIVERS folder. You also need to create a \DRIVERS\DRIVERS.TAG file which can have any text in it you like (e.g. a history of which drivers you have added). So the DRIVERS folder may look like this:
\DRIVERS\drivers.tag
\DRIVERS\Inspiron530\(files)
\DRIVERS\EEPC1001\(files)
\DRIVERS\ACER1504\(files)
The driver files will typically consist of an .INF file, a .CAT file and a .SYS file. Sometimes a few other files may also be required (if drvload gives an error, look for any files mentioned within the INF file and include those as well).
Make sure you ONLY include the correct drivers and INF files (e.g. Win 7 INF files for a Win7 PE OS, Vista INF files for a Vista WinPE OS).
Make sure that the file \Drivers\Drivers.tag ONLY exists on your USB drive and not on any other drive, otherwise the script will pick up drivers from the alphabetically highest drive volume letter only!
Karaktaka has used this code and found a few adjustments were required - see his reboot.pro post here for details.
His German PDF WinRecovery_PE31.pdf is available below.
Tags: PCI ID, vbs, NIC, Ethernet, script, shell, load, winpe