based on Simon's comment and his answer here and Brett's comment there here is a working PowerShell solution.
To be short, the line:
$dte = [runtime.interopservices.marshal]::GetActiveObject("visualstudio.dte")
is changing to this:
$dte = $interop::GetActiveObject("visualstudio.dte")
Full code:
$methodDefinition = @'
[DllImport("ole32")]
private static extern int CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] string lpszProgID, out Guid lpclsid);
[DllImport("oleaut32")]
private static extern int GetActiveObject([MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, IntPtr pvReserved, [MarshalAs(UnmanagedType.IUnknown)] out object ppunk);
public static object GetActiveObject(string progId, bool throwOnError = false)
{
if (progId == null)
throw new ArgumentNullException(nameof(progId));
var hr = CLSIDFromProgIDEx(progId, out var clsid);
if (hr < 0)
{
if (throwOnError)
Marshal.ThrowExceptionForHR(hr);
return null;
}
hr = GetActiveObject(clsid, IntPtr.Zero, out var obj);
if (hr < 0)
{
if (throwOnError)
Marshal.ThrowExceptionForHR(hr);
return null;
}
return obj;
}
'@
$interop = add-type -MemberDefinition $methodDefinition -Name "Interop" -Namespace "Interop" -PassThru
// All of above is for this:
$dte = $interop::GetActiveObject("visualstudio.dte")