1

As described here, COM objects can be created using New-Object -ComObject ProgID.

With the same steps we can create COM object with ProgID wscAPI.WSCProductList.1. But we see no methods are available whereas there are few as per docs here. Why these methods are not shown/accessible in powershell?

PS C:\>$Wsc = New-Object -ComObject wscAPI.WSCProductList.1
PS C:\>$Wsc | Get-Member
TypeName: System.__ComObject

Name                      MemberType Definition
----                      ---------- ----------
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
Equals                    Method     bool Equals(System.Object obj)
GetHashCode               Method     int GetHashCode()
GetLifetimeService        Method     System.Object GetLifetimeService()
GetType                   Method     type GetType()
InitializeLifetimeService Method     System.Object InitializeLifetimeService()
ToString                  Method     string ToString()

PS: There is a sample code to access these methods using C++ here.

OS: Microsoft Windows 10 Enterprise

Nilesh
  • 2,089
  • 3
  • 29
  • 53
  • Because COM service data type's are not as easily _discoverable_ as, say, a .NET method. At some point the engineering team probably decided that it was simply not worth the effort to try and implement :) – Mathias R. Jessen Feb 20 '20 at 20:22

1 Answers1

1

Well, by design, PowerShell is not a COM Object Browser. COM objects are only loaded when instantiated and called.

PowerShell is .Net based, and .Net is part is the Operating system and loaded when the OS starts. This is the reason what you get the .Net namespaces in IntelliSense In PowerShell without extra work. Though even with that one needs to call it correctly. For example,

[System.Net.Dns]::

… or if you want if you don’t what to type all that, you can put this…

Using Namespace System.Net

at the very top of your profile / your script or the first thing you’d put in an interactive session, then you could just due

[Dns]::

About Using It allows you to indicate which namespaces are used in the session.

COM would not be available to you in this manner. As for your pointer the C++ code. You can use external code segments/blocks/functions in PowerShell to supplement what you may be trying to do and this is what the Add-type cmdlet is used for.

Examples ---

Using CSharp (C#) code in Powershell scripts

As noted online:

from within PS run help add-type -full and look for the F# example (example 7 on my system). Assuming you have a C++ compiler that follows the "CodeDom" model, you can mirror the F# example.

Also, PowerShell can call unmanaged code using P/Invoke (this is a .NET concept), search the web for the use case.

So, based on even what you are showing, you are talking beyond this?

$wscAPI = New-Object -ComObject wscAPI.WSCProductList.1
$wscAPI.CreateObjRef(

... so, you want to be able to say to have IntelliSense/tab completion for when you start typing

New-Object -ComObject #[tab if on the command line or IntelliSense popup in an editor]

Yet there are modules/scripts, etc. via the Microsoft powershellgallery.com, the demonstrate how you could write your own object browser. See the resources below:

PowerShell Object Browser

This is a PowerShell application that displays objects in an explorer type application written in PowerShell. The PowerShell Object Browser displays the properties and child objects/collections for any PowerShell / .Net framework object. For an explanation on how to use this a

Download: PSObjectBrowser.ps1

There are several WMI, CIM, .Net examples/tools that show how to do object browsing, but again, that .Net. Just search for them as well. For Example:

PowerShell Object Browser

This is a PowerShell application that displays objects in an explorer type application written in PowerShell. The PowerShell Object Browser displays the properties and child objects/collections for any PowerShell / .Net framework object. For an explanation on how to use this a

Download: PSObjectBrowser.ps1

Weekend Scripter: The WMI Explorer Tool

Weekend Scripter: Announcing WMI Explorer 2.0

PowerShell ISE Add-on - CIM Explorer

PowerShell ISE add-on for navigating CIM(WMI) namespaces/definitions and creating PowerShell script examples through CIM cmdlets

Free WMI Explorer, WMI Tools & Powershell GUI Builder

Coretech WMI and PowerShell Browser

· A powerful WMI tool that allows you to connect to and work with WMI locally and remotely. With the tool, you can browse WMI namespaces, classes, methods, properties and class instances. Besides being a WMI browser the Coretech WMI and PowerShell Explorer allows also to export query results and namespace methods.

These could give you ideas regarding how you might design one for COM. Yet, you'd have to know all the possible COM classes (registered or not) you'd like to instantiate. So, you could do something like this to find them ...

Get-ChildItem -Path 'HKLM:\Software\Classes' -ErrorAction SilentlyContinue | 
Where-Object {$PSItem.PSChildName -match '^\w+\.\w+$' -and
(Get-ItemProperty "$($PSItem.PSPath)\CLSID" -ErrorAction SilentlyContinue)} | 
Format-Table PSChildName -AutoSize

# Results
<#
Sample output from the COM lookup.

PSChildName                                              
-----------                                              
...                                          
Access.Application                                       
...                                        
AcroPDF.PDF                                              
...                                          
AudioVBScript.1                                          
...                                          
CDO.Message                                              
...                        
Cmiv2.CmiFactory                                         
...                                                          
Excel.Application                                        
...                                         
InternetExplorer.Application                             
...                                         
Outlook.Application                                      
...                                             
Paint.Picture                                            
...
#>

One, of course, can modify the regex to look up whatever string(s) they choose. See the Regular Expression resource for detailed guidance on regex use.

RegExLib.com Regular Expression Cheat Sheet (.NET)

Regular-Expressions.Info Tutorials

So, with that block for say this effort...

New-Object -ComObject #[tab if on the command line or IntelliSense popup in an editor]

... as long as you load this at startup, and give them a populated variable name, that would be a quick and dirty way to do this. I've done similar things not only for this but for the .Net classes as well...

Function Get-AllCimClassesAsVariables
{
    # Set variables for CimClasses
    ForEach($Item in ((Get-CimClass -ClassName *).CimClassName))
    {Set-Variable -Name $Item -Value $Item}
}

Point of note here:

I don't use this approach anymore, because it is cumbersome, has a heavy startup load because it would have to populate this list on every PowerShell session.

I have full Visual Studio on my workstation (one can use the paid-for or free version), as well, so I use it for PowerShell development stuff as well to reference and browse COM resources.

Prior to that, I used OleView.exe from the Windows / MSOffice SDKs. There was also in the Windows Resource kits that were free to download. I still have that in a cloud location for my easy access, pinned to my taskbar when I just need that vs spinning up Visual Studio or when I am in a location where I don’t have Visual Studio at hand.

To do what you are after, it would be prudent just to use OleVIew.exe as part of your PowerShell toolset to look up and use the COM info, find the ones you'd regularly use and put those into a module you regularly load via your profile or you'll need to gin up whatever thingy you need for browsing the similar to what tools are shown for WMI/CIM/.Net ones above.

postanote
  • 15,138
  • 2
  • 14
  • 25
  • Do you mean only those COM objects can be used from powershell that comes with .NET types created already? Can you elaborate what is filter for - `$PSItem.PSChildName -match '^\w+\.\w+$'` ? – Nilesh Feb 21 '20 at 07:19
  • Nope, any that are on the machine that are discoverable. Which is all that Regex is doing, matching for registry item strings that meet that criteria. If you are asking, what each of those symbols mean, just go here ... --- http://regexlib.com/CheatSheet.aspx --- https://www.regular-expressions.info --- ...for a deep read on them and regex in general. – postanote Feb 21 '20 at 07:30
  • It is filtering out all `$PSItems` whose `PSChildName` contains dot. My question was does it mean child names with dot are not discoverable? any reference for this? – Nilesh Feb 21 '20 at 07:40
  • No, that is not what that means. You can modify the regex to look up whatever string(s) you choose, hence those pointers to the sites. Did you try the snippet to see what is brought back? See my update for you. Point of note: I don't use this approach anymore. I have full Visual Studio on my workstation, as well, so I use it for PowerShell stuff as well and reference and browse COM stuff there. Prior to that, I used OleView.exe from the Windows / MSOffice SDK. Which is free to download. Still have that pinned to my taskbar when I need it. – postanote Feb 22 '20 at 01:58
  • Thanks @postanote for very descriptive answer. Can you please summarize the answer to match the question title? That will be helpful for people landing on this thread from search engines. – Nilesh Feb 23 '20 at 12:41
  • Updated relative to additional comments/info. – postanote Feb 24 '20 at 01:23