Pages

Showing posts with label Printers. Show all posts
Showing posts with label Printers. Show all posts

Friday, October 12, 2012

Pharos Mobile Print: Print server Firewall

Pharos was nice enough to let us Demo Pharos MobilePrint and since there isn't much out there on Pharos Mobile Print I thought I'd post a few small things that might help some of you. I'm using Pharos MobilePrint version 1.2.

If your sending email to Pharos Mobile Print it has to verify your email address. From the documentation MobilePrint and Uniprint Integration located on the Pharos install media.
MobilePrint first checks if the user’s email address is in its internal cache (if the user has printed before their address will already be in the cache). If it is not found MobilePrint then checks in the Pharos Database.
If you are sure that the email account is correctly set on the user account. Either from Pharos Administrator or the DB.

SELECT  [user_id]      
,[active]      
,[id]      
,[email]  
FROM [pharos].[dbo].[users]  
where id like 'username1'

If its set and the service is still asking your accounts to register their email address instead it means the Pharos MobilePrint Server for what ever reason can't connect to the Pharos MobilePrint Auth Service. Check that the firewall port is open on the print server. Port 808. However if you have this issue refer to the Mobile Print Installation and Configuration Guide and check all the ports because its likely you have more than just this one firewall port issue.


The Pharos MobilePrint Log, which i set to “c:\PharosLogs” will display the following.

[2012/10/11 15:10:24 PDE8 T018 d MP_ConsignmentTracker] 84e2ba58-9023-561d-af42-3ee75a505f29 Indexing email from 'test1@test.nku.edu'
[2012/10/11 15:10:24 PDE8 T05F d MP_ConsignmentTracker] 84e2ba58-9023-561d-af42-3ee75a505f29 Starting Workflow for sender 'test1@test.nku.edu'
[2012/10/11 15:10:24 PDE8 T05F d MP_ConsignmentTracker] 84e2ba58-9023-561d-af42-3ee75a505f29 Sender email address not in cache
[2012/10/11 15:10:45 PDE8 T025 w MP_WorkflowService] An attempt was made to resume a Workflow Instances that has either completed or been deleted. This request will now be ignored.
[2012/10/11 15:10:45 PDE8 T026 e MP_WorkflowServiceExtension] An error occurred while attempting to process a response on the 'authentication' queue for message '465738ac-0a35-5c90-bfe2-b038a51f7dbd'.
[2012/10/11 15:10:45 PDE8 T026 e MP_WorkflowServiceExtension] Exception: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Type: CommunicationObjectFaultedException
StackTrace:   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelFactory.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelFactory.TypedServiceChannelFactory`1.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.System.IDisposable.Dispose()
   at MobilePrint.Service.Workflow.Extensions.AuthenticationManager.<.ctor>b__0(AuthenticateResponse response)
[2012/10/11 15:10:45 PDE8 T026 e MP_RestInterface] An unhandled error occurred while processing a REST command.
[2012/10/11 15:10:45 PDE8 T026 e MP_RestInterface] Exception: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Type: CommunicationObjectFaultedException
StackTrace:   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelFactory.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelFactory.TypedServiceChannelFactory`1.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.System.IDisposable.Dispose()
   at MobilePrint.Service.Workflow.Extensions.AuthenticationManager.<.ctor>b__0(AuthenticateResponse response)
   at MobilePrint.Core.Workflow.Library.QueueManager.<>c__DisplayClass1`1.b__0(BaseQueueResponse o)
   at System.Reactive.AnonymousObserver`1.Next(T value)
   at System.Reactive.AbstractObserver`1.OnNext(T value)
   at System.Reactive.Subjects.Subject`1.OnNext(T value)
   at MobilePrint.Core.Workflow.Library.QueueManager.PushResponse(String queueName, BaseQueueResponse packet)
   at MobilePrint.Service.Workflow.RestResource.WebResource.PushQueue(String queueName, HttpRequestMessage request)
[2012/10/11 15:10:45 PDE8 T025 w MP_WorkflowService] An attempt was made to resume a Workflow Instances that has either completed or been deleted. This request will now be ignored.
[2012/10/11 15:10:45 PDE8 T026 e MP_WorkflowServiceExtension] An error occurred while attempting to process a response on the 'authentication' queue for message 'e71cfa3f-0d71-52b2-a538-9ab27ed45271'.
[2012/10/11 15:10:45 PDE8 T026 e MP_WorkflowServiceExtension] Exception: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
Type: CommunicationObjectFaultedException


Monday, April 25, 2011

Microsoft Word printing from command line

All Testing was done using Office 2010 64bit.

Make Sure background printing is enabled in word. On the Tools menu, click Options, and then click the Print tab. Under Printing options, ensure that Background printing check box is checked.

cd C:\Program Files\Microsoft Office\Office14
winword "c:\file.BAT" /q /n /mFilePrintDefault /mFileExit

Change to the folder of your office installation.
Command Line parameters to pass to Word.

/q - Start Word without splash screen.
/n - Start Word without a document being open.
/m(MacroName) - Start Word and run the named macro. The windows macro commands FilePrintDefault and FileExit do exactly what they say. Also there is no space between the /m and the macro name.

To get a list of macros open word, on the right hand side of the View tab of the ribbon bar there s a Macros button. Click it and change the "Macros In" dropdown box to Word Commands.
Word 2010 Macros
If you need more control you can modifiy a Macro with the printing settings you need.

Create macro for the globe settings.


Sub FilePrintToPrinter1()
    ActivePrinter = "Pritner1"
    Application.PrintOut _
        FileName:="", _
        Range:=wdPrintAllDocument, _
        Item:=wdPrintDocumentWithMarkup, _
        Copies:=1, _
        Pages:="", _
        PageType:=wdPrintAllPages, _
        Collate:=True, _
        Background:=True, _
        PrintToFile:=False, _
        PrintZoomColumn:=0, _
        PrintZoomRow:=0, _
        PrintZoomPaperWidth:=0, _
        PrintZoomPaperHeight:=0
    Application.WindowState = wdWindowStateMaximize
End Sub


Now calling the this macro would be.
winword "c:\file.BAT" /q /n /mFilePrintToPrinter1 /mFileExit

Links
http://www.robvanderwoude.com/printfiles.php
http://www.autohotkey.com/forum/topic10600.html

Thursday, April 14, 2011

Printer Port Error "Cannot create a file when that file already exists"

If you are getting "Cannot create a file when that file already exists" when trying to create a printer port on windows by a specific name try a reboot. I had tried to find the port in WMI and the Registry thinking it got corrupted during an install but no luck finding it. Instead just a simple restart of the Machine solved it. (services restart of print spooler did not)

When I tried to create printer port GUI wizard and it would say complete but then it would problem a message box saying "Cannot create a file when that file already exists."

Posting this because I didn't find any results from Google on the issue. Ran into it using my powershell script to add printers.



Friday, April 8, 2011

Powershell API for Windows 2008 Print Queues and Ports

After you use this let me know what you think, this was one of projects I looked for and couldn't find before I started to write it.

Lately I've been working on migrating a Windows 2008 Print Server from from 32 bit to Windows 2008 R2 64bit. During this I've been cleaning up unused printers and ports as my other post suggested. Considering this print sever had nearly 500 printers installed worked on automating the process. Using Powershell I noticed many people complaining of poor integration of Powershell for Printer support. While I agree there should of been better built-in functions I was able to write every feature I wanted once I figured out how.

There where many posts online but none of them seemed to handle any issues that arrised. For example if you try and create a printer using [WMICLASS]"\\$ComputerName\ROOT\cimv2:Win32_Printer").createInstance() and call .Put() you may get the following error.


Exception calling "Put" with "0" argument(s): "Generic failure "
At C:\Users\towlesd\Documents\My Dropbox\PrinterInformationfor2008.ps1:319 char:24
+     [void] $newprinter.Put <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

This is caused because one of the pramaters you are trying to use isn't valid. It doesn't say that but thats what it means. Frustrating to say the least. The cause of this for me it was the print driver didn't exist on the server. Because of this my InstallPrinters function first checks that all printers and ports first exist on the remote server. Little things like this make the entire process possible.

You really need to break down how you want to use this script it self as there are alot of useful functions depending on what your working on. In all the script can gather all the printer information about a given server; Its printers, ports and drivers and export that to a csv-file. It can try to ping all the ports and detect which are offline or bad DNS entires.

Here are most of the Powershell functions

  • Create Printer
  • Create Port
  • Install Array of Printers
  • Get Installed Drivers
  • Get Install Ports
  • Match printers with their ports in a csv-file
  • Create csv files for any of this information
  • migrate printers from one serevr to another


Without further delay.
###########################
#
#  Purpose: Printer API for Managing and migrating Printers
#  Created By: Chris Towles
#  Website: http://www.ChrisTowles.com
#  When: 04/08/2011
#  Version: 1.0
#  Change List
#
###########################

function Ping() {
 param ([string] $ComputerName)
 [bool] $Pingable = $false
  
 try {
  $ping = new-object System.Net.NetworkInformation.Ping
  $Reply = $ping.send($ComputerName, 1000)
  if ($Reply.status –eq “Success”) {
   $Pingable = $true
  }
 } 
 catch { return "DNS Issue" }
 
 if ($Pingable) { return “Online” }
 else { return "Offline" }
}
function Get-Nslookup() {
 param ([string] $Name)
 
 $DNSInfo = "" | select "DNSName", "DNS_IP"
 $DNSInfo.DNSName = $null
 $DNSInfo.DNS_IP = $null
 
 try {
  #http://powershellmasters.blogspot.com/2009/04/nslookup-and-powershell.html
  $cmd = "nslookup " + $Name + " " + $ns + " 2>&1" 
  $result = Invoke-Expression ($cmd) -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
  
  $DNSInfo.DNSName = $result.SyncRoot[3]
  $DNSInfo.DNSName = $DNSInfo.DNSName.Split(":")[1]
  $DNSInfo.DNSName = $DNSInfo.DNSName.Trim()
  
  $DNSInfo.DNS_IP = $result.SyncRoot[4]
  $DNSInfo.DNS_IP = $DNSInfo.DNS_IP.Split(":")[1]
  $DNSInfo.DNS_IP = $DNSInfo.DNS_IP.Trim()
 }
 catch{
  $DNSInfo.DNSName = $null
  $DNSInfo.DNS_IP = $null
 }
 return  $DNSInfo
}
Function Get-Printers( ) {
 param ([string] $ComputerName  = ".") #sets "." as the default param if none is supplied

 Write-Host "Connecting to $ComputerName by WMI to gather printer information."
 Write-Host " Warning this may take a few minutes depending how many printers there are." -ForegroundColor Red
 
 $colItems = get-wmiobject -class "Win32_Printer" -namespace "root\CIMV2" -computername $ComputerName
 $count = $colItems.Count
 $pos = 0
 Write-Host "Found $count printers. Getting details on each now."
 $Printers = @()

 foreach ($objItem in $colItems) {
  write-progress -activity "Getting Information on each printer." -status "% Complete" -percentcomplete (($pos++/$count)*100);
  
  #creating a new object called $PrinterInfo 
     $PrinterInfo = New-Object psobject  

     $PrinterInfo | Add-Member NoteProperty Caption $objItem.Caption
     $PrinterInfo | Add-Member NoteProperty Comment  $objItem.Comment
     $PrinterInfo | Add-Member NoteProperty "Default"  $objItem.Default
     $PrinterInfo | Add-Member NoteProperty "DriverName" $objItem.DriverName
     $PrinterInfo | Add-Member NoteProperty "Local" $objItem.Local
     $PrinterInfo | Add-Member NoteProperty "Name" $objItem.Name
     $PrinterInfo | Add-Member NoteProperty "PortName" $objItem.PortName
     $PrinterInfo | Add-Member NoteProperty "PrinterStatus" $objItem.PrinterStatus
     $PrinterInfo | Add-Member NoteProperty "PrintProcessor" $objItem.PrintProcessor
     $PrinterInfo | Add-Member NoteProperty "Shared" $objItem.Shared
     $PrinterInfo | Add-Member NoteProperty "ShareName" $objItem.ShareName
     $PrinterInfo | Add-Member NoteProperty "Status" $objItem.Status
     $PrinterInfo | Add-Member NoteProperty "SystemName" $objItem.SystemName
     $PrinterInfo | Add-Member NoteProperty "WorkOffline" $objItem.WorkOffline
     
  $Printers += $PrinterInfo
 }
 write-progress -activity "Getting Information on each Port." -status "% Complete:" -percentcomplete 100 -Completed;
 return $Printers
}
function Get-PortInfo () {
 param ([string] $ComputerName  = ".",
   [bool]$CheckPorts = $true) #sets "." as the default param if none is supplied
  
 Write-Host "Connecting to $ComputerName by WMI to gather printer port information."
 Write-Host " Warning this may take a few minutes because its pinging each port." -ForegroundColor Red

 $colItems = get-wmiobject -class "Win32_TCPIPPrinterPort" -namespace "root\CIMV2" -computername $ComputerName
 $count = $colItems.Count
 $pos = 0
 Write-Host "Found $count printer ports. Getting details on each now."
 
 
 $Ports = @()
 
 foreach ($objItem in $colItems) {
  write-progress -activity "Getting Information on each Printer Port. " -status "% Complete:" -percentcomplete (($pos++/$count)*100);
  
  $PortInfo = New-Object psobject  
  $PortInfo | Add-Member NoteProperty "ByteCount" $objItem.ByteCount
  $PortInfo | Add-Member NoteProperty "HostAddress" $objItem.HostAddress
  $PortInfo | Add-Member NoteProperty "HostAddressLink" ("http://" + $objItem.HostAddress + "/" )
  $PortInfo | Add-Member NoteProperty "Name" $objItem.Name
  $PortInfo | Add-Member NoteProperty "PortNumber" $objItem.PortNumber
  $PortInfo | Add-Member NoteProperty "Protocol" $objItem.Protocol
  $PortInfo | Add-Member NoteProperty "Queue" $objItem.Queue
  $PortInfo | Add-Member NoteProperty "SNMPCommunity" $objItem.SNMPCommunity
  $PortInfo | Add-Member NoteProperty "SNMPDevIndex" $objItem.SNMPDevIndex
  $PortInfo | Add-Member NoteProperty "SNMPEnabled" $objItem.SNMPEnabled
  
  if($CheckPorts) {
   $pingstring = Ping -ComputerName $objItem.HostAddress
   $PortInfo | Add-Member NoteProperty "Ping" $pingstring
  
   $DNSInfo = get-nslookup -Name $objItem.HostAddress
   $PortInfo | Add-Member NoteProperty "DNSName" $DNSInfo.DNSName
   $PortInfo | Add-Member NoteProperty "DNS_IP" $DNSInfo.DNS_IP
  }
  
  $Ports += $PortInfo
 }
 write-progress -activity "Getting Information on each Port." -status "% Complete:" -percentcomplete 100 -Completed;
 return $Ports
}
function Get-PrintersWithPort {
 param ( [array] $Printers,
   [array] $Ports  )

 $count = $Printers.Count
 $pos = 0
 $PrinterWithPortInfo = @()
 Foreach($Printer in $Printers) {
 
  write-progress -activity "Sorting Printers to their matching Ports." -status "% Complete" -percentcomplete (($pos++/$count)*100);
  $Port = $Ports | where {$_.Name -like ($Printer.PortName) }
  if($Port -ne $null) {
   $properties = $Port | Get-Member -MemberType NoteProperty
   
   foreach ($member in $properties )
   {
    $PropName = $member.Name
    $PropValue = $Port | Get-Member -MemberType NoteProperty ($member.Name) 
    
    $PropValue = $PropValue.ToString().Split("=")[1]
    
    if($PropValue -match "null")
    { $PropValue = ""}
    
    $Printer | Add-Member NoteProperty ("Port_" + $Propname) $PropValue
   }
   $PrinterWithPortInfo += $Printer
  }
 }
 write-progress -activity "Sorting Printers to their matching Ports. Phase 3 of 3." -status "% Complete" -percentcomplete 100 -Completed;
 return $PrinterWithPortInfo
}
function Get-PortsWithPrinterAndOnline {
 param ( [array] $Printers , 
   [array] $Ports  )
 
 $PortsWithPrinterAndOnline = @()
 Foreach($Printer in $Printers) {
   $Port = $Ports | where { $_.Name -like ($Printer.PortName)  }
   if(($Port -ne $null ) -and ($Port.Ping -like "Online")) {
    $PortsWithPrinterAndOnline += $Port
   }
 }
 return $PortsWithPrinterAndOnline
}
function Get-PortsWithoutPrinters {
 param ( [array] $Printers , 
   [array] $Ports  )
 
 $PortsWithoutPrinters  = @()
  
 Foreach($Port in $Ports) {  
   $Printer = $Printers | where { $_.PortName -like ($Port.Name) }
   if(($Printer -eq $null ) ) { #-and ($Port.Ping -like "Online")) {
    #Port Has no Printer
    $PortsWithoutPrinters += $Port
   }
 }
 $PortsWithoutPrinters = $PortsWithoutPrinters | sort -Property "Name"
 
 return $PortsWithoutPrinters
}
function Get-PrintersWithPortsOffLine {
 param ( [array] $Printers,
   [array] $Ports  )
 
 $PrinterWithPortOffLine = @()
 Foreach($Printer in $Printers) {
   $Port = $Ports | where { $_.Name -like ($Printer.PortName)  }
   if(($Port -ne $null ) -and ($Port.Ping -inotlike "Online")) {
    $PrinterWithPortOffLine += $Printer
   }
 }
 return $PrinterWithPortOffLine
}
function Get-PharosQueuesWithWInprintProcessor {
 param ( [array] $Printers )
 $WinPrint = @()
 Foreach($Printer in $Printers) {
   
  if($Printer.PrintProcessor -ine "WinPrint" -and $Printer.Name -like '*Q') {
   $WinPrint += $Printer
  }
 }
 return $WinPrint | sort "Name" 
}
Function Get-InstalledPrinterDrivers () {
 param ( [string] $ComputerName = "." )
  
 $colItems = get-wmiobject -class "Win32_PrinterDriver " -namespace "root\CIMV2" -computername $ComputerName

 $PrintDrivers = @()
 foreach ($objItem in $colItems) {
  #creating a new object called $PrinterInfo 
     $Driver = New-Object psobject 
     $Driver | Add-Member NoteProperty Name $objItem.Name.Split(",")[0]
  $Driver | Add-Member NoteProperty Chip $objItem.Name.Split(",")[2]
  
  $PrintDrivers += $Driver
 }
 
 return $PrintDrivers
}
function Create-PrinterPort {
 param ( [string] $ComputerName  = ".", #sets "." as the default param if none is supplied
  [string] $PortName ,
  [string] $DNSName ,
  [int] $Protocol = 1,  #default of 1 for RAW
  [string]$Queue = $null,
  [string]$PortNumber =  "9100",
  [bool] $SNMPEnabled ,
  [string] $SNMPCommunity = $null)
 
 $newPort = ([WMICLASS]"\\$ComputerName\ROOT\cimv2:Win32_TCPIPPrinterPort").createInstance() 
 $newport.Name = $PortName
 $newport.HostAddress= $DNSName #sometimes IP Address
 $newport.Protocol= $Protocol 
 #Protocols possiable
 #1 = RAW, Printing directly to a device or print server.
 #2 = LPR, Legacy protocol, which is eventually replaced by RAW.
 
 if ($Protocol -eq 2 ) {
  $newport.Queue = $Queue 
 }
 
 $newPort.PortNumber = "9100"
 $newport.SNMPEnabled = $SNMPEnabled
 if( $SNMPCommunity -ne $null ) {
  $newport.SNMPCommunity = $SNMPCommunity
 }
 
 Write-Host "Creating Port $PortName" -foregroundcolor "darkgreen"
 [void] $newport.Put()
 
}
function Create-CSVOutputFile {
 param ( [array] $CustomObject , 
   [String] $filename  )

 #writing file to 
 Write-Host $filename
 $CustomObject  | Sort-Object "Name" | Export-Csv $filename

 #removes the top line as it just has #TYPE System.Management.Automation.PSCustomObject in it.
 get-content $filename |  select -Skip 1 |  set-content "$filename-temp"
 
 if (Test-Path "$filename-temp") {
  move  "$filename-temp" $filename -Force 
 }
 else {
  Remove-Item "$filename"
  Write-Host "$filename was deleted because nothing was in it." 
 } 
}
function Create-Printer {
  Param (
  [string]$ComputerName = ".",
     [string]$PrinterName,
     [string]$DriverName,
     [string]$Location,
  [string]$ShareName,
  [String]$PortName,
     [string]$Comment
    )
   
 $newprinter = ([WMICLASS]"\\$ComputerName\ROOT\cimv2:Win32_Printer").createInstance() 
 $newprinter.Drivername = $DriverName
 $newprinter.PortName = $PortName
 $newprinter.Shared = $true
 $newprinter.Sharename = $ShareName
 $newprinter.Location = $Location
 $newprinter.Comment = $Comment
 $newprinter.DeviceID = $PrinterName
 Write-Host "Creating Printer $PrinterName" -foregroundcolor "darkgreen"
 [void] $newprinter.Put()
 
 #Exception calling "Put" with "0" argument(s): "Generic failure "
 # This Means their is something wrong with a paramter, Most likely its the driver name
}
function Install-PrinterPorts {
 param ( [string] $ComputerName , 
   [array] $Ports  )

 Write-Host "Creating the following " $Ports.Count " printer ports on " $ComputerName
 foreach ($newport in $Ports) {
  
  [bool] $SNMPEnabled = $false
  if( $newport.SNMPEnabled -eq $true ) {
   $SNMPEnabled = $true
  }
  
  Create-PrinterPort -ComputerName $ComputerName `
   -DNSName $newport.HostAddress.ToUpper() `
   -PortName $newport.Name.ToUpper() `
   -PortNumber $newport.PortNumber `
   -Protocol $newport.Protocol `
   -SNMPEnabled $SNMPEnabled `
   -SNMPCommunity $newport.SNMPCommunity `
   -Queue $newport.Queue
 }
}
Function Install-Printers {
 param (
  [string] $ComputerName = ".",
  [array] $PrintersToCreate,
  [array] $PortsToCreate,
  [bool] $TestDriversAndPortsOnly = $false
 )
 $PrintersToInstall = @()
 $MissingPort = @()
 $MissingDriver = @()
 
 #Create the Remote Ports
 Install-PrinterPorts  -ComputerName $ComputerName -Ports $PortsToCreate
 
 #Check Print server for what ports and Printers are installed.
 $InstalledDrivers = Get-InstalledPrinterDrivers -ComputerName $ComputerName 
 $InstalledPorts = Get-PortInfo -ComputerName $ComputerName -CheckPorts $false
 
 #I wished to have all the names in uppercase only.
 $Printer.PortName = $Printer.PortName.ToUpper() 
 
 foreach($Printer in $Printers)
 {
  $DriverFound = $InstalledDrivers | where {$_.Name -eq $Printer.DriverName} 
  $PortFound = $InstalledPorts | where {$_.Name -eq $Printer.PortName} 
  
  if($DriverFound -eq $null) {
   #Write-Host ("The Print Driver isn't installed on the Destination Server" + $Printer.DriverName )
   $MissingDriver += $Printer.DriverName
  }
  elseif($PortFound -eq $null) {
   #Write-Host ("The Printer Port " + $Printer.Port_Name + " didn't existon the destination Server" + $Printer.DriverName )
   $MissingPort += $Printer.PortName
  }
  else{
   $PrintersToInstall += $Printer
  }
 }
 
 Write-Host ""
 Write-Host ("The following printer drivers are missing from " + $ComputerName )
 $MissingDriver | Sort | Get-Unique | ft -AutoSize
 
 Write-Host ""
 Write-Host ("The following printer port didn't exist on " + $ComputerName )
 $MissingPort | Sort | Get-Unique | ft -AutoSize
 
 Write-Host ""
 if ( $TestDriversAndPortsOnly -eq $false ) {
  foreach($Printer in $PrintersToInstall) {
 
   Create-Printer `
    -PrinterName  $Printer.Name  `
    -ComputerName $DestinationHost `
    -DriverName   $Printer.DriverName `
    -PortName    $Printer.PortName.ToUpper() `
     -ShareName    $Printer.ShareName  `
    -Comment    $Printer.Comment `
    -Location    "" 
  }
 }
}

#################################################################################
#        MAIN           #
#################################################################################
Clear
$ComputerName = Read-Host "Enter the Print Server you wish to gather data about."
#$DestinationHost = "dvprintserv1"

[bool] $QueryData = $true
[bool] $OutputFiles = $true

if( $QueryData ) {
 #Gets all the information
 $Printers = @() | Get-Printers -ComputerName $ComputerName
 $Ports  = @() | Get-PortInfo -ComputerName $ComputerName
 $PrinterWithPortInfo = @() | Get-PrintersWithPort -Printers $Printers -Ports  $Ports
 $PortsWithoutPrinters = @() | Get-PortsWithoutPrinters -Printers $Printers -Ports $Ports
 $PrintersWithOffLinePort =   @() | Get-PrintersWithPortsOffLine -Printers $Printers -Ports  $Ports
}
#Used to migrate printers from one server to another.
#Install-Printers -ComputerName $DestinationHost -PrintersToCreate $Printers -Ports $Ports #-TestDriversAndPortsOnly $true

if($OutputFiles) {

 #Formated File Names
 $d = get-date
 $FileTime = "" + $d.Year + "-" + ("{0:D2}" -f $d.Month) + "-" + ("{0:D2}" -f $d.Day) + "-" + ("{0:D2}" -f $d.Hour ) + ("{0:D2}" -f $d.Minute)
 $PortsFilename = [String]::Format( "{0}_Ports_{1}.csv", $ComputerName, $FileTime )
 $PrintersFilename = [String]::Format( "{0}_Printers_{1}.csv", $ComputerName, $FileTime )
 $PrintersWithPortFilename = [String]::Format( "{0}_PrintersWithPort_{1}.csv", $ComputerName, $FileTime )
 $PortsWithoutPrintersFilename = [String]::Format( "{0}_PortsWithoutPrinters_{1}.csv", $ComputerName, $FileTime )
 $PrintersWithOffLinePortFileName = [String]::Format( "{0}_PrintersWithOffLinePort_{1}.csv", $ComputerName, $FileTime )

 #writing file
 [Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
 Write-Host ("Saving CSV Files at " + [Environment]::CurrentDirectory + " Named the following.")
 
 Create-CSVOutputFile $Printers -filename $PrintersFilename
 Create-CSVOutputFile $Ports -filename $PortsFilename
 Create-CSVOutputFile $PrinterWithPortInfo  -filename $PrintersWithPortFilename
 Create-CSVOutputFile $PortsWithoutPrinters  -filename $PortsWithoutPrintersFilename
 Create-CSVOutputFile $PrintersWithOffLinePort -filename $PrintersWithOffLinePortFileName
}
Here an example of some output.
Connecting to dvprintserv1 by WMI to gather printer information.
Warning this may take a few minutes depending how many printers there are.
Found 123 printers. Getting details on each now.
Connecting to dvprintserv1 by WMI to gather printer port information.
 Warning this may take a few minutes because its pinging each port.
Found 355 printer ports. Getting details on each now.
Saving CSV Files at C:\Users\towlesd\Documents Named the following.
dvprintserv1_Printers_2011-04-08-1211.csv
dvprintserv1_Ports_2011-04-08-1211.csv
dvprintserv1_PrintersWithPort_2011-04-08-1211.csv
dvprintserv1_PortsWithoutPrinters_2011-04-08-1211.csv
dvprintserv1_PrintersWithOffLinePort_2011-04-08-1211.csv