Deploying Drivers and Firmware to Surface Pro

Important Update - December 9th 2014 - Please do not use the methods outlined in this post to update touch firmware drivers. To exclude the Touch drivers simply remove them from the package of drivers/firmware.

In the last month the Surface Pro team have started releasing driver and firmware packs that include all on the drivers and firmware required for Surface Pro. This pack is a simple zip file that contains all of the drivers as INF files that can be installed with out requiring an executable, which for those of you that have followed my previous posts will know is the way I like to see drivers provided.

Firmware Deployment

Perhaps the coolest thing about this pack is the fact that it includes firmware that is delivered in the form of a driver package. This is possible due to a UEFI feature called capsule packages. These capsule packages can be installed several ways:

  • Published via Windows Update
  • Injected into an offline Windows image
  • Installed into Windows 8 online

Note - They cannot be installed via Windows Software Update Service (WSUS).

The firmware is exposed to the machine as a device under the firmware node in device manager.


To update the firmware manually simply install the driver package on the machine then Windows will then seamlessly take care of the update process for you, ensuring that the correct firmware is applied. Once installed a flag is set for the loader and on restart all available firmware updates are applied. During the boot process a dialog will appear that states “installing system updates”. If you are deploying the drivers as part of an OS deployment, perhaps with the Microsoft Deployment Toolkit or System Center Configuration Manager 2012 you simply add these firmware drivers to your existing driver deployment methodology and the Windows will handle handle the update process for you.

Driver Deployment

Deploying these drivers as part of your existing OS deployment process is simple, however what happens if you want to update drivers on a Surface Pro that has already been deployed. This is definitely something you will want to do as the Surface team has already delivered a number of significant performance improvements as driver and firmware updates. One option would be to manually right clicking on the device in device manager, and select the appropriate driver to install. However this is a laborious process. It is possible to automate this process using a PowerShell script that calls the PnPUtil utility.

The following script iterates recursively through the pack and installs all of the drivers that it finds:

$ScriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition

$files = get-childitem -path $Scriptpath -recurse -filter *.inf

foreach ($file in $files)


    Write-host "Injecting driver $file"

    pnputil -i -a $file.FullName


To use this script extract the driver pack and place the script in top level folder of the extracted zip file. Then execute the script, it will install all drivers (including firmware). This could also be packaged into a System Center Configuration Manager package and deployed to existing machines.


For further details on Surface Pro deployment please refer to the Surface Pro - Enterprise Deployment Quick Start Guide within the Surface Pro firmware and driver pack that I worked with the Surface Team create.

This post was contributed by Ben Hunter, a Solution Architect with Microsoft Consulting Services.

Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use.

Comments (41)
  1. Ben Hunter says:

    You cannot deploy firmware updates through SCUP or from WSUS.



    1. Sam says:

      Hey Ben. as per this article, WSUS should now deploy firmware updates but as per your statement its not the same case….. Which one is corrent.

  2. Ben Hunter says:

    Hi Ryan,

    There was an issue with the pack, this has now been updated and you will find all of the drivers are available from within the pack itself.



  3. Anonymous says:

    I am attempting to deploy Windows 8.1 Enterprise 64 bit to a Surface Pro 2.

    I have tried adding the drivers from both and to SCCM but both sets of drivers fail with error 31 during windows setup. From what I have read error 31 means that setup found an unsigned driver. I checked and both driver packs have unsigned drivers (Display and WLAN). I can deploy the same task sequence to a Lenovo T430 after removing the unsigned drivers but the install still fails on the Surface.

    I have also set the OSDAllowUnsignedDriver variable to False in my task sequence because it was defaulting to true.

    Do you have any ideas as to what I can do to get this to work?

    Thank you.

  4. ccatlett1984_ says:

    I am seeing some odd results, I run the script on a SP3 that has not had its firmware updated recently (July firmware & drivers) We deployed it back then. And the drivers are updated, but the firmware is not staged and does not apply. I have a premier
    case open for this ( REG:114092411833571) If I manually click "update driver software" on each of the four firmware nodes in device manager and point it at the folder containing the extracted driver pack, the firmware is staged and applies on the next reboot.
    I see no errors when running the script. Any ideas?

  5. ccatlett1984_ says:

    @Marty you do not need to disable secure boot, if you have a UEFI pxe image to boot to.MDT (2013) boot images are UEFI enabled. In regards to the usb Ethernet adapter, is a Gigabit Adapter.

  6. Ben Hunter says:

    Hi CarthaR,

    When I refer to touch firmware I am not referring to the Touch cover I am referring to the screen touch. It is important that you don’t use this process to update the touch drivers however the other drivers and firmware should be able to use this process. To
    update the touch firmware you will need to use Windows Update.


  7. says:

    Great write up Ben!

  8. ccatlett1984_ says:

    @smoluh Might need to edit the "pnputil" line to include the system path (although it should be available running as system) Try running the script manually as the system account, use psexec to launch a cmd window as system and look at the output.

    @BenHunter What is the issue with updating the Touch Firmware itself via this method? This really doesn't help clients of mine that do not allow endpoints to talk to windows update at all……

  9. CarthaR says:

    I am looking to upgrade the Surface Pro 3's we have in our corporate environment. After reading your post I noticed that you have posted on 12.9.14 to not update the Touch firmware drivers. We are having issues with our SP3's when redocking. It kills the
    keyboard and only after detach/reattach multiple times do we finally get the keyboard to work again. The November updates has a bunch of Touch cover FW updates as well as Type cover FW updates. Do I remove all of these? Both Touch and Type? I just want to
    be sure. Also, have you heard of this issue with the keyboard not responding after dock? Also, what if any are the issues with the Touch FW updates?


  10. Anonymous says:

    I would ignore this method, use the MSI installer MS is now providing. It works great.

  11. NoDowt says:

    Any updates on the touch drivers issue posted at the top of the article?
    We've just bought a couple Surface Pro3's to test & I've just imported the whole lot into SCCM & created a driver package (using the March 2015 zipped driver/firmware collection).

    Would like to get clarified if this unexplained issue includes SCCM OSD driver injection, or just the pnputil scripted install? And if this is/will be addressed in future driver/firmware collections.

  12. Anonymous says:

    @ Zebulon 1. Firmware will not downgrade, it will realize newer firmware / drivers are installed and not replace them.
    2. Best bet is to query the "driver" version installed for each piece of firmware.

    @NoDowt Applying all of the firmware through a normal OSD TS. You can always run the MSI Surface Platform Update to ensure they are installed. (I'm staying with the January firmware in my boot media, plus OSD) And running the latest MSI near the end of the
    TS. (Since I deploy the msi to machines already in the field.)

  13. engstromr says:

    I am attempting to install the drivers manually after doing a clean install of Windows 8 Enterprise x64.  I created and ran the PowerShell script.  The only device I can't find a driver for is the 'PCI Simple Communications Controller'.  Any ideas?

  14. engstromr says:

    Disregard my previous post.  After running through the first set of Windows Updates, the unknown device was installed.

  15. SCUP for Firmware Updates? says:

    What about importing the Firmware updates through SCUP? Does that work for enterprise?

  16. Rohit says:

    We are deploying Surface Pro using MDT TS, Will deployment take care of updating firmware if included as drivers in MDT?

    I have added the drivers in MDT and created selection profile to include the firware update as part of driver.



  17. Lakshmi J says:


    How can I deploy Firmware through Wise package studio or VB script? is there any way we can perform silent deployment?



  18. Zach Cline says:

    Nice post, it worked perfectly on a surface pro 2 with a fresh install of enterprise 8.1

  19. James Ihde says:

    I understand you stated that these drivers will not be available through WSUS even though they are delivered to systems by Windows Update (so the technology is there).

    In our SCCM 2012 R2 environment there is a Windows 8.1 Drivers classification in the WSUS download options. We have this selected but I haven't noticed any drivers showing up in our list of patches. Are there any plans to release these driver and firmware updates for Enterprise Customers?

  20. Ben Hunter says:

    Hi James,

    I do not know of any plans around adding the Surface drivers to the WSUS catalog.



  21. Michael Davis says:

    I was also having a problem whereby I would attempt to boot a Surface Pro 2 and it would sit on trying to Start the PXE process on ipv4. After about 40-45 seconds, it would flip over to ipv6, then finally flash a message before immediately booting the Surface back into Windows.

    I finally managed to make out the message and it had something about "timeout" in the error. I deduced there was something on the network causing it to take too long to acquire an IP address, both while PXE booting and while pulling from DHCP in Windows. After working with our Network administrator, we realized it was port trunking. We had PortFast enabled on the switch as well, but port trunking mode was causing the Surface ethernet adapter to acquire an IP address incredibly slowly. No other UEFI enabled desktop I tried on that same port had this issue, so I assume it's a problem with the Surface firmware or ethernet adapter.

    As to why we had trunking mode enabled, we have a very specific scenario where we're using a separate vlan for PXE boot along with a Hyper-V server on that port to allow multiple VMs the ability to PXE boot for testing on that port.

    Hopefully this help someone else.

  22. Cormang says:

    Has anyone figured out a way to add the Surface Pro drivers to WDS? They all fail…

  23. Squuiid says:

    Cormang, no, I'm having the same issue. You cannot install the Surface network drivers in 2008R2 WDS.
    Typical of Microsoft. This product is garbage as is Microsoft's support for it in enterprise.

  24. Greg Lambert says:

    Thanks, that is a very helpful tool 🙂

  25. Frustrated says:

    So there's no easy automated way to install the firmware update that actually allow these pieces of crap to PXE boot!?

    So in an enterprise deployment scenario, where you might take delivery of hundreds of Surface Pro 2's, you have to

    1) Physically start up each device, boot into the factory Windows 8.1 image,

    2) Connect it to the network.

    3) Get to the internet (as all enterprise environments will have a corporate firewall set up),

    4) Run Windows Updates to get the firmware update (as for some unfathomable reason you can't make it available via your own WSUS server)

    5) Reboot it.

    6) Allow the firmware update to install

    7) Reboot it again

    8) Finally PXE boot it, in order to deploy your image via MDT TS?

    6) Repeat another x hundred times for each Surface Pro 2 you need to deploy your SOE image to

    Absolutely ridiculous, and completely unacceptable. You'd think a company being smashed by it's main rivals in the tablet market would be bending over backwards to make it as easy as possible for Educational and Corporate environments to take up their devices.
    Instead, completely the opposite seems to be true? Typical Microsoft – left hand has no idea what the right hand is doing.

  26. says:

    Very helpful PowerShell script, much appreciated!

  27. Marty says:

    Hi, It's working fine for deployment if you use the Microsoft Ethernet Adapter, add the the proper driver to Winpe x64 and don't forget to turn off secure boot or you won't be able to boot pxe. Now the Big issue is that the Ethernet adapter for the Surface
    Pro is only 100 mbps and USB 2.0. The OSD takes forever… Pretty disappointed, especially for a 39.99 + tx price.

  28. Aravinda LC says:

    I am facing Issue while injecting driver it says : Unable to find destination partition drive ,disk or partition no valid network adapter found …any one have any idea ?

  29. Ricko says:

    Its easy if you have SCCM, just deploy it as a task sequence. First step of task sequence, copy the files using a command line. Second step run the script from the command line. Third step remove files copied using command line. Will take you about an
    hour to setup.

  30. SPO says:

    When I run the script as a local admin I get a lot of driver failed to install, access denied issues and windows still wants the firmware updates. Am I wrong in thinking that if you download the packages from and then extract the driver packages and use the script above then we shouldn't need to run the firmware update?

  31. smoluh says:

    hi, would someone please help me with the process of pushing out the driver/firmware update to already deployed SP3s?
    we use sccm2012r2 for OSD etc but am not sure where to start with the PS script, how to package the whole thing, thanks in advance.

  32. ccatlett1984 says:

    Take the above powershell script, copy it into a folder with the extracted contents of the Driver pack, make a package.
    The command will be to call the powershell script (you might have to bypass the execution mode, depending on your environment.) Since the driver pack is cumulative, you only need one package, as the latest version of each firmware/driver will always be applied if a device needs it. You will want to force a reboot after the package runs, to ensure the firmware is actually updated.

  33. smoluh says:

    only for test purpose the steps i've done so far:

    I packaged it into a SCCM…

    Package properties
    Data Source tab:
    -This package contains source files \sccmsources…

    Then created program with following settings:
    General tab:
    – Command line: Powershell.exe -executionpolicy Bypass -file .InstallDrivers.ps1
    – Run: Normal
    – After Running: no action

    Environment tab:
    – Program can run: Only when a user is logged on;
    – Run Mode: Run with administrative rights;
    – Ticked: Allow users to interact with this program;
    – Drive mode: Runs with UNC name;

    Advanced tab:
    – Run once for the computer
    – Ticked: Suppress program notifications

    Distributed Content into DP;

    Deployed to existing test collection;

    Deployment settings: Action:Install; Purpose: Available

    When i run it from Software Centre on the client i'm getting following errors:

    Injecting driver HDXMSSExtDsp.inf
    pnputil : The term 'pnputil' is not recognized as the name of a cmdlet,
    function, script file, or operable program. Check the spelling of the name, or
    if a path was included, verify that the path is correct and try again.
    At C:windowsccmcache4InstallDrivers.ps1:11 char:5
    + pnputil -i -a $file.FullName
    + ~~~~~~~
    + CategoryInfo : ObjectNotFound: (pnputil:String) [], CommandNotF
    + FullyQualifiedErrorId : CommandNotFoundException

    Injecting driver RtsUStor.inf
    pnputil : The term 'pnputil' is not recognized as the name of a cmdlet,
    function, script file, or operable program. Check the spelling of the name, or
    if a path was included, verify that the path is correct and try again.
    At C:windowsccmcache4InstallDrivers.ps1:11 char:5
    + pnputil -i -a $file.FullName
    + ~~~~~~~
    + CategoryInfo : ObjectNotFound: (pnputil:String) [], CommandNotF
    + FullyQualifiedErrorId : CommandNotFoundException

    Press Enter to continue

    BTW, if i run it manually without sccm all is running seamlessly.

    could you please give me a hint what im doing wrong?


  34. eschloss says:

    smoluh, I too am trying to run this as an SCCM package and getting the same results when calling pnputil.exe. I tried switching to start-process instead. I have the following as my for loop:
    foreach($file in $files) {
    $Command = "C:WindowsSystem32PnPutil.exe"
    $Arguments = "-i -a """ + $file.FullName + """"
    Start-Process -FilePath $Command -ArgumentList $Arguments -Wait -NoNewWindow

    If I run the script outside of SCCM it works fine. Running as a package, I get:
    Start-Process : This command cannot be run due to the error: The system cannot find the file specified.
    At …SurfaceDrivers.ps1:25 char:5
    + Start-Process -FilePath $Command -ArgumentList $Arguments -Wait-NoNewWindow
    + CategoryInfo : InvalidOperation: (:) [Start-Process], InvalidOperationException
    + FullyQualifiedErrorId : InvalidOperationException,Microsoft.PowerShell.Commands.StartProcessCommand

  35. Kevin Bishop says:

    Ben do you happen to know how to get the auto rotation function back after imaging per your Enterprise Deployment guide. I've imaged five surface pro 3's and non of them will auto rotate. It's like it's missing some driver to enabled it. I say this because
    all the places where you would find the autolock or other features about rotate the icons or settings or check boxes are missing. This is all with and without a cover attached. The sensor diag found a service not started but even after starting it and setting
    it to auto there is still no auto rotation function available on my surface pro 3's.

    any help would be appreciated.

  36. Anonymous says:

    Voici la suite (Part 3) de la procédure de déploiement de la surface Pro 3
    Les différentes

  37. Randy Nerbas says:

    Hi Ben, Like the others, what is the issue with the touch firmware? We don't allow our workstations to connect to MS Update so that isn't an option. Could you please elaborate on why it's important to not do the touch firmware this way? And what other
    option you would recommend for this?

  38. Zebulon says:

    Great post. A couple of quick questions though.

    1) What happens if some buffoon runs this on a Surface that already has newer firmware than what's used in the script? Does the device get the older firmware, or is it smart enough to not go backwards?

    2) Do you know of any way to query WMI to get the current version of each of these three firmware devices? Win32_BIOS.SMSBIOSVersion seems to line up with the UEFI firmware but I haven't had any luck finding the others.

  39. Eric says:

    I used this code to get it to work


    $ScriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition
    Foreach ($file in Get-Childitem $ScriptPath -recurse -filter *.inf)

    Write-host "Injecting driver $file"

    pnputil -i -a $file.FullName


  40. Robert Odom says:

    For Anonymous, in the SCCM task sequence, you can add a Apply Driver Package step for that model, make sure you check the box that says Do unattended installation of unsigned drivers, and on the option tab, add a WMI query to Select * from Win32_ComputerSystem
    Where model like "model name"

Comments are closed.

Skip to main content