PowerShell/WMI Win32_PritnerDriver

You have to install the printer driver on the remote machine before you can use it.  Contact the printer vendo to learn how to do this for your printer. In all cases only Administrators can  add printers.

87 means that you have a bad parameter in your call.  It is likely caused by not haveing the driver available on the remote machine and installed correctly.  This is vendor specific.

"87" can also mean you have used the wrong arguments in the wrong order.  There is no way for s to tell from what you have posted.

February 7th, 2015 7:37am

Also note that you cannot remotely install a driver from a netowrk share due to security restrictions.

Free Windows Admin Tool Kit Click here and download it now
February 7th, 2015 7:40am

Here is how to do this assuming the driver can be installed remotely. (vendor specific)

# get the class instance with all provileges enabled
$driver=Get-WmiObject-list Win32_PrinterDriver -EnableAllPrivileges -Computer W8Test

$driverInfo = $driver.CreateInstance()
$driverInfo.Name = 'NewPrinter Model 2900'
$driverInfo.SupportedPlatform = 'Windows NT x86'
$driverInfo.Version = '3'

# the following must be local paths.  Cannot be network shares.
$driverInfo.DriverPath = 'C:\Scripts\NewPrinter.dll'
$driverInfo.Infname = 'C:\Scripts\NewPrinter.inf'

# add the driver
$driverInfo.AddPrinterDriver($driverinfo)

# returnCodes wil determine status

The DrievrInfo is filled out to specify the settings that choose the correct entry in the OEN inf file. 

Return code 87 is defined as:

The parameter is incorrect. May occur when the object is not correctly filled or when driver can not be found in the system.  Alternately, the name attribute may be different than the model specified in the .inf file. Or, there may be a missing backslash ("\") on a  PathFile attribute.

February 7th, 2015 8:00am

I did some more research and came to know that when calling AddPrinterDriver method we must use  SeLoadDriverPrivilege to load and unload a device driver. I could be able to find out gaining SeLoadDriverPrivilege access in vb but How can we set this privilege level in PS? 


The issue -87- is not a provilege issue. A privilege issue would give you a -5- returnCode.

You cannot enable privileges you don't have.  By default systems administrators have the SeLoadDriverPrivilege.  THe EnablePrivileges just says to use this privilege. You must be running elevated locally to use it or be accessing a remote system with or without elevation.

Free Windows Admin Tool Kit Click here and download it now
February 7th, 2015 8:23am

Yes Jrv, you are right in a sense that I must install the device driver to the remote computer before adding printer via PS script and the script works if I do so. 

There is no need to involve printer's vendor in this as I mentioned, the script works on my local computer return code 0. It also works to the remote computer if the driver is already installed to it returning code 87 i.e. adds the printer successfully to remote computer but still show return code 87.

I will share the script below, again please note that the script works to

  1. local computer with no driver installed return code 0.
  2. Remote computer with driver installed already but return code 87

The script fails to work to the remote computer where the driver is not installed but if I installed the driver manually it follow the above point no.2

## Declearing variables
$PrinterIP = "10.3.x.x"
$PrinterPort = "9100"
$PrinterPortName = "IP_" + $PrinterIP
$DriverName = "HP Color LaserJet 5550 PCL 6"
$DriverPath = "\\MyComp\HP 5550"
$DriverInf = "\\MyComp\HP 5550\hpc5550c.inf"
$PrinterCaption = "HP Color LaserJet 5550 PCL 6 - 3290"

## feeding target computers from txt file
$ComputerList = Get-Content "C:\Test.txt"

## Declearing Functions
Function CreatePrinterPort {
param ($PrinterIP, $PrinterPort, $PrinterPortName, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\root\cimv2:win32_tcpipPrinterPort"
$wmi.Scope.Options.Authentication = [System.Management.AuthenticationLevel]::PacketPrivacy
$Port = $wmi.createInstance()
$Port.name =  $PrinterPortName
$Port.hostAddress = $PrinterIP
$Port.portNumber = $PrinterPort
$Port.SNMPEnabled = $true
$Port.Protocol = 1
$Port.put()
}

Function InstallPrinterDriver {
Param ($DriverName, $DriverPath, $DriverInf, $ComputerName)
$wmi = [wmiclass]"\\$ComputerName\Root\cimv2:Win32_PrinterDriver"

$wmi.Scope.Options.Authentication = [System.Management.AuthenticationLevel]::PacketPrivacy
$wmi.Scope.options.enablePrivileges = $true
$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()
}
##Main Script
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
}

As I mentioned earlier,  for AddPrinterDriver method we must use SeLoadDriverPrivilege to load and unload a device driver. This can be seen from following the link below

https://msdn.microsoft.com/en-us/library/aa384771(v=vs.85).aspx

Finally, I can see the following script to again access to SeLoadDriverPrivilege in VB. 

objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege", True

What I fail to find out and need help is to do the above same in PowerShell. I strongly believe that if we could be able to find out the above line in PowerShell. The Script will work even if the driver is not manually installed to the remote computer because this script will grab the driver and installs it.


   
February 7th, 2015 8:28am

Please reread and try to understand my post.  YOu are insisting on something that just isn't correct and so cannot see the issue I raise.

You cannot gain provileges you don't hold.

If you have no access to teh driver you wil get an 87.

The paths have to be to the remote computer not the local computer.

Your issue is 87 which is "INCORECT PARAMETER".  Please read my post again.

Free Windows Admin Tool Kit Click here and download it now
February 7th, 2015 8:59am

Finally, I can see the following script to again access to SeLoadDriverPrivilege in VB. 

objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege", True

What I fail to find out and need help is to do the above same in PowerShell. I strongly believe that if we could be able to find out the above line in PowerShell. The Script will work even if the driver is not manually installed to the remote computer because this script will grab the driver and installs it.


   

This inPowerShell is:

$driver=Get-WmiObject-list Win32_PrinterDriver -EnableAllPrivileges -Computer W8Test

This adds ALL privileges to the session.  If this was not working you would get return code 5.


February 7th, 2015 9:02am

As I posted above you cannot use these paths:

$DriverPath = "\\MyComp\HP 5550"
$DriverInf = "\\MyComp\HP 5550\hpc5550c.inf

Paths must belocal and NOT on a network share.

This is the cause of your 87. Remote systems are not allowed access to a third computer due to the third hop security exclusion.

Copy the install folder to the remote system anduse local paths to see what I mean.

This is well documented and comes up constantly here. I am not making up any new ideas. Do some searching to see what I mean.

Free Windows Admin Tool Kit Click here and download it now
February 7th, 2015 9:06am

This works, the driver has to be on the local machine and will not be on the network share. If we put it on the network, 87 will return.

"Remote system are not allowed access to third computer due to the third hop security exclusion"

My understanding was to bypass the security in order to enable remote system retrieve driver from the printer server (third computer), this is why I was insisting enabling the privileges. But anyhow, this script would work by copying the driver file to the remote computer.

Quick Question

Can We bypass this security? I mean, I want to retrieve the driver from the print server and not the remote local computer?

Thanks for your replies buddy!!!!


 

  • Edited by Faraz_pk 21 hours 5 minutes ago
February 7th, 2015 9:26am

This works, the driver has to be on the local machine and will not be on the network share. If we put it on the network, 87 will return.

"Remote system are not allowed access to third computer due to the third hop security exclusion"

My understanding was to bypass the security in order to enable remote system retrieve driver from the printer server (third computer), this is why I was insisting enabling the privileges. But anyhow, this script would work by copying the driver file to the remote computer.

Thanks for your replies buddy!!!!


 

You cannot in any way alter the WMI settings to bypass Windows network security.  It is not possible without altering the whole netowrk.  If yuo don't believe me post your question in the Security Forum to get a more comprehensive answer.

Assume this:

You have a lock on you car door.  Can you alter WMI security so it will open your car door?  No.  They are two unrelated things.  Windows security is not related to WMI security.  WMI allows a privilege but you mus first have the right.  You do not have the right to remotely access a third system.

You can do this by using constrained endpoints in WinRM or through configuring CredSSP. 

The reason you are having this issue is because you are applying an obsolete solution to Windows Printing. The modern method of bypassing these issues is to install a print server service on one of your systems and spool the printer.  By doing that Windows will install all client drivers for you automatically and without admin intervention.

Free Windows Admin Tool Kit Click here and download it now
February 7th, 2015 9:33am

Hi Scripting Guys!!!

Background:

I am getting some troubles in adding a network printer via PS script on a remote computer. I am using three classes to accomplish this task i.e. Win32_tcpipPrinterPort (this is to setup IP port), Win32_PrinterDriver (to load the driver) and Win32_Printer(to create the printer)

Problem State:

After feeding in the variables to the required properties, when I call AddPrinterDriver function it returns 0 (success) for my local computer and returns 87 (which means form the documentation, The parameter is incorrect. May occur when the object is not correctly filled or when driver can not be found in the system. Alternately, the name attribute may be different than the model specified in the .inf file. Or, there may be a missing backslash ("\") on a PathFile attribute.)

Question:

I did some more research and came to know that when calling AddPrinterDriver method we must use  SeLoadDriverPrivilege to load and unload a device driver. I could be able to find out gaining SeLoadDriverPrivilege access in vb but How can we set this privilege level in PS? 

I have tried enabling all privileges in PS by writing this code, assuming that it will enable load driver privileges as well.

$wmi = [wmiclass]"\\$ComputerName\Root\cimv2:Win32_PrinterDriver"

$wmi.Scope.Options.EnablePrivileges = $true

But no luck  :(

Really appreciate your help guys

Faraz Amjad


  • Edited by Faraz_pk Saturday, February 07, 2015 7:51 AM
February 7th, 2015 10:50am

This works, the driver has to be on the local machine and will not be on the network share. If we put it on the network, 87 will return.

"Remote system are not allowed access to third computer due to the third hop security exclusion"

My understanding was to bypass the security in order to enable remote system retrieve driver from the printer server (third computer), this is why I was insisting enabling the privileges. But anyhow, this script would work by copying the driver file to the remote computer.

Quick Question

Can We bypass this security? I mean, I want to retrieve the driver from the print server and not the remote local computer?

Thanks for your replies buddy!!!!


 

  • Edited by Faraz_pk Saturday, February 07, 2015 2:26 PM
Free Windows Admin Tool Kit Click here and download it now
February 7th, 2015 5:23pm

Thanks for the explanation :) this surly helps.

Faraz Amjad

 
February 8th, 2015 2:21am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics