We help IT Professionals succeed at work.

Install Printer on Seperate Machine?

angus_young_acdc
on
I'm not sure if this is possible, as I would imagine the security risks would be dangerous, but I've been tasked with installing all printers on our various print servers (13 in total) on our Production boxes (8 in total), and it appears to be a boring manual task, especially as selecting all and pressing Enter prompts a dialog, and right clicking and selecting Connect throws an error when it attempts to access private printers.

So, I was wondering if it's possible for me to install them on the target machines via code that will run on my machine.   And if it is possible, how to go about it? I know the account credentials for the boxes, so I can use impersonation to run any code I write.

I should state, I would be doing this in C# (not a script) as I can't put anything on the boxes, and my machine is XP and the target boxes are Win2000.
Comment
Watch Question

Most Valuable Expert 2012
Top Expert 2008
Commented:
WMI has the Win32_Printer class, and it has a AddPrinterConnection method.  With a connection to the remote server, with the proper credentials (Domain Admin), you might be able use this option.


// Add a reference to System.Management.dll to the project.
//
// MSDN reference:
// http://msdn2.microsoft.com/en-us/library/aa394363(VS.85).aspx

using System;
using System.Collections;
using System.Collections.Generic;
using System.Management;
using System.Reflection;

namespace CSharp.CodeSnippet.WMI
{

    public enum PrinterStatus
    {
        Other = 1,
        Unknown,
        Idle,
        Printing,
        Warmup,
        Stopped,
        Offline
    }

    public class Win32_Printer : BaseWmiObject<Win32_Printer>
    {

        public int DefaultPriority;
        public bool Direct;
        public bool DoCompleteFirst;
        public string DriverName;
        public bool EnableBIDI;
        public bool EnableDevQueryPrint;
        public bool Hidden;
        public bool KeepPrintedJobs;
        public bool Local;
        public string Location;
        public string Name;
        public bool Network;
        public string PortName;
        public bool Queued;
        public bool RawOnly;
        public string ServerName;
        public bool Shared;
        public PrinterStatus Status;
        public bool WorkOffline;

        public Win32_Printer(ManagementObject managementObject)
            : base(managementObject)
        {
        }

        public Win32_Printer()
        {
        }

        /// <summary>
        /// Get printers using a WMI query.
        /// </summary>
        public List<Win32_Printer> GetList()
        {
            return base.ExecuteQuery();
        }

        /// <summary>
        /// Get printers using a WMI query on a remote machine.
        /// </summary>
        public List<Win32_Printer> GetList(string machineName, string userName, string password)
        {
            return base.ExecuteQuery(machineName, userName, password);
        }

        public void AddPrinterConnection(string friendlyName)
        {
            base.InvokeMethod(friendlyName);
        }

        public void CancelAllJobs()
        {
            base.InvokeMethod();
        }

        public void Pause()
        {
            base.InvokeMethod();
        }

        public void PrintTestPage()
        {
            base.InvokeMethod();
        }

        public void RenamePrinter(string newName)
        {
            base.InvokeMethod(newName);
        }

        public void Resume()
        {
            base.InvokeMethod();
        }

        public void SetDefaultPrinter()
        {
            base.InvokeMethod();
        }

    }

}

Open in new window

Most Valuable Expert 2012
Top Expert 2008
Commented:
BaseWmiObject:


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Management;
using System.Reflection;

namespace CSharp.CodeSnippet.WMI
{

    public class BaseWmiObject<T> where T : class
    {

        public BaseWmiObject(ManagementObject managementObject)
        {
            _managementObject = managementObject;
        }

        public BaseWmiObject()
        {               
        }

        private ManagementObject _managementObject = null;
        internal ManagementObject ManagementObject
        {
            get { return _managementObject; }
        }

        private void ConfigureScope(ManagementObjectSearcher searcher, string machineName, string userName, string password)
        {
            if (userName != null && password != null && userName.Trim().Length > 0 && userName.Trim().Length > 0)
            {
                ManagementPath path = new ManagementPath();

                if (machineName != ".")
                    path.Server = string.Format(@"\\{0}\root\cimv2", machineName.TrimStart('\\'));

                ConnectionOptions options = new ConnectionOptions();
                options.Username = userName;
                options.Password = password;

                ManagementScope scope = new ManagementScope(path, options);

                searcher.Scope = scope;
            }
        }


        protected List<T> ExecuteQuery()
        {
            return ExecuteQuery(null, null, null);
        }

        protected List<T> ExecuteQuery(string machineName, string userName, string password)
        {
            string query = "Select * From " + this.GetType().Name;

            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

            // If machine name, user name, and password are passed, configure the scope to execute the query on the remote machine.
            if (!string.IsNullOrEmpty(machineName))
            {
                this.ConfigureScope(searcher, machineName, userName, password);
            }

            List<T> list = new List<T>();

            // Execute the query to get all the WMI objects.
            ManagementObjectCollection result = searcher.Get();

            // Build a list of type-specific objects.
            foreach (ManagementObject obj in result)
            {
                T entry = (T) Activator.CreateInstance(this.GetType(), obj);

                // Get all the public fields.
                FieldInfo[] fieldList = this.GetType().GetFields();

                foreach (FieldInfo field in fieldList)
                    field.SetValue(entry, ConvertValue(obj[field.Name], field.FieldType));

                list.Add(entry);
            }
            return list;
        }

        protected object InvokeMethod(params object[] parameters)
        {
            // Reflect the method to call from the caller's name.
            StackFrame sf = new StackFrame(1);
            string method = sf.GetMethod().Name;

            return this.ManagementObject.InvokeMethod(method, parameters);
        }

        protected object ConvertValue(object value, Type type)
        {
            if (value != null)
            {
                if (type == typeof(DateTime))
                {
                    string time = value.ToString();
                    time = time.Substring(0, time.IndexOf("."));
                    return DateTime.ParseExact(time, "yyyyMMddHHmmss", null);
                }
                else if (type == typeof(long))
                    return Convert.ToInt64(value);
                else if (type == typeof(int))
                    return Convert.ToInt32(value);
                else if (type == typeof(short))
                    return Convert.ToInt16(value);
                else if (type == typeof(string))
                    return value.ToString();
                else if (type.BaseType == typeof(Enum))
                    return value;
            }
            return null;
        }

    }

}

Open in new window

Most Valuable Expert 2012
Top Expert 2008
Commented:
Example:

Win32_Printer printer = new Win32_Printer();
printer.AddPrinterConnection("friendly name");
Unfortunately I couldn't exactly get this to work, and I was unsure how to do it for other machines (this appears to just be local).  

I would have posted back about it, however the company I work for changes their mind constantly, and this project was scrapped.