1

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?

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)
  • I see. So highest possible version would be 65535.65535.65535.65535 - should actually be enough for a printer driver... - thanks, nice answer. – TNT Dec 5 '18 at 16:54
0

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.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.