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 progress to my powershell project.  My prior post had the basics here: http://forum.driverpacks.net/viewtopic. … 275#p59275

The below code (generated with the help of AI) 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 discriminator to handle the different command options. I'm not convinced this new longer script is any "better" than my previous short script.  I'm not sure the AI code can be trusted.
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.  There are valid reasons to NOT use $WinPEDriver$ folder, but the benefits outweigh the problems I think.
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
Write-Host "--- All processing complete at $(Get-Date) ---"
Write-Host "--- Finished on computer: $env:COMPUTERNAME ---"
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!