Description
I wrote this program to compare the installed printers on multiple citrix servers. (locally installed printers, not redirected) The first time you run the program it will create an INI file in the same directory as your script. (read the directions variables for information) You MUST modify this file to match your environment. You define one print server/client as the “master” and it will compare it to as many others as you want it to. It is matching Printer Name, Port Name, and Driver Name. If they do not exactly match it will show you the difference. It will also tell you if you are missing printers on either of the servers being compared. If you have 3 print servers, lets call them p1, p2 and p3, you could set p1 as the master and p2 and p3 as compare servers. It would compare all installed printers on p1 to p2 and give you the results. It would then compare all printers on p1 to p3 and give you the results.
Source Code
#include <Array.au3>
$configFile = @ScriptDir & "\" & "PrinterCompare.ini"
If FileExists($configFile)Then
$masterServer = IniRead($configFile, "General", "MasterServer", ".")
$compareServers = IniRead($configFile, "General", "CompareServers", "")
Else
IniWrite($configFile,"General", "Directions1", "For MasterServer, type in the name of the computer you will compare all others to. Use a period if you want to use the local computer. Do not use quotes.")
IniWrite($configFile, "General", "MasterServer", "printserver01")
IniWrite($configFile,"General", "Directions2", "Separate multiple computers in 'CompareServers' with a Pipe symbol '|', Do not use quotes.")
IniWrite($configFile, "General", "CompareServers", "printserver02|printserver03")
MsgBox(0,"","Please setup the configuration file located here: " & $configFile)
Exit
EndIf
$aCompare = StringSplit($compareServers, "|", 2)
Global $aPrintersMaster
$aPrintersMaster = _GetPrinters($masterServer)
For $compare In $aCompare
If Not (_ComparePrintes($masterServer, $compare)) Then MsgBox(0,"","Skipping server: " & $compare)
Next
Func _ComparePrintes($masterServer, $compareServer)
;MsgBox(0,"",$masterServer & " " & $compareServer)
Local $aPrintersCompare
$aPrintersCompare = _GetPrinters($compareServer)
;If we have an issue, skip this computer
If Not IsArray($aPrintersCompare) Then Return 0
Global $nomatch = ""
Local $missingPrinters = "Printers on " & $compareServer & " but not on " & $masterServer & ":" & @CRLF
Local $missingPrinters2 = "Printers on " & $masterServer & " but not on " & $compareServer & ":" & @CRLF
For $x = 1 To (UBound($aPrintersCompare, 1) - 1)
$match = _ArraySearch($aPrintersMaster, $aPrintersCompare[$x][0], 0, 0, 0, 0, 1, 0)
If $match > 0 Then
If ($aPrintersMaster[$match][1] <> $aPrintersCompare[$x][1]) Or ($aPrintersMaster[$match][2] <> $aPrintersCompare[$x][2]) Then
$nomatch &= $masterServer & ": " & $aPrintersMaster[$match][0] & " Driver: " & $aPrintersMaster[$match][1] & " Port: " & $aPrintersMaster[$match][2] & @CRLF
$nomatch &= $compareServer & ": " & $aPrintersCompare[$x][0] & " Driver: " & $aPrintersCompare[$x][1] & " Port: " & $aPrintersCompare[$x][2] & @CRLF & @CRLF
EndIf
Else
$missingPrinters &= $aPrintersCompare[$x][0] & @CRLF
;msgbox(0,"","Could not find printer " & $aPrintersCompare[$x][0])
EndIf
Next
For $x = 1 To (UBound($aPrintersMaster, 1) - 1)
$match = _ArraySearch($aPrintersCompare, $aPrintersMaster[$x][0], 0, 0, 0, 0, 1, 0)
If $match < 0 Then
$missingPrinters2 &= $aPrintersMaster[$x][0] & @CRLF
EndIf
Next
_MsgBoxScrollable(0, "Missing Printers", $missingPrinters & @CRLF & @CRLF & $missingPrinters2)
_MsgBoxScrollable(0, "Printers with different configuration", $nomatch)
Return 1
EndFunc ;==>_ComparePrintes
Func _GetPrinters($computer = ".")
Global $objWMIService = ObjGet("winmgmts:{impersonationLevel = impersonate}!\\" & $computer & "\root\cimv2")
If @error Then
MsgBox(0, "WMI Query Error", "Error connecting to the server " & $computer & ": " & Hex(@error, 8))
Return 0
EndIf
Global $colItems = $objWMIService.ExecQuery("Select * from Win32_Printer")
Global $result = ""
Local $aPrinters[1][3]
$aPrinters[0][0] = 0
For $objItem In $colItems
$aPrinters[0][0] += 1
ReDim $aPrinters[UBound($aPrinters, 1) + 1][3]
$aPrinters[UBound($aPrinters, 1) - 1][0] = $objItem.Name
$aPrinters[UBound($aPrinters, 1) - 1][1] = $objItem.DriverName
$aPrinters[UBound($aPrinters, 1) - 1][2] = $objItem.PortName
Next
;MsgBox(0, "Information", $result)
Return $aPrinters
EndFunc ;==>_GetPrinters
Func _MsgBoxScrollable($mb_Icon, $mb_Title, $mb_Text, $mb_Time = '')
;This function is from: http://www.autoitscript.com/forum/topic/48485-how-do-i-make-a-messagebox-scollable/page__hl__msgbox++scroll
;It was modified slightly to help fix the size of the box
Local $StrnLenText = LongestStringLen($mb_Text)
;Msgbox(0,"",$StrnLenText)
Local $NumberOfLines = (UBound(StringSplit($mb_Text, @CRLF)) - 1) * 6.5
If (160 + $NumberOfLines) >= @DesktopHeight Then $NumberOfLines = @DesktopHeight - 200
If $StrnLenText + 150 >= @DesktopWidth - 200 Then $StrnLenText = @DesktopWidth - 200
Local $Button1Txt = "OK"
Local $Button2Txt = "Cancel"
Local $MsgValue = 0
Local $Timer = ''
Local $ScrollLabel1 = -1, $ScrollLabel2 = -1
Local $iMsgBox = GUICreate($mb_Title, $StrnLenText + 150, 100 + $NumberOfLines, -1, -1, 0x00400000, 0x00000008)
Local $DefaultEditStyle = 0
If $NumberOfLines >= (@DesktopHeight - 200) Or $StrnLenText + 150 >= 200 Then $DefaultEditStyle = 3150016
Local $Edit = GUICtrlCreateEdit($mb_Text, 60, 10, $StrnLenText + 80, $NumberOfLines + 30, _
BitOR($DefaultEditStyle, 64 + 128 + 2048 + 4), 0x990)
Local $IconID = GUICtrlCreateIcon(@SystemDir & "\User32.dll", $mb_Icon, 10, 10, 35, 35)
$Button1 = GUICtrlCreateButton($Button1Txt, 10 + ($StrnLenText / 2), 45 + $NumberOfLines, 60 + StringLen($Button1Txt), 25)
$Button2 = GUICtrlCreateButton($Button2Txt, 80 + ($StrnLenText / 2), 45 + $NumberOfLines, 60 + StringLen($Button2Txt), 25)
GUISetState()
If $mb_Time <> 0 Then $Timer = TimerInit()
ControlFocus($iMsgBox, "", $IconID)
While 1
$imsg = GUIGetMsg()
Select
Case $imsg = $Button1
$MsgValue = 6
ExitLoop
Case $imsg = $Button2
$MsgValue = 7
ExitLoop
Case $imsg = $ScrollLabel1
ControlSend($iMsgBox, "", $Edit, "{PgDn}")
ControlFocus($iMsgBox, "", $IconID)
Case $imsg = $ScrollLabel2
ControlSend($iMsgBox, "", $Edit, "{PgUp}")
ControlFocus($iMsgBox, "", $IconID)
Case $mb_Time <> 0
If TimerDiff($Timer) / 1000 >= $mb_Time Then ExitLoop
EndSelect
WEnd
GUIDelete($iMsgBox)
Return $MsgValue
EndFunc ;==>_MsgBoxScrollable
Func LongestStringLen($sText)
;Used by _MsgBoxScrollable()
Local $BiggestStr = 0
Local $sSplit = StringSplit($sText, @CRLF)
For $i = 1 To UBound($sSplit) - 1
If StringLen($sSplit[$i]) > $BiggestStr Then $BiggestStr = StringLen($sSplit[$i])
Next
Return $BiggestStr * 5 + 50
EndFunc ;==>LongestStringLen