DSCClassResources/PrinterDriver/PrinterDriver.psm1

enum Ensure
{
    Absent
    Present
}
[DscResource()]
class PrinterDriver
{
    [DscProperty(Mandatory)]
    [Ensure] $Ensure

    [DscProperty(Mandatory)]
    [System.String[]]$Name

    [DscProperty(Key)]
    [System.String] $Source

    [DscProperty(Mandatory)]
    [System.String] $Version

    [DscProperty()]
    [System.Boolean] $Purge = $false

    hidden $Messages = ""

    PrinterDriver()
    {
        $this.Messages = Import-LocalizedData -FileName 'PrinterDriver.strings.ps1' -BaseDirectory (Split-Path -Parent $PSCOMMANDPATH)
        Import-Module -Name Dism -Verbose:$false
    }
    [void] Set()
    {
        if ($this.Ensure -eq [Ensure]::Present)
        {
            $stagedDriver = $this.InstalledDriver()
            if ($null -eq $stagedDriver)
            {
                Write-Verbose -Message ($this.Messages.DriverDoesNotExistMessage -f $this.Name)

                $output = Invoke-Command -ScriptBlock {
                    param (
                        [Parameter()]$Source
                    )
                    & C:\Windows\System32\pnputil.exe -a "$Source"
                } -ArgumentList ($this.Source)

                [regex]$DriverAdded = '(?i)Published Name\s?:\s*(?<Driver>oem\d+\.inf)'
                $successDriverAdd = $DriverAdded.Match($output)
                if ($successDriverAdd.Success)
                {
                    $this.Source = (Get-WindowsDriver -Driver $successDriverAdd.Groups['Driver'].Value -Online).OriginalFileName[0]
                    Write-Verbose -Message  ($this.Messages.StagedDriverMessage -f $this.Source)
                } # End if DriverAdded
                else
                {
                    Write-Error -Message ($this.Messages.FailedToStageDriver -f $this.Source)
                    return
                } # End Else
            } # End Else
            else
            {
                # Need to reset the Source path to the driver store location
                $this.Source = $stagedDriver.OriginalFileName
            } # End else

            foreach ($Name in $this.Name)
            {
                $AddPrinterPortParams = @{
                    InfPath = $this.Source
                    Name    = $Name
                }
                try
                {
                    $installedPrintDriver = Get-PrinterDriver -Name $Name -ErrorAction Stop
                } # End Try
                catch
                {
                    $installedPrintDriver = $null
                    Add-PrinterDriver @AddPrinterPortParams
                } # End catch

                if ($null -ne $installedPrintDriver -and $installedPrintDriver.InfPath -ne $stagedDriver.OriginalFileName)
                {
                    Add-PrinterDriver @AddPrinterPortParams
                } # End if installedPrintDriver
            } # End foreach Name
        } # End if Ensure Present
        else
        {
            foreach ($Name in $this.Name)
            {
                try
                {
                    Write-Verbose -Message ($this.Messages.RemovingPrintDriver -f $Name)
                    $installedPrintDriver = Get-PrinterDriver -Name $Name -ErrorAction Stop
                } # End Try
                catch
                {
                    $installedPrintDriver = $null
                } # End catch
                if ($null -ne $installedPrintDriver)
                {
                    Remove-PrinterDriver -Name $Name
                } # End if installedPrintDriver
            } # End foreach Name
            if ($this.Purge -eq $true)
            {
                Write-Verbose -Message $this.Messages.PurgingDriverMessage
                $stagedDriver = $this.InstalledDriver()
                if ($null -ne $stagedDriver.Driver)
                {
                    Write-Verbose -Message ($this.Messages.CheckingForRemovalConflicts -f $stagedDriver.Driver)
                    $driverConflicts = Get-PrinterDriver | Where-Object InfPath -eq $stagedDriver.OriginalFileName
                    if ([bool]$driverConflicts)
                    {
                        Write-Warning -Message ($this.Messages.FoundConflicts -f ($driverConflicts.Name -join ','), $stagedDriver.OriginalFileName)
                    } # End if driverConflicts
                    else
                    {
                        Write-Verbose -Message ($this.Messages.RemovingDriverMessage -f $stagedDriver.OriginalFileName)
                        $output = Invoke-Command -ScriptBlock {
                            param (
                                [Parameter()]$Driver
                            )
                            & "C:\Windows\System32\pnputil.exe" -f -d "$Driver"
                        } -ArgumentList ($stagedDriver.Driver)

                        if ($output -ilike "*successfully*")
                        {
                            Write-Verbose -Message ($this.Messages.DriverRemovedSuccessfullyMessage -f $stagedDriver.Driver)
                        }
                        else
                        {
                            Write-Error -Message $this.Messages.ErrorRemovingDriverMessage
                        }
                    } # End else driverConflicts
                } # End If StagedDriver
            } # End if Purge
        } # End Else Ensure
    } # End Set()
    [bool] Test()
    {
        if ($this.Ensure -eq [Ensure]::Present)
        {
            foreach ($Name in $this.Name)
            {
                try
                {
                    $installedPrintDriver = Get-PrinterDriver -Name $Name -ErrorAction Stop
                } # End Try
                catch
                {
                    $installedPrintDriver = $null
                    Write-Verbose -Message  ($this.Messages.NotInDesiredStateMultipleObjects -f "Ensure", $Name, 'Absent', $this.Ensure)
                    return $false
                } # End catch
                $windowsDriverParam = @{
                    Driver = $installedPrintDriver.InfPath
                    Online = $true
                }
                $currentVersion = (Get-WindowsDriver @windowsDriverParam).Version | Get-Unique
                if ($currentVersion -ne $this.Version)
                {
                    Write-Verbose -Message  ($this.Messages.NotInDesiredStateMultipleObjects -f "Version", $Name, $currentVersion, $this.Version)
                    return $false
                }
            } # End foreach Name
        } # End if Ensure Present
        else
        {
            foreach ($Name in $this.Name)
            {
                try
                {
                    $installedPrintDriver = Get-PrinterDriver -Name $Name -ErrorAction Stop
                } # End try
                catch
                {
                    $installedPrintDriver = $null
                } # End catch
                if ($installedPrintDriver)
                {
                    Write-Verbose -Message  ($this.Messages.NotInDesiredStateMultipleObjects -f "Ensure", $Name, 'Present', $this.Ensure)
                    return $false
                } # End if installedPrintDriver
                if ($this.Purge -eq $true)
                {
                    $stagedDriver = $this.InstalledDriver()
                    if (-not [string]::IsNullOrEmpty($stagedDriver))
                    {
                        return $false
                    } # End If StagedDriver
                } # End If Purge
            } # End foreach Name
        } # End else
        return $true
    } # End Test()

    [PrinterDriver] Get()
    {
        $ReturnObject = [PrinterDriver]::new()
        $ReturnObject.Name = @()

        foreach ($Name in $this.Name)
        {
            try
            {
                $installedPrintDriver = Get-PrinterDriver -Name $Name -ErrorAction Stop
            } # End Try
            catch
            {
                $installedPrintDriver = $null
                # Print driver isn't installed, need to look in the driver store to see if it is there. Only checking if the $Purge is set to true
                $ReturnObject.Ensure = [Ensure]::Absent
                if ($this.Purge -eq $true)
                {
                    $stagedDriver = $this.InstalledDriver()
                    if ($null -ne $stagedDriver)
                    {
                        $ReturnObject.Ensure = [Ensure]::Present
                    } # End If StagedDriver
                } # End If this.Purge
                return $ReturnObject
            } # End catch

            $ReturnObject.Ensure = [Ensure]::Present
            $windowsDriverParam = @{
                Driver = $installedPrintDriver.InfPath
                Online = $true
            }

            $ReturnObject.Source = $installedPrintDriver.InfPath
            $ReturnObject.Version = (Get-WindowsDriver @windowsDriverParam).Version | Get-Unique

            [System.Collections.ArrayList]$tmpArrayList = $ReturnObject.Name
            $tmpArrayList.Add($Name)
            $ReturnObject.Name = $tmpArrayList | Sort-Object

            Remove-Variable -Name tmpArrayList
        } # End foreach Name

        return $ReturnObject
    } # End Get()

    hidden [System.Collections.Hashtable] InstalledDriver()
    {
        # Since we don't have an INF file to look at. We need look in the driver store.
        $InstalledDriverPacks = Get-WindowsDriver -Online -All -Verbose:$false | Where-Object { $_.ClassName -eq 'Printer' -and $_.Version -eq $this.Version }
        foreach ($InstalledDriverPack in $InstalledDriverPacks)
        {
            $DriverExists = Get-WindowsDriver -Online -Driver $InstalledDriverPack.Driver -Verbose:$false | Where-Object { $this.Name -contains $_.HardwareDescription }

            if ($DriverExists)
            {
                Write-Verbose -Message ($this.Messages.FoundStagedDriverMessage -f $InstalledDriverPack.OriginalFileName)
                $returnDriver = @{
                    OriginalFileName = $InstalledDriverPack.OriginalFileName
                    Driver           = $InstalledDriverPack.Driver
                }

                return $returnDriver
            } # End if DriverExists
        } # End foreach

        return $null
    } # End InstalledDriver()
} # End Class PrinterDriver