Public/system/Get-DriverInventory.ps1

#Requires -Version 5.1
function Get-DriverInventory {
    <#
        .SYNOPSIS
            Retrieves a structured inventory of signed drivers from local or remote computers
 
        .DESCRIPTION
            Queries Win32_PnPSignedDriver via CIM to return an inventory of installed device
            drivers, including device name, class, manufacturer, version, date, signature
            state, and INF file. Results can be filtered by device class or restricted to
            unsigned drivers only, and the function supports multiple machines with per-machine
            error isolation.
 
        .PARAMETER ComputerName
            One or more computer names to query. Defaults to the local computer.
            Accepts pipeline input by value and by property name.
 
        .PARAMETER DeviceClass
            Optional device class to filter on (case-insensitive), for example 'Net',
            'Display', or 'System'. When omitted, drivers of all classes are returned.
 
        .PARAMETER UnsignedOnly
            When specified, only drivers that are not digitally signed are returned.
 
        .PARAMETER Credential
            Optional PSCredential for authenticating to remote computers.
            Not used for local queries.
 
        .EXAMPLE
            Get-DriverInventory
 
            Retrieves the full driver inventory from the local computer.
 
        .EXAMPLE
            Get-DriverInventory -ComputerName 'SRV01' -DeviceClass 'Net'
 
            Retrieves only network-class drivers from SRV01.
 
        .EXAMPLE
            'SRV01', 'SRV02' | Get-DriverInventory -UnsignedOnly
 
            Retrieves only unsigned drivers from multiple servers via pipeline.
 
        .OUTPUTS
            PSWinOps.DriverInventory
            Returns one object per driver with device name, class, manufacturer, version,
            date, signature state, and INF file name.
 
        .NOTES
            Author: Franck SALLET
            Version: 1.0.0
            Last Modified: 2026-08-11
            Requires: PowerShell 5.1+ / Windows only
 
        .LINK
            https://github.com/k9fr4n/PSWinOps
 
        .LINK
            https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-pnpsigneddriver
    #>

    [CmdletBinding()]
    [OutputType('PSWinOps.DriverInventory')]
    param(
        [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [Alias('CN', 'DNSHostName')]
        [string[]]$ComputerName = $env:COMPUTERNAME,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [string]$DeviceClass,

        [Parameter(Mandatory = $false)]
        [switch]$UnsignedOnly,

        [Parameter(Mandatory = $false)]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential
    )

    begin {
        Write-Verbose -Message "[$($MyInvocation.MyCommand)] Starting"

        $scriptBlock = {
            @(Get-CimInstance -ClassName 'Win32_PnPSignedDriver' -ErrorAction Stop)
        }
    }

    process {
        foreach ($machine in $ComputerName) {
            try {
                Write-Verbose -Message "[$($MyInvocation.MyCommand)] Querying Win32_PnPSignedDriver on '$machine'"
                $drivers = @(Invoke-RemoteOrLocal -ComputerName $machine -ScriptBlock $scriptBlock -Credential $Credential)

                if ($PSBoundParameters.ContainsKey('DeviceClass')) {
                    $drivers = @($drivers | Where-Object { $_.DeviceClass -eq $DeviceClass })
                }

                $displayName = $machine

                foreach ($driver in $drivers) {
                    $isSigned = [bool]$driver.IsSigned

                    if ($UnsignedOnly -and $isSigned) {
                        continue
                    }

                    [PSCustomObject]@{
                        PSTypeName    = 'PSWinOps.DriverInventory'
                        ComputerName  = $displayName
                        DeviceName    = $driver.DeviceName
                        DeviceClass   = $driver.DeviceClass
                        Manufacturer  = $driver.Manufacturer
                        DriverVersion = $driver.DriverVersion
                        DriverDate    = $driver.DriverDate
                        IsSigned      = $isSigned
                        InfName       = $driver.InfName
                        Timestamp     = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
                    }
                }
            }
            catch {
                Write-Error -Message "[$($MyInvocation.MyCommand)] Failed on '${machine}': $_"
                continue
            }
        }
    }

    end {
        Write-Verbose -Message "[$($MyInvocation.MyCommand)] Completed"
    }
}