1

I currently have an issue where the print queue is getting stuck on a central print server (windows server 2008). Using the "Clear all documents" function does not clear it and gets stuck too. I need non-admin users to be able to clear the print queue from their work stations.

I have tried using the following winforms program which I created and allows a user to stop the print spooler, delete printer files in the "C:\Windows\System32\spool\PRINTERS folder" and then start the print spooler but this functionality requires the program to be run as an administrator, how can I allow my normal users to execute this program without giving them admin privileges?

Or is there another way I can allow normal user to clear the print queue on the server?

Imports System.ServiceProcess
Public Class Form1
    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        ClearJammedPrinter()
    End Sub
    Public Sub ClearJammedPrinter()
        Dim tspTimeOut As TimeSpan = New TimeSpan(0, 0, 5)
        Dim controllerStatus As ServiceControllerStatus = ServiceController1.Status

        Try

            If ServiceController1.Status <> ServiceProcess.ServiceControllerStatus.Stopped Then
                ServiceController1.Stop()
            End If

            Try
                ServiceController1.WaitForStatus(ServiceProcess.ServiceControllerStatus.Stopped, tspTimeOut)
            Catch
                Throw New Exception("The controller could not be stopped")
            End Try

            Dim strSpoolerFolder As String = "C:\Windows\System32\spool\PRINTERS"

            Dim s As String
            For Each s In System.IO.Directory.GetFiles(strSpoolerFolder)
                System.IO.File.Delete(s)
            Next s

        Catch ex As Exception
            MsgBox(ex.Message)
        Finally
            Try

                Select Case controllerStatus
                    Case ServiceControllerStatus.Running
                        If ServiceController1.Status <> ServiceControllerStatus.Running Then ServiceController1.Start()
                    Case ServiceControllerStatus.Stopped
                        If ServiceController1.Status <> ServiceControllerStatus.Stopped Then ServiceController1.Stop()
                End Select

                ServiceController1.WaitForStatus(controllerStatus, tspTimeOut)
            Catch
                MsgBox(String.Format("{0}{1}", "The print spooler service could not be returned to its original setting and is currently: ", ServiceController1.Status))
            End Try
        End Try
    End Sub
End Class
JamesCW
  • 309
  • 1
  • 4
  • 16
Reafidy
  • 319
  • 1
  • 7
  • 18
  • 1
    You have the option to either impersonate a user whom is an admin (with credentials stored in settings/somewhere else) or to pop up the UAC prompt to run as an elevated user. Which are you after? – Reddog Nov 09 '11 at 00:56
  • See this question: http://stackoverflow.com/questions/2532769/how-to-start-a-process-as-administrator-mode-in-c-sharp possible duplicate – Paul Tyng Nov 09 '11 at 00:56
  • @Reddog, Thanks, I would prefer to have the process run with little disruption to the user so impersonation sounds good but happy with anyway that works. – Reafidy Nov 09 '11 at 01:00
  • @Paul T. I don't think that article is of use, I cant elevate because I need a normal user to run the application. – Reafidy Nov 09 '11 at 01:03
  • Sorry I declined your flag before I saw the commentary in the answers below. Anyhow, is this code (above) running on the users workstation or on the server itself? – Kev Nov 09 '11 at 23:50
  • @Kev: He's trying to run that code on the server, with admin privilege, but needs an unprivileged user to trigger it across the network. – Ben Voigt Nov 10 '11 at 00:30
  • @BenVoigt - what as in walk across to the server or via RDP click buttons? This *can't* be solved by tweaking security on 2008, you have to be admin period to perform these printer management tasks. But it can be solved by providing a service application running on the server as a trusted user exposing just enough functionality (via remoting or WCF) to perform these tasks. His client app (on server or from his workstations) can then run as normal user and make Remoting or WCF calls to this service app. – Kev Nov 10 '11 at 00:40
  • @Kev: Even here on StackOverflow we figured out a solution (create scheduled task on server with saved credentials, set permissions on task to let normal user start it, use schtasks.exe to launch across the network), and I suspect the SF folks might have a cleaner one. Why write code for such a service application when Microsoft already did!?! – Ben Voigt Nov 10 '11 at 00:43
  • You definitely don't have to be admin to perform printer management tasks, [there are permissions designed expressly for the purpose](http://technet.microsoft.com/en-us/library/cc773372(WS.10).aspx) The case under discussion is how to recycle the Print Spooler service when it's too stuck for the normal method to work, and that still doesn't actually require admin rights. – Ben Voigt Nov 10 '11 at 00:46
  • @BenVoigt - yep I should've RTFM, apologies. I forgot about the Print Operators group. – Kev Nov 10 '11 at 00:53

2 Answers2

1

Execute the delete command with the "runas" verb:

var p = new Process();
p.StartInfo.Verb = "runas";
p.StartInfo.FileName = "cmd.exe";

//add your delete command, etc. as args to the process

You could also just make your app require elevation in general by modifying its manifest:

https://stackoverflow.com/questions/1215443/show-uac-prompt-when-launching-an-app

Paul Tyng
  • 111
  • 2
1

you can create a scheduled task which is set to run as admin, and give normal users the right to start it. sort of like how setuid works on unix.

however, this isn't necessary for your problem. you can change the permissions on the print spooler service so that normal users can start and stop it. but that's a better question for serverfault.

Ben Voigt
  • 473
  • 6
  • 20
  • Ok thanks Ben, I think I can manage that, what about deleting the files in the windows/system32 folder though? – Reafidy Nov 09 '11 at 02:28
  • @reafidy: Run as a scheduled task, or change the permissions of the `C:\Windows\System32\spool\PRINTERS` directory. (Don't change the permissions of `C:\Windows` or `C:\Windows\System32`, just the spooler subdirectory). – Ben Voigt Nov 09 '11 at 03:44
  • I will setup a scheduled task, I'm guessing I do this on the server itself and somehow allow each of the users access to it via there workstations? – Reafidy Nov 09 '11 at 04:02
  • @Reafidy: Wait, when did this question become an over-the-network operation? – Ben Voigt Nov 09 '11 at 14:19
  • Sorry Ben, I should have pointed this out at the start. Everyone prints through a "print server" setup on our windows server. This occasionally gets jammed up and the only way to clear it is too stop the print spooler, clear the printer folder and restart. I am sick of doing this about once a week and want to allow our users to do it themselves. I need a holiday. :) – Reafidy Nov 09 '11 at 18:02
  • If the scheduled task is on the server, the users should (if the permissions are set correctly) be able to run it from their machines using **Schtasks /Run /S Server /TN taskname** – sgmoore Nov 09 '11 at 19:45
  • @sgmoore: Thanks for providing that, I didn't know off the top of my head. This question really should be moved to ServerFault. – Ben Voigt Nov 09 '11 at 22:08
  • @Reafidy: I assume you've already tried the "Cancel All Documents" (purge print queue) function built into the Print Spooler, and that's hanging? – Ben Voigt Nov 09 '11 at 22:09
  • @sgmoore - thanks I managed to setup the task and I can run it from a workstation but it only works if i add the username and password of an admin account **Schtasks /Run /S Server /U Admin /P AdminPass /TN taskname** have I done something wrong? – Reafidy Nov 09 '11 at 22:17
  • @Ben, Yes I have tried that and unfortunately it does not clear the print que. Do you want me to repost my question at server fault or are you suggesting a mod should move it? – Reafidy Nov 09 '11 at 22:29
  • @Reafidy: A mod will move it if you as the question author place a flag asking for that. I've already voted to do so, but this question is probably too old to collect 4 more move votes. – Ben Voigt Nov 09 '11 at 22:33
  • @Reafidy: But you probably want to link an account there first, so you continue to own the question. Also probably a good idea to edit the question and explain what you need (clear stuck print queue on a central print server, "clear all documents" function gets stuck too), what you've tried (the code), and where you got stuck (running that code as admin, but triggered by a normal user). Honestly, I'd change the title to "Allowing non-admin users to unstick the print spooler" since you'd be very happy if someone points you at an existing tool instead of using the code you wrote. – Ben Voigt Nov 09 '11 at 22:35
  • @Reafidy: You have to (1) save admin credentials in the scheduled task (they're stored securely inside the server) and (2) change the permissions on the task to let anyone start it. The first is pretty straightforward using the Schedule Task GUI. The second is a bit more involved, and I can't remember the steps off the top of my head. – Ben Voigt Nov 10 '11 at 00:48
  • @Reafidy: I think you have to find the associated .job file in `C:\Windows\Tasks`, and give execute permission to the right group of users. – Ben Voigt Nov 10 '11 at 00:53
  • [This seems relevant](http://forums.techarena.in/windows-server-help/684821.htm) – Ben Voigt Nov 10 '11 at 01:01
  • @Ben: I have given the user full control of the job file and given the right "Logon as Batch" though GPO, but I am still getting access denied. – Reafidy Nov 10 '11 at 05:27