2

I have a Powershell script that performs some modifications with a MSWord document. In the beginning of the script PS opens the document:

$word = New-Object -ComObject Word.Application
$desktop_path = [Environment]::GetFolderPath("Desktop")
$doc = $word.Documents.Open("$desktop_path" + "blabla.docx")

But as the requirements changed, I now need to run this PS script within an already opened document. Is there any options to force PowerShell find an opened document (by the name for example) and "connect" to it?

FYI: The sequense I want to obtain is: I open the file, launch some macros, call from VBA my PSScript (and here I need PS to be able to "fetch" an opened doc), launch other macros.

Thank you a lot in advance!

G42
  • 9,791
  • 2
  • 19
  • 34
TRP
  • 33
  • 6
  • 2
    why not change the sequence to run macros via powershell? `$doc.run("Macro01")` runs a macro named "Macro01"? – Guenther Schmitz Aug 29 '18 at 10:40
  • Thanks for the reply. The point is that the macros are launching using hot keys, depending on the user choice... And via PS is performed a little piece of functionality, anyway, I will think of it, thank you. – TRP Aug 29 '18 at 11:38

1 Answers1

3

This should the same as for Excel:

$word = [Runtime.Interopservices.Marshal]::GetActiveObject('Word.Application')

Note the same-user limitation. I would recommend doing the whole thing programmatically via PowerShell though, as suggested by Guenther.

If word is not running, is running under a different user, or is running as admin (and PowerShell is not running as admin) you will get an error:

Exception calling "GetActiveObject" with "1" argument(s): "Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))"
At line:1 char:1
+ $word = [Runtime.Interopservices.Marshal]::GetActiveObject('Word.Appl ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : COMException

As advised, check that PowerShell and Word are running under the same user. You can so this by going to Task Manager > Details, and checking the user name column for WINWORD.EXE and powershell.exe

To get a specific document based on name:

$doc = $word.Documents | Where-Object {$_.Name -eq "Document2"}

You can check how many documents are open by looking at the count:

$word.Documents.Count
G42
  • 9,791
  • 2
  • 19
  • 34
  • When I do: Add-Type -AssemblyName "Microsoft.Office.Interop.Word" $word = [System.Runtime.InteropServices.Marshal]::GetActiveObject('Word.Application') $doc = $word.ActiveDocument(), I get the message "This command is not available because no document is open." But there is an open document and the question is - how to connect to it. – TRP Aug 29 '18 at 12:02
  • 1
    Thank you, yes, it works perfectly: $word = [Runtime.Interopservices.Marshal]::GetActiveObject('Word.Application') $doc = $word.Documents | Where-Object {$_.Name -eq "HANA_TPO"} Good luck! – TRP Aug 29 '18 at 13:47