Retrieve printer driver version with Powershell PrintManagement cmdlets?

5,467

Solution 1

This is because Get-PrinterDriver's DriverVersion is of type UInt64:

enter image description here

A breakout way to fix this is to use the below (source). I hope there is a more elegant way of recasting these values in the format we expect, though I appreciate how transparent this method is to best understand what is going on.

Get-PrinterDriver | Select-Object Name,@{
    n="DriverVersion";e={

        $ver = $_.DriverVersion
        $rev = $ver -band 0xffff
        $build = ($ver -shr 16) -band 0xffff
        $minor = ($ver -shr 32) -band 0xffff
        $major = ($ver -shr 48) -band 0xffff
        "$major.$minor.$build.$rev"

    }
}

The first result of this when run on my machine is:

Name                                                    DriverVersion 
----                                                    ------------- 
Send to Microsoft OneNote 16 Driver                     16.0.7629.4000

The conversion works by using bitwise operation to evaluate each DriverVersion (64bit) in sections of 16 bits to determine the major, minor, build, and revision numbers.

For example, the first DriverVersion on my machine, as a 64bit number, is 4503600127348640. Here is the bitwise AND (-band) happening during the definition of the $rev variable, shown in binary:

‭00010000000000000000000000011101110011010000111110100000‬ (4503600127348640)
                                        1111111111111111 (65535, aka "0xffff")
                                    =   0000111110100000 (4000)
                                                         (DriverVersion = X.Y.Z.4000)

Here is $build, which also uses -shr (bit shift-right):

‭00010000000000000000000000011101110011010000111110100000‬ (4503600127348640)
                        1111111111111111                 (65535)
                    =   0001110111001101                 (7629)
                                                         (DriverVersion = X.Y.7629.4000)

Here is $minor:

‭00010000000000000000000000011101110011010000111110100000‬ (4503600127348640)
        1111111111111111                                 (65535)
    =   0000000000000000                                 (0)
                                                         (DriverVersion = X.0.7629.4000)

Finally, $major:

00010000000000000000000000011101110011010000111110100000‬ (4503600127348640)
11111111                                                 (65535)
00010000                                                 (16)
                                                         (DriverVersion = 16.0.7629.4000)

Solution 2

There is a lot of room for arguing about what is elegant, what is expressive, what is concise, what is cryptic a.s.o. - A certainly more brief - not necessarily in any way better - version would be the following:

Get-PrinterDriver | Select-Object Name, @{ 
  n = "DriverVersion"
  e = {
        $ver = $_.DriverVersion
        (3..0 | ForEach-Object { ($ver -shr ($_ * 16)) -band 0xffff }) -join '.'
      }
}

Just another way to Rome.

Share:
5,467

Related videos on Youtube

TNT
Author by

TNT

Updated on September 18, 2022

Comments

  • TNT
    TNT over 1 year

    The version numbers in the gui look like 10.0.17134.1 and 3.0.8.0 but their equivalents (?) from the Get-PrinterDriver-cmdlet look at least cryptic:

    Get-PrinterDriver | Select-Object Name, MajorVersion, DriverVersion
    

    gives me an output like this:

    Name                   MajorVersion    DriverVersion
    ----                   ------------    -------------
    Microsoft XPS Docu...             4 2814750890000385
    Samsung Universal ...             3  844424930656256
    

    So do I really need to use the WMI/CIM cmdlets to get the real version numbers?

  • TNT
    TNT over 5 years
    I see. So highest possible version would be 65535.65535.65535.65535 - should actually be enough for a printer driver... - thanks, nice answer.
  • GuitarPicker
    GuitarPicker over 2 years
    Excellent. I'm PDQ Inventory to catalog the drivers in our environment, and this was the missing piece.