Skip to content

Instantly share code, notes, and snippets.

@littletoyrobots
Last active May 1, 2020 23:21
Show Gist options
  • Select an option

  • Save littletoyrobots/e25ac397eb48c16d43bd5a4e27fd00bd to your computer and use it in GitHub Desktop.

Select an option

Save littletoyrobots/e25ac397eb48c16d43bd5a4e27fd00bd to your computer and use it in GitHub Desktop.
# Make an admin portal config file for your network printers web interfaces!
# This script will take the supplied print servers, and get a list of all their pritners from wmi. It will
# then look to see which of these printers have TCP/IP printer ports. If they do, I try and grab the IP
# address from their hostaddress, then barring that, the port name, and the comments. Then, for each of
# those printers that have a matching IP address, I'll test port 80 and 443 connections to them. I choose
# HTTP first, simply because in my org the HTTPS are all self-signed certs (I know). I also try and use the
# driver name to guess at the manufacturer and assign a picture as well.
# Categories will be grouped by print server, duplicates can exist, and this is probably the wrong way to
# do things.
# Example Usage:
# $PrintServers = "PrintServer", "Print64", "CompanyPrint", "Print2"
# .\Get-AdminPortalPrinters.ps1 -PrintServers $PrintServers
# Example Usage:
# $OutFile = "C:\Git\AdminPortal\printers.csv"
# .\Get-AdminPortalPrinters.ps1 -PrintServers "print1", "print2" -OutFile $OutFile -LogFile "C:\Logs\AdminPortalPrinters.csv"
# C:\Git\AdminPortal\PortalGenerator.ps1 -ConfigFile $OutFile -WebSiteFile "C:\Git\AdminPortal\printers.html"
[cmdletbinding()]
param (
[string[]]$PrintServers,
[string]$OutFile = "$env:TEMP\printers.csv",
[string]$LogFile = "$env:TEMP\AdminPortalPrinters-$(Get-Date -Format filedate).csv",
[switch]$Force
)
# If you don't want have / want PSFramework for logging, or PoshRSJob for speed, it should be relatively
# easy to edit them out.
Import-Module PoshRSJob
Import-Module PSFramework
[datetime]$StartTime = Get-Date
Write-PSFMessage "--- BEGIN $($MyInvocation.MyCommand) ---"
Set-PSFLoggingProvider -Name "logfile" -Enabled $true -FilePath $LogFile
# $PrintServers = "PrintServer", "Print64", "CompanyPrint", "Print2"
if ((Test-Path $OutFile) -and $Force) {
Remove-Item $OutFile -Force
}
$Results = foreach ($PrintServer in $PrintServers) {
try {
$Printers = Get-WmiObject win32_printer -ComputerName $PrintServer -ErrorAction Stop
$PrinterPorts = Get-WmiObject win32_tcpipprinterport -ComputerName $PrintServer -ErrorAction Stop
Write-PSFMessage "There are $($Printers.Count) printers and $($PrinterPorts.Count) ports on $PrintServer"
}
catch {
Write-PSFMessage -Level Warning "Unable to get printers / ports from $PrintServer" -ErrorRecord $Error[0]
continue
}
try {
$Printers | Start-RSJob -Name { "$PrintServer - $($_.Name)" } -ScriptBlock {
$Printer = $_
$PrinterName = $Printer.Name
$PrinterPort = $Printer.PortName
# Let's add some pictures to the printers. Add your own here.
# default to generic
$Image = "img/printer.png"
if ($Printer.DriverName -match "sharp") { $Image = "img/sharp.png" }
elseif ($Printer.DriverName -match "hp") { $Image = "img/hp.png" }
elseif ($Printer.DriverName -match "savin") { $Image = "img/savin.png" }
elseif ($Printer.DriverName -match "kyocera") { $Image = "img/kyocera.png" }
elseif ($Printer.DriverName -match "zdesigner") { $Image = "img/zebra.png" }
elseif ($Printer.DriverName -match "muratec") { $Image = "img/muratec.png" }
try {
# This section will check that a shared printer has a corresponding TCPIP PrinterPort, and if so
# it will check that it has a usable web interface. It will also check the comment in case someone put it in there
$HostAddress = $Using:PrinterPorts | Where-Object Name -eq $PrinterPort | Select-Object -ExpandProperty Hostaddress -First 1
if ($null -ne $HostAddress) {
try {
# Extract the IP address out of the string, as sometimes you'll see IP_123.123.123.123 or
# 123.123.123.123_1 as the port name.
$HostIP = [ipaddress]($HostAddress | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}" -AllMatches).Matches.Value
}
catch {
# if it can't convert to IP address, check in the comments
try {
$HostIP = [ipaddress]($Printer.Comment.Trim() | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}" -AllMatches).Matches.Value
# Write-PSFMessage -Message "$Using:PrintServer - $PrinterName - $PrinterPort - $HostIP - Found IP in comments"
}
catch {
Write-PSFMessage -Level Warning -Message "$Using:PrintServer - $PrinterName - $PrinterPort - No IP found" -ErrorRecord $Error[0]
exit
}
}
}
else {
# If no matching hostname, look in the comments
try {
$HostIP = [ipaddress]($Printer.Comment.Trim() | Select-String -Pattern "\d{1,3}(\.\d{1,3}){3}" -AllMatches).Matches.Value
# Write-PSFMessage -Message "$Using:PrintServer - $PrinterName - $PrinterPort - $HostIP - Found IP in comments"
}
catch {
Write-PSFMessage -Level Warning -Message "$Using:PrintServer - $PrinterName - $PrinterPort - No IP found" -ErrorRecord $Error[0]
exit
}
}
}
catch {
Write-PSFMessage -Level Warning -Message "$Using:PrintServer - $PrinterName - $PrinterPort - Error retrieving hostname" -ErrorRecord $Error[0]
}
# If we have a resolvable IP, let's test it on HTTP then HTTPS.
# Solely doing HTTP because of prevalence of self-signed certs. You should probably reverse these.
$Uri = $null
if ($null -ne $HostIP) {
if (Test-NetConnection $HostIP -Port 80 -InformationLevel Quiet -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {
$Uri = "http://$HostIP"
}
elseif (Test-NetConnection $HostIP -Port 443 -InformationLevel Quiet -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {
$Uri = "https://$HostIP"
}
elseif (Test-NetConnection $HostIP -InformationLevel Quiet -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) {
Write-PSFMessage -Level Warning -Message "$Using:PrintServer - $PrinterName - $PrinterPort - $HostIP - Responds to ping. No reachable web interface 80 / 443"
}
else {
Write-PSFMessage -Level Warning -Message "$Using:PrintServer - $PrinterName - $PrinterPort - $HostIP - Does not repond to ping. No reachable web interface 80 / 443"
}
}
# If we have a URI, add it to the pile.
if ($null -ne $Uri) {
[PSCustomObject]@{
Category = $Using:PrintServer
AltText = $PrinterName
URI = $Uri
Image = $Image
}
}
} -ModulesToImport PSFramework | Wait-RSJob | Receive-RSJob
}
catch {
Write-PSFMessage -Level Warning -Message "$PrintServer" -ErrorRecord $Error[0]
}
# } -Throttle 2 | Wait-RSJob | Receive-RSJob
}
# $Results | ConvertTo-Csv -NoTypeInformation | Add-Content -Path $OutFile
$Results | Export-Csv -Path $OutFile -NoTypeInformation -Append
[datetime]$EndTime = Get-Date
[timespan]$TimeSpan = $EndTime - $StartTime
Write-PSFMessage "--- Duration: $($TimeSpan.Minutes) minutes, $($TimeSpan.Seconds) seconds, $($TimeSpan.Milliseconds) milliseconds"
Write-PSFMessage "--- END $($MyInvocation.MyCommand) ---"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment