As an experiment I created $obj=new-object -com file
. ("file" is the progid for the FileMoniker COM class). [Runtime.InteropServices.marshal]::GetIUnknownForObject($obj)
gives me an System.IntPtr
on my Windows 2008R2 machine. I was able to pass that value, along with the GUID for IMoniker to [Runtime.InteropServices.marshal]::QueryInterface and I got back the same value (ie same pointer) as I got from GetIUnknownForObject. So I was able to query the interface.
However, I'm not sure what good that does from Powershell. There are a lot of other methods in [Runtime.InteropServices.marshal] that might be of interest for dealing with COM from PS. But in general dealing with COM objects in PS is very different than dealing with them in C++.
EDIT
I recently found and verified a way to access some COM components from PS that might be of interest here. The Windows SDK comes with a large set of IDL files. If you want to access one of these (and the component doesn't implement IDispatch), you can compile the IDL with MIDL and then use TLBIMP to create an interop assembly. I successfully did this with the 3 VSS Hardware Provider interfaces.
I also learned that you can use [type]::GetTypeFromCLSID to get a type from a CLSID. And depending on the component you can then instantiate it.