jeudi 29 mai 2014

Windows 7 - supprimer Win7 pilote d'imprimante réseau à distance à l'aide de WMI - Stack Overflow


I need help with deleting network printer driver remotely on a Win7 client using a vbscript with an account having administrator privilegies on the computer in question. The problem is that I can't delete the connected printer the user have connected. Everything else seems to work. Below is the code for the script.


The script does several things, but the ultimate goal is to fysically remove the printer-drivers. The current version of the script fails since the driver files are in use. The script contains code to avoid special printers. It also stops and starts the print spooler.


intSleep        = 4000
strService = " 'Spooler' "
strComputer = "<remote computer name>"
Set fsobj = CreateObject("Scripting.FileSystemObject") 'Calls the File System Object
Set objNetwork = CreateObject("WScript.Network")
arrPrinters = Array("PDF", "Adobe", "Remote", "Fax", "Microsoft", "Send To", "Generic")

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

' List drivers
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * from Win32_PrinterDriver")

Set drivrutinCol = CreateObject("Scripting.Dictionary")

For each objPrinter in colInstalledPrinters
' Wscript.Echo "Configuration File: " & objPrinter.ConfigFile
' Wscript.Echo "Data File: " & objPrinter.DataFile
' Wscript.Echo "Description: " & objPrinter.Description
' Wscript.Echo "Driver Path: " & objPrinter.DriverPath
' Wscript.Echo "File Path: " & objPrinter.FilePath
' Wscript.Echo "Help File: " & objPrinter.HelpFile
' Wscript.Echo "INF Name: " & objPrinter.InfName
' Wscript.Echo "Monitor Name: " & objPrinter.MonitorName
' Wscript.Echo "Name: " & objPrinter.Name
' Wscript.Echo "OEM Url: " & objPrinter.OEMUrl
' Wscript.Echo "Supported Platform: " & objPrinter.SupportedPlatform
' Wscript.Echo "Version: " & objPrinter.Version

if InArray(objPrinter.Name, arrPrinters ) = False then
Wscript.Echo "Name: " & objPrinter.Name
drivrutinCol.Add drivrutinCol.Count, Replace(objPrinter.ConfigFile, "C:", "\\" & strComputer & "\c$")
drivrutinCol.Add drivrutinCol.Count, Replace(objPrinter.DataFile, "C:", "\\" & strComputer & "\c$")
drivrutinCol.Add drivrutinCol.Count, Replace(objPrinter.DriverPath, "C:", "\\" & strComputer & "\c$")
end if

Next

' Remove network printers
Const NETWORK = 22
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * From Win32_Printer")

For Each objPrinter in colInstalledPrinters
If objPrinter.Attributes And NETWORK Then

' The code never gets here for user connected network printers

End If
Next

' Stop Print Spooler Service
Set colListOfServices = objWMIService.ExecQuery _
("Select * from Win32_Service Where Name ="_
& strService & " ")

For Each objService in colListOfServices
objService.StopService()
WSCript.Sleep intSleep
Next

' Delete drivers
for i = 0 to drivrutinCol.Count-1
Wscript.Echo "Deleting driver: " & drivrutinCol.Item(i)
fsobj.DeleteFile(drivrutinCol.Item(i))
Next

' Start Print Spooler Service
For Each objService in colListOfServices
WSCript.Sleep intSleep
objService.StartService()
Next

Function InArray(item,myarray)
Dim i
For i=0 To UBound(myarray) Step 1
If InStr(lcase(item), lcase(myarray(i)))>0 Then
InArray=True
Exit Function
End If
Next
InArray=False
End Function

The part where the code is not working is the "Remove network printers" - part. The script do not list the network printers that the user have connected in the userprofile, only the local printers connected to the computer profile. When the user printer is not removed, we cannot delete the drivers.


Any help in how to solve this issue is very appreciated!




To remove a (network) printer connection of a user who isn't logged in you need to load the user hive into the registry and delete the respective value from the Printers\Connections subkey:


Function qq(str) : qq = Chr(34) & str & Chr(34) : End Function

Set sh = CreateObject("WScript.Shell")

username = "..."
hive = "\\" & strComputer & "\C$\Users\" & username & "\ntuser.dat"

sh.Run "reg load HKU\temp " & qq(hive), 0, True
sh.RegDelete "HKEY_USERS\temp\Printers\Connections\server,printer"
sh.Run "reg unload HKU\temp", 0, True

You need to load the hive from a network share, because unlike other subcommands load and unload don't work with remote registries.




To delete a printer driver (after you removed the printer connection from the user's config) you need to acquire the SeLoadDriverPrivilege first and then remove the respective instance of the Win32_PrinterDriver class (see section "Remarks"):


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

qry = "SELECT * FROM Win32_PrinterDriver"
For Each driver In objWMIService.ExecQuery(qry)
If driver.Name = "..." Then driver.Delete_
Next


I need help with deleting network printer driver remotely on a Win7 client using a vbscript with an account having administrator privilegies on the computer in question. The problem is that I can't delete the connected printer the user have connected. Everything else seems to work. Below is the code for the script.


The script does several things, but the ultimate goal is to fysically remove the printer-drivers. The current version of the script fails since the driver files are in use. The script contains code to avoid special printers. It also stops and starts the print spooler.


intSleep        = 4000
strService = " 'Spooler' "
strComputer = "<remote computer name>"
Set fsobj = CreateObject("Scripting.FileSystemObject") 'Calls the File System Object
Set objNetwork = CreateObject("WScript.Network")
arrPrinters = Array("PDF", "Adobe", "Remote", "Fax", "Microsoft", "Send To", "Generic")

Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

' List drivers
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * from Win32_PrinterDriver")

Set drivrutinCol = CreateObject("Scripting.Dictionary")

For each objPrinter in colInstalledPrinters
' Wscript.Echo "Configuration File: " & objPrinter.ConfigFile
' Wscript.Echo "Data File: " & objPrinter.DataFile
' Wscript.Echo "Description: " & objPrinter.Description
' Wscript.Echo "Driver Path: " & objPrinter.DriverPath
' Wscript.Echo "File Path: " & objPrinter.FilePath
' Wscript.Echo "Help File: " & objPrinter.HelpFile
' Wscript.Echo "INF Name: " & objPrinter.InfName
' Wscript.Echo "Monitor Name: " & objPrinter.MonitorName
' Wscript.Echo "Name: " & objPrinter.Name
' Wscript.Echo "OEM Url: " & objPrinter.OEMUrl
' Wscript.Echo "Supported Platform: " & objPrinter.SupportedPlatform
' Wscript.Echo "Version: " & objPrinter.Version

if InArray(objPrinter.Name, arrPrinters ) = False then
Wscript.Echo "Name: " & objPrinter.Name
drivrutinCol.Add drivrutinCol.Count, Replace(objPrinter.ConfigFile, "C:", "\\" & strComputer & "\c$")
drivrutinCol.Add drivrutinCol.Count, Replace(objPrinter.DataFile, "C:", "\\" & strComputer & "\c$")
drivrutinCol.Add drivrutinCol.Count, Replace(objPrinter.DriverPath, "C:", "\\" & strComputer & "\c$")
end if

Next

' Remove network printers
Const NETWORK = 22
Set colInstalledPrinters = objWMIService.ExecQuery _
("Select * From Win32_Printer")

For Each objPrinter in colInstalledPrinters
If objPrinter.Attributes And NETWORK Then

' The code never gets here for user connected network printers

End If
Next

' Stop Print Spooler Service
Set colListOfServices = objWMIService.ExecQuery _
("Select * from Win32_Service Where Name ="_
& strService & " ")

For Each objService in colListOfServices
objService.StopService()
WSCript.Sleep intSleep
Next

' Delete drivers
for i = 0 to drivrutinCol.Count-1
Wscript.Echo "Deleting driver: " & drivrutinCol.Item(i)
fsobj.DeleteFile(drivrutinCol.Item(i))
Next

' Start Print Spooler Service
For Each objService in colListOfServices
WSCript.Sleep intSleep
objService.StartService()
Next

Function InArray(item,myarray)
Dim i
For i=0 To UBound(myarray) Step 1
If InStr(lcase(item), lcase(myarray(i)))>0 Then
InArray=True
Exit Function
End If
Next
InArray=False
End Function

The part where the code is not working is the "Remove network printers" - part. The script do not list the network printers that the user have connected in the userprofile, only the local printers connected to the computer profile. When the user printer is not removed, we cannot delete the drivers.


Any help in how to solve this issue is very appreciated!



To remove a (network) printer connection of a user who isn't logged in you need to load the user hive into the registry and delete the respective value from the Printers\Connections subkey:


Function qq(str) : qq = Chr(34) & str & Chr(34) : End Function

Set sh = CreateObject("WScript.Shell")

username = "..."
hive = "\\" & strComputer & "\C$\Users\" & username & "\ntuser.dat"

sh.Run "reg load HKU\temp " & qq(hive), 0, True
sh.RegDelete "HKEY_USERS\temp\Printers\Connections\server,printer"
sh.Run "reg unload HKU\temp", 0, True

You need to load the hive from a network share, because unlike other subcommands load and unload don't work with remote registries.




To delete a printer driver (after you removed the printer connection from the user's config) you need to acquire the SeLoadDriverPrivilege first and then remove the respective instance of the Win32_PrinterDriver class (see section "Remarks"):


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

qry = "SELECT * FROM Win32_PrinterDriver"
For Each driver In objWMIService.ExecQuery(qry)
If driver.Name = "..." Then driver.Delete_
Next

0 commentaires:

Enregistrer un commentaire