wmi, MSFT_Printer, AddConnection()

This topic contains 10 replies, has 4 voices, and was last updated by  js 3 months, 1 week ago.

  • Author
    Posts
  • #98400

    js
    Participant

    http://wutils.com/wmi/root/standardcimv2/msft_printer/#addconnection_methods

    How can I call AddConnection('\\server\printer') in powershell? This isn't working:

    $printer = Get-CimInstance -namespace 'root/standardcimv2' -class MSFT_Printer
    $printer.AddConnection('\\server\printer')
    
    Method invocation failed because [Microsoft.Management.Infrastructure.CimInstance] does not contain a method named
    'addconnection'.
    At line:1 char:1
    + $printer.AddConnection('\\server\printer')
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (addconnection:String) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound
    

    Docs: http://wutils.com/wmi/root/standardcimv2/msft_printer/#addconnection_methods

    I think 'Add-Printer -ConnectionName' calls it.

  • #98427

    L-Bo
    Participant

    I just so happened to run into something similar at work recently. I do not have the ability to confirm this code works as I do not have access to a print server right now to test, but I know it involved using the "AddWindowsPrinterConnection" method of the Wscript.Network comObject. It was something like this...

    $obj = New-Object -ComObject WScript.Network
    $obj.AddWindowsPrinterConnection('\\server\printqueue')
    

    Hope this helps! If you need additional help let me know and I can double check my production code when I get back to work.

    • #98430

      js
      Participant

      Thanks. I knew about the vbscript way. I was hoping to get it working the other way.

    • #98431

      L-Bo
      Participant

      I apologize if I misunderstood what your objective was. I use the PrintManagement module at work for most things, but I had to write a logon script for a GPO to map existing print queues to a new server. I had to make the script backward compatible for PS 2.0 clients since we still have more of them in the environment than I care to admit... That is how I went about it. I would think the "Invoke-CimMethod" cmdlet would due the trick, but when I send the object to "Get-Member" I don't see an "AddConnection" method.

      Get-CimInstance -namespace 'root/standardcimv2' -class MSFT_Printer | Get-Member -MemberType Methods
      
      
         TypeName: Microsoft.Management.Infrastructure.CimInstance#root/standardcimv2/MSFT_Printer
      
      Name                      MemberType Definition                                                                                                                                      
      ----                      ---------- ----------                                                                                                                                      
      Clone                     Method     System.Object ICloneable.Clone()                                                                                                                
      Dispose                   Method     void Dispose(), void IDisposable.Dispose()                                                                                                      
      Equals                    Method     bool Equals(System.Object obj)                                                                                                                  
      GetCimSessionComputerName Method     string GetCimSessionComputerName()                                                                                                              
      GetCimSessionInstanceId   Method     guid GetCimSessionInstanceId()                                                                                                                  
      GetHashCode               Method     int GetHashCode()                                                                                                                               
      GetObjectData             Method     void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISeriali...
      GetType                   Method     type GetType()                                                                                                                                  
      ToString                  Method     string ToString()
      
  • #98443

    postanote
    Participant

    Firstly, this, if this was to used...

    'root/standardcimv2'
    

    ...should bs this way...

    'root\StandardCimv2'
    

    Using the below tool and completing the 'Browse the namespace on this computer', section. You'd also see this and that the .addconntion you are trying to use does exist.

    'microsoft.com/en-us/download/details.aspx?id=8572'

    Or this PowerShell-based one..

    'blog.ctglobalservices.com/powershell/kaj/coretech-wmi-and-powershell-browser'

    If you want to be sure a built-in function / cmdlet has a particual parameter, try this...

    # Find all cmdlets / functions with a target parameter
    Get-Command -CommandType Function | 
    Where-Object { $_.parameters.keys -match 'addconnection'} | 
    Out-GridView -PassThru -Title 'Available functions which has a specific parameter'
    
    Get-Command -CommandType Cmdlet | 
    Where-Object { $_.parameters.keys -match 'addconnection'} | 
    Out-GridView -PassThru -Title 'Available cmdlets which has a specific parameter'
    

    You could also look to this tool to look at all the WMI stuff.

    Otherwise you end up doing stuff like this...

    $net = new-Object -com WScript.Network
    $net.AddWindowsPrinterConnection($PrinterPath)
    

    Or legacy net use command
    Or why not just GPO?

    Settings for printers in Group Policy are under
    "Policies/Windows Settings/Deployed Printers"

    • #98449

      L-Bo
      Participant

      @postanote – I am a little confused by your response, I think it mostly stems from your validating with the OP that the method DOES exist? I ran the commands you suggested and didnt get any results, I didnt think it was possible to screw up a copy and paste, but I imagine if there is a way to do it just leave it to me! I mean I am the guy using the comObject to update existing printer mappings for users via GPO Logon scripts. 🙂

      PS C:\Users\L-Bo> Get-Command -CommandType function | 
      Where-Object { $_.parameters.keys -match 'addconnection'} | 
      Out-GridView -PassThru -Title 'Available cmdlets which has a specific parameter'
      
      PS C:\Users\L-Bo> 
      PS C:\Users\L-Bo> Get-Command -CommandType Cmdlet | 
      Where-Object { $_.parameters.keys -match 'addconnection'} | 
      Out-GridView -PassThru -Title 'Available functions which has a specific parameter'
      

      Wait, maybe the commands didn't yield any results because the OP was speaking about methods available to a particular Infrastructure.CimInstance object rather than parameters available in a particular Cmdlet or function?

      Look, I was just trying to offer some quick advice off the top of my head to help a fellow member of the community out. I didn't realize my answer was going to be scrutinized so heavily. Since I am taking the time to defend my position I thought I would dive into one of my books on the topic which led me to this little gem.

      PS C:\Users\L-Bo>  Get-CimClass -ClassName *print* -MethodName *addconnection*
      
      PS C:\Users\L-Bo>  Get-CimClass -ClassName *print* -MethodName *add*connection*
      
      
         NameSpace: ROOT/cimv2
      
      CimClassName                        CimClassMethods      CimClassProperties                                                                                                          
      ------------                        ---------------      ------------------                                                                                                          
      Win32_Printer                       {SetPowerState, R... {Caption, Description, InstallDate, Name...}                                                                                
      
      
      
      PS C:\Users\L-Bo>  Get-CimClass -ClassName Win32_Printer -MethodName * | select -exp cimclassmethods
      
      Name                  ReturnType Parameters         Qualifiers                                         
      ----                  ---------- ----------         ----------                                         
      SetPowerState             UInt32 {PowerState, Time} {}                                                 
      Reset                     UInt32 {}                 {}                                                 
      Pause                     UInt32 {}                 {Description, Implemented, ValueMap, Values}       
      Resume                    UInt32 {}                 {Description, Implemented, ValueMap, Values}       
      CancelAllJobs             UInt32 {}                 {Description, Implemented, ValueMap, Values}       
      AddPrinterConnection      UInt32 {Name}             {Description, Implemented, Static, ValueMap...}    
      RenamePrinter             UInt32 {NewPrinterName}   {Description, Implemented, ValueMap, Values}       
      PrintTestPage             UInt32 {}                 {Description, Implemented, ValueMap, Values}       
      SetDefaultPrinter         UInt32 {}                 {Description, Implemented, ValueMap, Values}       
      GetSecurityDescriptor     UInt32 {Descriptor}       {description, implemented, Privileges, ValueMap...}
      SetSecurityDescriptor     UInt32 {Descriptor}       {description, implemented, Privileges, ValueMap...}
      

      With all things considered maybe a better answer to the OPs post is this?

      $printer = '\\server\printer'
      $cim = Get-CimClass -ClassName Win32_Printer
      Invoke-CimMethod -CimClass $cim -MethodName 'AddPrinterConnection' -Arguments @{name = $printer}
      
  • #98484

    js
    Participant

    I got it! I'm just looking for different ways to do it and get back different error messages. It doesn't seem reliable in Windows 10 to add a network printer during a new profile creation, by script or policy. I had run add-printer with 'set-psdebug -trace 1' and got the 'AddConnection' method, and the error message (invalid parameter) had the MSFT_Printer class. This is how add-printer works (via the MethodInvocationInfo class). Why didn't it work my original way?

    PS C:\> $printer = '\\server\printer'
    PS C:\> $cim = Get-CimClass -ClassName  MSFT_Printer -Namespace 'root\StandardCimv2'
    PS C:\> $cim | select -exp cimclassmethods
    
    Name              ReturnType Parameters                                                         Qualifiers
    ----              ---------- ----------                                                         ----------
    AddConnection         UInt32 {ConnectionName}                                                   {implemented, static}
    AddByExistingPort     UInt32 {BranchOfficeOfflineLogSizeMB, Comment, ComputerName, Datatype...} {implemented, static}
    AddByWsdPort          UInt32 {BranchOfficeOfflineLogSizeMB, Comment, ComputerName, Datatype...} {implemented, static}
    RenameByName          UInt32 {ComputerName, Name, NewName}                                      {implemented, static}
    RenameByObject        UInt32 {InputObject, NewName}                                             {implemented, static}
    
    
    PS C:\> Invoke-CimMethod -CimClass $cim -MethodName 'AddConnection' -Arguments @{ConnectionName = $printer}
    
    PSComputerName
    --------------
    

    You can also add a printer like this. I'm not sure what the difference is between this and get-wmiobject (static vs constructor?).

    $printer = '\\server\printer'
    $printClass = [wmiclass]'win32_printer'
    $printClass.AddPrinterConnection($printer)
    
  • #98631

    js
    Participant

    I get it now. There are static and instance methods in wmi just like in .net. This will list instance methods:

    get-wmiobject "MSFT_Printer" -Namespace root\StandardCimv2 | get-member
    

    And this will list static methods (including 'AddConnection'):

    [wmiclass]"root\StandardCimv2:MSFT_Printer" | get-member
    
    • #98703

      L-Bo
      Participant

      Thanks for sharing the solution! That is not something I knew before and I appreciate your helping me learn something new. Sorry for any confusion on my part

    • #98713

      js
      Participant

      No, you helped me figure it out.

  • #98632

    Joel Sallow
    Participant

    Ah, nice! Of course, you were getting and instance of the WMI class, which would naturally lack the static methods.

    Nice find, I'll have to remember this one!!

You must be logged in to reply to this topic.