Googling turned up much shorter code that actually works, which I have adapted into a generic utility function:
Code:
Public Function PrinterOffline(Optional pstrPrinter As String = "Default") As Boolean
    Dim strWhere As String
    Dim objWMI As Object
    Dim objPrinters As Object
    Dim objPrinter As Object
    
    Set objWMI = GetObject("winmgmts:\\.\root\CIMV2")
    If LCase$(pstrPrinter) = "default" Then
        strWhere = "Default = True"
    Else
        strWhere = "Name = '" & pstrPrinter & "'"
    End If
    Set objPrinters = objWMI.ExecQuery("SELECT * FROM Win32_Printer WHERE " & strWhere)
    For Each objPrinter In objPrinters
        PrinterOffline = objPrinter.WorkOffline
        Exit For
    Next
    Set objPrinter = Nothing
    Set objPrinters = Nothing
    Set objWMI = Nothing
End Function
Send this function the name of the printer you want to query, or send it nothing to query the default printer. Returns True if the printer is turned off or not ready, False if the printer is on.

Does anyone know how I can remove the For...Each loop from the code? It strike me as quite inelegant.