?
Solved

Powershell to Install Network Printer

Posted on 2014-11-05
14
Medium Priority
?
639 Views
Last Modified: 2014-11-07
Found this Powersell script on the internet for installing printers.  I'm running Powershell version 3 on Windows7 x64.   I get the attached error when attempting to run.  I thought it had something to do with the 64bit driver so I pointed the UNC path to the x64 directory, same error.  I also pointed the script to a local directory containing drivers, still same error.

####################################################
# Change these values to the appropriate values in your environment

$PrinterIP = "172.29.15.10"
$PrinterPort = "9100"
$PrinterPortName = "IP_" + $PrinterIP
$DriverName = "Lexmark 654de"
$DriverPath = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP"
$DriverInf = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP\LMACM540.inf"
$PrinterCaption = "Lexmark 654de"
####################################################

### ComputerList Option 1 ###
$ComputerList = @("ISH3LP")

### ComputerList Option 2 ###
# $ComputerList = @()
# Import-Csv "C:\Temp\ComputersThatNeedPrinters.csv" | `
# % {$ComputerList += $_.Computer}

Function CreatePrinterPort {
param ($PrinterIP, $PrinterPort, $PrinterPortName, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\root\cimv2:win32_tcpipPrinterPort"
$wmi.psbase.scope.options.enablePrivileges = $true
$Port = $wmi.createInstance()
$Port.name = $PrinterPortName
$Port.hostAddress = $PrinterIP
$Port.portNumber = $PrinterPort
$Port.SNMPEnabled = $false
$Port.Protocol = 1
$Port.put()
}

Function InstallPrinterDriver {
Param ($DriverName, $DriverPath, $DriverInf, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\Root\cimv2:Win32_PrinterDriver"
$wmi.psbase.scope.options.enablePrivileges = $true
$wmi.psbase.Scope.Options.Impersonation = `
[System.Management.ImpersonationLevel]::Impersonate
$Driver = $wmi.CreateInstance()
$Driver.Name = $DriverName
$Driver.DriverPath = $DriverPath
$Driver.InfName = $DriverInf
$wmi.AddPrinterDriver($Driver)
$wmi.Put()
}

Function CreatePrinter {
param ($PrinterCaption, $PrinterPortName, $DriverName, $ComputerName)
$wmi = ([WMIClass]"\\$ComputerName\Root\cimv2:Win32_Printer")
$Printer = $wmi.CreateInstance()
$Printer.Caption = $PrinterCaption
$Printer.DriverName = $DriverName
$Printer.PortName = $PrinterPortName
$Printer.DeviceID = $PrinterCaption
$Printer.Put()
}

foreach ($computer in $ComputerList) {
CreatePrinterPort -PrinterIP $PrinterIP -PrinterPort $PrinterPort `
-PrinterPortName $PrinterPortName -ComputerName $computer
InstallPrinterDriver -DriverName $DriverName -DriverPath `
$DriverPath -DriverInf $DriverInf -ComputerName $computer
CreatePrinter -PrinterPortName $PrinterPortName -DriverName `
$DriverName -PrinterCaption $PrinterCaption -ComputerName $computer
}

Powershell-Error.JPG
0
Comment
Question by:ats2012
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 7
14 Comments
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426652
You are running this script with administrative privileges correct?
0
 

Author Comment

by:ats2012
ID: 40426662
Yes, I am.  I'm already a domain admin but I am running Powershell as administrator.  I keep thinking it has something to do with how the printer driver is handled.  The UNC Path to the driver is specified but the printer I'm trying to install is an enterprise level Lexmark machine that requires you to run the setup program.  Not sure I can do this with this script.  

Thoughts?
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426675
From the naming of the driver, you may be trying to install an incompatible driver. If your installing on a 64-bit Win7 the driver should not be Win_2kXP.

Do you have the 64bit drivers for it?
0
Ready to trade in that old firewall?

Whether you need to trade-up to a shiny new Firebox or just ready to upgrade from whatever appliance you're using now, WatchGuard has the right appliance for you! Find your perfect Firebox today with appliance sizing tool!

 

Author Comment

by:ats2012
ID: 40426738
I should have specified that I tested that.  The UNC directory path for the 64bit driver was tested  as in:

$DriverPath = ...\drivers\Print\Win_2kXP\x64
$DriverInf = ...\drivers\Print\Win_2kXP\x64\ntprint.inf

I tested this on a 32bit machine as well (with the 32bit instructions) and still get the exact same error.

Would the remote machines need to be running the latest .Net Framework?
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426795
that could be a possibility...

Whats strange is that it doesnt seem to have any issue with the PrinterPort and PrinterDriver, it only throws an error when trying to "Put" the printer. Maybe it needs an updated WMI framework? try updating one of the workstations to WMF 4.0 and see if it succeeds after that?
0
 

Author Comment

by:ats2012
ID: 40426923
It's doesn't appear to be a WMF issue after all.  I updated the 32bit machine to WMF 4.5 and reran the script and still same issue.  In fact I tested this on my machine earlier and I'm running 4.5 as well and it didn't work either.
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40426934
do you have another printer to try? That would definitely narrow it down to whether you have to run the setup application for the Lexmark printer.
0
 

Author Comment

by:ats2012
ID: 40427228
I tried this with the most basic HP universal driver for a simple laserjet printer and it still didn't work.  It continues to fail with the same error.  Examining the error and researching via google it looks like one of key strings aren't getting passed into the function, hence the "Exception calling 'Put' with '0' argument(s)."    

That said I don't know what I should modify regarding $PrinterPort, $DriverPath, $DriverInf
0
 
LVL 16

Expert Comment

by:Joshua Grantom
ID: 40428357
Since you have spaces in the DriverName and PrinterCaption, try this below. I wrapped the variables in parentheses so it will read them as a single string. Let me know

####################################################
# Change these values to the appropriate values in your environment

$PrinterIP = "172.29.15.10"
$PrinterPort = "9100"
$PrinterPortName = "IP_" + $PrinterIP
$DriverName = "Lexmark 654de"
$DriverPath = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP"
$DriverInf = "\\UNC Path\apps\Printers\Lexmark\654de\Admin\drivers\Print\Win_2kXP\LMACM540.inf"
$PrinterCaption = "Lexmark 654de"
####################################################

### ComputerList Option 1 ###
$ComputerList = @("ISH3LP")

### ComputerList Option 2 ###
# $ComputerList = @()
# Import-Csv "C:\Temp\ComputersThatNeedPrinters.csv" | `
# % {$ComputerList += $_.Computer}

Function CreatePrinterPort {
param ($PrinterIP, $PrinterPort, $PrinterPortName, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\root\cimv2:win32_tcpipPrinterPort"
$wmi.psbase.scope.options.enablePrivileges = $true
$Port = $wmi.createInstance()
$Port.name = $PrinterPortName
$Port.hostAddress = $PrinterIP
$Port.portNumber = $PrinterPort
$Port.SNMPEnabled = $false
$Port.Protocol = 1
$Port.put()
}

Function InstallPrinterDriver {
Param ($DriverName, $DriverPath, $DriverInf, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\Root\cimv2:Win32_PrinterDriver"
$wmi.psbase.scope.options.enablePrivileges = $true
$wmi.psbase.Scope.Options.Impersonation = `
[System.Management.ImpersonationLevel]::Impersonate
$Driver = $wmi.CreateInstance()
$Driver.Name = "$DriverName"
$Driver.DriverPath = $DriverPath
$Driver.InfName = $DriverInf
$wmi.AddPrinterDriver($Driver)
$wmi.Put()
}

Function CreatePrinter {
param ($PrinterCaption, $PrinterPortName, $DriverName, $ComputerName)
$wmi = ([WMIClass]"\\$ComputerName\Root\cimv2:Win32_Printer")
$Printer = $wmi.CreateInstance()
$Printer.Caption = "$PrinterCaption"
$Printer.DriverName = "$DriverName"
$Printer.PortName = $PrinterPortName
$Printer.DeviceID = $PrinterCaption
$Printer.Put()
}

foreach ($computer in $ComputerList) {
CreatePrinterPort -PrinterIP $PrinterIP -PrinterPort $PrinterPort `
-PrinterPortName $PrinterPortName -ComputerName $computer
InstallPrinterDriver -DriverName $DriverName -DriverPath `
$DriverPath -DriverInf $DriverInf -ComputerName $computer
CreatePrinter -PrinterPortName $PrinterPortName -DriverName `
"$DriverName" -PrinterCaption "$PrinterCaption" -ComputerName $computer
}

Open in new window

0
 

Author Comment

by:ats2012
ID: 40429038
Still fails with the same error.  Have you tested this script in your environment?  I still think that for some reason the string values (UNC Path to drivers) aren't being stored and passed to the function properly.  My only experience with this is simply setting those as constants, not calling a UNC path.  Seems pretty straight-forward though.  I've reached out to the author of the script but haven't heard anything.
0
 
LVL 16

Accepted Solution

by:
Joshua Grantom earned 2000 total points
ID: 40429086
I actually think it is the driver name. When you open that INF file does it actually say "Lexmark 654de" or is it "Lexmark X654de" or another long name? It must match what is in the driver info not what you want it to be called.
0
 

Author Comment

by:ats2012
ID: 40429164
OK, it sorta works.  The driver name was the issue.  It is named "Lexmark X654de".  However, the script only works on my machine.  It still fails when trying to install the printer on a remote computer which is kinda the point of this whole exercise.  Thought is that it's because I'm running PS as administrator on my machine but remote machines the script wouldn't run with elevated permissions.  How would a person get this script to run with elevated permissions on remote systems?  Also the fact the I have enabled my machine to run unsigned scripts.
0
 
LVL 16

Assisted Solution

by:Joshua Grantom
Joshua Grantom earned 2000 total points
ID: 40429169
If you run it with a Domain Admin account it should install. If it still does not let you, you may have to create a gpo to allow Remote Management and Remote access to WMI

http://www.briantist.com/how-to/powershell-remoting-group-policy/

http://community.spiceworks.com/how_to/show/17452-group-policy-to-allow-wmi-access-to-remote-machine
0
 

Author Closing Comment

by:ats2012
ID: 40429282
Thanks, this working now.  I indeed had to go in and allow remote management with WMI in group policy.  This script is saving us a ton of work having to remote to a machine and install a printer.
0

Featured Post

Bringing Advanced Authentication to the SMB Market

WatchGuard announces the acquisition of advanced authentication provider, Datablink, with one mission – to bring secure authentication to SMB, mid-market, and distributed enterprises with a cloud-based solution, ideal for resale via their established channel & MSSP community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Recently we ran in to an issue while running some SQL jobs where we were trying to process the cubes.  We got an error saying failure stating 'NT SERVICE\SQLSERVERAGENT does not have access to Analysis Services. So this is a way to automate that wit…
In this post we will be converting StringData saved within a text file into a hash table. This can be further used in a PowerShell script for replacing settings that are dynamic in nature from environment to environment.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question