Re: Stand Alone Driverpack utility for all OS (XP, 2k3, 2k8, Vista, Win7)

Hi,
I accidentally glanced at the forum while doing some tidying up on my portable drive ;-). Have you moved anything forward with the project? I currently run SDI after installing Windows which does the job most of the time, and if not WindowsUpdate. Nice to have been involved in the development of such a useful tool when I was young.

http://d1syubgj0w3cyv.cloudfront.net/cdn/farfuture/Vi-VfNVo2-n3OpKsB4llVKFIQfdM7s85pIh1ua1bdSA/perpetual:forever/userbar/translator-3.png

Re: Stand Alone Driverpack utility for all OS (XP, 2k3, 2k8, Vista, Win7)

I've made some significant improvements to my powershell project.  My prior post had the basics here: http://forum.driverpacks.net/viewtopic. … 275#p59275

The below code seems to run just fine in Win10/Win11 post-install environments, but should work in Win7/8 also.  Because of syntax differences between powershell versions, I've added an OS descriminator to handle the different command options. I may toy with placing everything in the $WinPEDriver$ folder at the root of the install medium to make the drivers available during the OS install process for a future version.
It has basic logging and is launched by a "helper" install.bat.

Install.bat

@echo OFF
SET WorkingDir=%cd%
SET PSPath='%WorkingDir%\Install-SpecifiedDrivers.ps1'
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& %PSPath%"

Install-SpecifiedDrivers.ps1

# ========================

# Version 2.2 by Erik Hansen

# Universal driver installer with privilege elevation using existing Microsoft OS tools.

# Install and/or upgrade any drivers specified in the .\drivers directory using pnputil.exe

# Recursively finds each driver installer file INF in the specified folder and uses pnputil to inject the driver into the running OS.

# ========================

# Don't execute this .ps1 script directly, use "helper script" Install_1st.bat

# ========================

# =============================================================================

# Self-Elevation Check - MUST BE AT THE TOP OF THE SCRIPT

# =============================================================================

#

# 1. Check if the current session is running as an Administrator.

# 2. If not, it re-launches the script in a new, elevated PowerShell window.

# 3. The original, non-elevated script then immediately exits.

# =============================================================================

# Get the identity of the current user

# =============================================================================

 

$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()

$windowsPrincipal = [System.Security.Principal.WindowsPrincipal]$currentUser

 

# Check if the user is a member of the 'Administrators' group

if (-not $windowsPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) {

    # If not an admin, re-launch the script with elevated privileges

    try {

        Write-Warning "This script requires administrator privileges. Attempting to re-launch with elevation..."

        # Build the arguments to pass to the new process

        $arguments = "& '$PSCommandPath'"

        # Start a new PowerShell process with the 'RunAs' verb to trigger UAC

        Start-Process powershell.exe -Verb RunAs -ArgumentList $arguments -ErrorAction Stop

        # Exit the current, non-elevated script

        # The 'exit' is crucial to prevent the rest of the script from running in the non-admin context and failing.

        exit

    }

    catch {

        Write-Error "Failed to re-launch with elevated privileges. Please right-click the script and choose 'Run as Administrator'."

        # Pause to allow the user to read the error before the window closes

        Start-Sleep -Seconds 10

        exit

    }

}

# If the script reaches this point, it is confirmed to be running as an administrator.

Write-Host "Script is running with administrator privileges."

# =============================================================================

# End of Elevation Check

# =============================================================================

 

# =============================================================================

# Begin actual work

# =============================================================================

 

# Set string variables, paths, and environment

# Explicitly sets the log path.  If running from a read-only device, change this path to a writeable directory.

$TempLogs = "$env:HOMEDRIVE\Temp\Logs\Install-SpecifiedDrivers_LOG.txt"

$PSScriptRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition

 

# Start log.  Remove the '-Append' option to create new log from scratch.

Start-Transcript -Path $TempLogs -Append

 

# Get all INF files from the drivers directory

# Explicitly sets the path to the drivers directory. Change this to where your drivers are stored.

$driverFiles = Get-ChildItem -Path "$PSScriptRoot\drivers" -Recurse -Filter "*.inf"

Write-Host "Found $($driverFiles.Count) driver packages. Checking for installation or upgrade..."

 

# =============================================================================

# --- OS Version-Aware Driver Enumeration ---

# =============================================================================

$installedDrivers = $null

 

# Get the Major version of the OS. Windows 7 is 6.1, Windows 8 is 6.2, Win 8.1 is 6.3, Win 10/11 are 10.0

$osMajorVersion = [System.Environment]::OSVersion.Version.Major

 

if ($osMajorVersion -ge 10 -or ($osMajorVersion -eq 6 -and [System.Environment]::OSVersion.Version.Minor -ge 2)) {

    # OS is Windows 8 or newer (including 10 and 11)

    Write-Host "OS is Windows 8 or newer. Using 'Get-WindowsDriver'..."

    $installedDrivers = Get-WindowsDriver -Online | Where-Object { $_.ProviderName -ne "Microsoft" }

}

else {

    # OS is Windows 7. Use the WMI fallback.

    Write-Host "OS is Windows 7. Using 'Get-WmiObject' fallback..."

    # The property names from WMI are different, so we use calculated properties

    # to make the output object look the same as the one from Get-WindowsDriver.

    $installedDrivers = Get-WmiObject Win32_PnPSignedDriver | `

        Where-Object { $_.Manufacturer -ne "Microsoft" } | `

        Select-Object @{Name="ProviderName"; Expression={$_.Manufacturer}}, @{Name="Version"; Expression={$_.DriverVersion}}

}

 

if ($installedDrivers -eq $null) {

    Write-Warning "Could not retrieve a list of installed drivers. The upgrade logic will assume no drivers are installed."

}

# =============================================================================

# --- Begin Driver Enumeration and Comparison ---

# =============================================================================

 

foreach ($infFile in $driverFiles) {

    try {

        # Read the INF file content as an array of lines

        $infLines = Get-Content -Path $infFile.FullName -ErrorAction Stop

        # Find the initial Provider line and Driver Version using regex

        $providerLine = $infLines | Select-String -Pattern "^\s*Provider\s*=\s*(.+)"

        $versionLine = $infLines | Select-String -Pattern "^\s*DriverVer\s*=\s*(.+)"

 

        if (-not ($providerLine -and $versionLine)) {

            Write-Warning "Could not find a valid Provider or DriverVer line in $($infFile.Name). Skipping."

            continue

        }

 

        # --- Resolve the Provider token two-step---

       

        # 1. Get the initial token (e.g., "%ManufacturerName%")

        $providerToken = $providerLine.Matches[0].Groups[1].Value.Trim()

        $resolvedProvider = ""

 

        # 2. Check if it's a token that needs resolving

        if ($providerToken.StartsWith('%') -and $providerToken.EndsWith('%')) {

            # It's a token. Let's find its value in the [Manufacturer] section.

           

            # Remove the '%' characters to get the lookup key (e.g., "ManufacturerName")

            $lookupKey = $providerToken -replace '%'

            # Find the start of the [Manufacturer] section

            $mfgSectionLineNum = ($infLines | Select-String -Pattern '^\s*\[Manufacturer\]' -List).LineNumber

           

            if ($mfgSectionLineNum) {

                # Search for the key only in the lines *after* the [Manufacturer] section header

                # The pattern looks for "key = value,..." and captures "value"

                $resolvedLine = $infLines[$mfgSectionLineNum..($infLines.Count - 1)] | `

                    Select-String -Pattern "^\s*$lookupKey\s*=\s*([^,]+)" | `

                    Select-Object -First 1

         # From here, use the $resolvedProvider variable for either option              

                if ($resolvedLine) {

                    # The actual provider name is the first captured group

                    $resolvedProvider = $resolvedLine.Matches[0].Groups[1].Value.Trim()

                }

            }

        } else {

            # It's not a token, so the value is literal.

            $resolvedProvider = $providerToken

        }

 

        if ([string]::IsNullOrWhiteSpace($resolvedProvider)) {

            Write-Warning "Could not resolve provider name for token '$providerToken' in $($infFile.Name). Skipping."

            continue

        }

 

        # ----------------------------------------------

        # The rest of the logic remains the same, using the now-correct $infProvider

        $infProvider = $resolvedProvider

        $infVersionString = ($versionLine.Matches[0].Groups[1].Value.Split(',')[1]).Trim()

        $infVersion = [System.Version]$infVersionString

 

# =============================================================================

# --- Begin Driver Injection using pnputil.exe ---

# =============================================================================

        # Rack and stack the INF file content array and only process driver files that are newer than already installed.

        Write-Host "Processing driver: $($infFile.Name) | Provider: $infProvider | Version: $infVersion"

        $matchingInstalledDriver = $installedDrivers | Where-Object { $_.ProviderName -eq $infProvider } | Sort-Object -Property Version -Descending | Select-Object -First 1

 

        if ($matchingInstalledDriver) {

            $installedVersion = [System.Version]$matchingInstalledDriver.Version

            # We matched a newer driver than what is installed on the system.  Yay!

            Write-Host "Found installed driver from provider '$infProvider' with version $installedVersion."

            if ($infVersion -gt $installedVersion) {

                Write-Host "Newer version $infVersion found for $($infFile.Name). Upgrading..."

                pnputil.exe /add-driver $infFile.FullName /install

                Write-Host "SUCCESS: Upgraded driver from $($infFile.FullName)."

            } else {

                Write-Host "Installed version ($installedVersion) is the same or newer. No action needed."

            }

        } else {

            # We didn't find an existing driver to match the scanned driver. Pushing the driver through pnputil and let the system sort it out.

            # If it works, great.  If it fails, not our problem.

            Write-Host "No existing driver found for provider '$infProvider'. Installing..."

            pnputil.exe /add-driver $infFile.FullName /install

            Write-Host "SUCCESS: Installed new driver from $($infFile.FullName)."

        }

    }

    catch {

        Write-Error "An error occurred while processing $($infFile.FullName): $_"

    }

    Write-Host "---"

}

 

# Stop log

Stop-Transcript
Read BEFORE you post.  HWID tool   DriverPacks Tutorial   DONATE!
http://driverpacks.net/userbar/admin-1.png
Not all heroes wear capes, some wear Kevlar!