Archive
Simple Script to find MSI errors
Here’s a simple PowerScript to pull out MSI errors out of the EventViewer and the MSI logs.
Baiscally the script first clears the log file then clears everything out of the Temp directory. Next the script prompts for the admin to start the installation, once you are done installing the program click ok to continue. The script will then collect the error messages from the MSI logs and the last three windows installer entries from the EventViewer. If there are no errors then it will return sucessful installs entries from the Event Viewer and nothing from the logs. In short this script is just a time saver from having to dig though the event logs and the temp directory for the msi logs and then having to go through those long MSI logs. Troubleshooting the error codes will still need to happen outside of the script.
Be sure to enable Windows Installer logging before beginning. This can be set with the following PowerShell command line.
Set-ItemProperty -path “HKLM:\SOFTWARE\Policies\Microsoft\Windows\Installer” -name “Logging” -value voicewarmup
Here’s the final code:
MSIErrorExtractor.ps1
Clear-Content errors.txt get-Childitem $env:Temp | remove-Item -force $a = new-object -comobject wscript.shell $b = $a.popup("Please run installation and click ok once installation is complete",0,"Waiting for MSI Installation and User Input",1) Get-EventLog Application | ? {$_.Source -eq "MSIInstaller" } | Select-Object TimeGenerated,Source, EntryType, Message -First 3| Format-List | out-file errors.txt #-and $_.EntryType -eq "Error" filter finderrors { if ($_.contains("Error")) {$_}} Get-Content $env:temp\MSI*.log | finderrors | Out-File -Append errors.txt | notepad errors.txt |
Modifying the MS Print webpage for Internet Printing
By default the Internet Printing web-page only displays 10 printers at a time. In our environment we have over 1600 printers and it would take forever to find the printer you need. By modifying a single line in the following file you can change the maximum number or printers to display per page.
C:\WINNT\Web\Printers\ipp_0001.asp
Change the following line to any number that fits your need.
Const iPrinterLength = 2000
Additionally I removed the Status Column to speed up the time to process the webpage
A section of the orginal ipp_0001.asp looked like this…
For Each objPrinter In objPrinters
If i > iRevEnd Then Exit For
If i > iRevStart Then
iPrinters = iPrinters + 1
ReDim Preserve rgPrinters(ADSI_PRINTER_ATTRIBUTES, iPrinters)
rgPrinters(ADSI_PRINTER_STATUS, iPrinters) = objPrinter.Status
If Err.Number = &H80070005 Then ‘Access Denied
Err.Clear
rgPrinters(ADSI_PRINTER_NAME, iPrinters) = objPrinter.Name
rgPrinters(ADSI_PRINTER_ACCESS, iPrinters) = PRINTER_ACCESS_DENIED
rgPrinters(ADSI_PRINTER_LOCATION, iPrinters) = “”
rgPrinters(ADSI_PRINTER_MODEL, iPrinters) = “”
rgPrinters(ADSI_PRINTER_COMMENT, iPrinters) = “<a href=”"ipp_0001.asp?v=1&startid=” &_
CStr (iStart) & “&endid=” & CStr (iEnd) & “”">” & L_AccessDenied_Text & “</a>”
rgPrinters(ADSI_PRINTER_JOBS, iPrinters) = 0
Else
If Err.Number <> 0 Then
Err.Clear
rgPrinters(ADSI_PRINTER_NAME, iPrinters) = objPrinter.Name
rgPrinters(ADSI_PRINTER_ACCESS, iPrinters) = PRINTER_OPENING
rgPrinters(ADSI_PRINTER_LOCATION, iPrinters) = “”
rgPrinters(ADSI_PRINTER_MODEL, iPrinters) = “”
rgPrinters(ADSI_PRINTER_COMMENT, iPrinters) = L_Opening_Text
rgPrinters(ADSI_PRINTER_JOBS, iPrinters) = 0
Else
dwStatus = objPrinter.Status
If objPrinter.Attributes And &H400 Then dwStatus = dwStatus Or &H80
rgPrinters(ADSI_PRINTER_NAME, iPrinters) = GetFriendlyName (objPrinter.PrinterName, strServerName)
rgPrinters(ADSI_PRINTER_STATUS, iPrinters) = dwStatus
rgPrinters(ADSI_PRINTER_LOCATION, iPrinters) = strCleanString (objPrinter.Location)
rgPrinters(ADSI_PRINTER_MODEL, iPrinters) = strCleanString (objPrinter.Model)
rgPrinters(ADSI_PRINTER_COMMENT, iPrinters) = strCleanString (objPrinter.Description)
rgPrinters(ADSI_PRINTER_JOBS, iPrinters) = objPrinter.JobCount
If Err Then Exit Function
rgPrinters(ADSI_PRINTER_ACCESS, iPrinters) = PRINTER_OK
End If
End If
End If
i = i + 1
Next
After removing the Status lines this was the final code of that section looked like this…
For Each objPrinter In objPrinters
If i > iRevEnd Then Exit For
If i > iRevStart Then
iPrinters = iPrinters + 1
ReDim Preserve rgPrinters(ADSI_PRINTER_ATTRIBUTES, iPrinters)
If Err.Number = &H80070005 Then ‘Access Denied
Err.Clear
rgPrinters(ADSI_PRINTER_NAME, iPrinters) = objPrinter.Name
rgPrinters(ADSI_PRINTER_ACCESS, iPrinters) = PRINTER_ACCESS_DENIED
rgPrinters(ADSI_PRINTER_LOCATION, iPrinters) = “”
rgPrinters(ADSI_PRINTER_MODEL, iPrinters) = “”
rgPrinters(ADSI_PRINTER_COMMENT, iPrinters) = “<a href=”"ipp_0001.asp?v=1&startid=” &_
CStr (iStart) & “&endid=” & CStr (iEnd) & “”">” & L_AccessDenied_Text & “</a>”
Else
If Err.Number <> 0 Then
Err.Clear
rgPrinters(ADSI_PRINTER_NAME, iPrinters) = objPrinter.Name
rgPrinters(ADSI_PRINTER_ACCESS, iPrinters) = PRINTER_OPENING
rgPrinters(ADSI_PRINTER_LOCATION, iPrinters) = “”
rgPrinters(ADSI_PRINTER_MODEL, iPrinters) = “”
rgPrinters(ADSI_PRINTER_COMMENT, iPrinters) = L_Opening_Text
Else
rgPrinters(ADSI_PRINTER_NAME, iPrinters) = GetFriendlyName (objPrinter.PrinterName, strServerName)
rgPrinters(ADSI_PRINTER_LOCATION, iPrinters) = strCleanString (objPrinter.Location)
rgPrinters(ADSI_PRINTER_MODEL, iPrinters) = strCleanString (objPrinter.Model)
rgPrinters(ADSI_PRINTER_COMMENT, iPrinters) = strCleanString (objPrinter.Description)
If Err Then Exit Function
rgPrinters(ADSI_PRINTER_ACCESS, iPrinters) = PRINTER_OK
End If
End If
End If
i = i + 1
Next
