I'm unable to get a Word 2010 (14.0.x) document to SaveAs or Close using Powershell. From all the tuts online it seems like it should be working with 2.0, but I don't have that anymore.
Simple case:
$Path = "C:\MyDoc.docx"
$Word = New-Object -comobject Word.Application
$Word.Visible = $True #Do this to close it out without task manager
$Doc = $Word.Documents.Open($Path)
$Doc.SaveAs($Path)
$Doc.Close()
At this point everything works up until the saving and closing:
Argument: '1' should be a System.Management.Automation.PSReference. Use [ref].
At line:5 char:1
+ $Doc.SaveAs($Path)
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : NonRefArgumentToRefParameterMsg
Argument types do not match
At line:6 char:1
+ $Doc.Close()
+ ~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], ArgumentException
+ FullyQualifiedErrorId : Argument types do not match
It seems like any methods that Get-Member shows as having arguments fail. For instance, calling a simple $Doc.Save() works fine, it seems. Looking at the MSDN info on those methods it looks like it takes things like the SaveChanges method, but that's honestly beyond my skills at this point.
I've tried passing $Null or $True or $False in hopes of getting lucky, but it just keeps balking at me.
All I've been able to find is that it is apparently linked to PS 3.0 Beta (seems to work fine in 2.0 for people) and a comment Ed Wilson hasn't gotten back to.
I was also struggling al lot with this error, but got finally around it by calling the "Value" property of the PSReference (I got my Information here: https://msdn.microsoft.com/en-us/library/system.management.automation.psreference(v=vs.85).aspx )
this finally resulted in the codeLines:
$filename = [ref]"C:\Temp\pv_report.docx"
[ref]$option = [Microsoft.Office.Interop.Word.WdSaveFormat] -as [type]
$document.SaveAs(([ref]$filename).Value, ([ref]$option::wdFormatDocumentDefault).Value)
$document.Close()
You just need to use [ref]
when you call SaveAs
. This worked for me:
$Path = "C:\MyDoc.docx"
$NewPath = "C:\MyDocRenamed.docx"
$Word = New-Object -comobject Word.Application
$Word.Visible = $True #Do this to close it out without task manager
$Doc = $Word.Documents.Open($Path)
$Doc.SaveAs([ref] $NewPath)
$Doc.Close()
This might help you:
http://msdn.microsoft.com/en-us/library/office/cc626294(v=office.12).aspx#VSTO3PowerTools_OfficeInteropAPIExtensions
Office Interop API Extensions
The Office Interop API Extensions tool uses new features found in
Microsoft .NET Framework 3.5 and Microsoft Visual C# 3.0 to wrap the
Office object model and provide a more productive environment for the
C# developer. Specifically, it employs extension methods, object
initializers, and nullable types to create a simplified,
strongly-typed, and, in some cases, Microsoft Visual Basic–like API.
It is not a complete managed API for Office, but is designed to
augment the raw object model in useful ways.
The Office object model was originally targeted at dynamic languages
such as Microsoft Visual Basic for Applications (VBA) and Visual
Basic. As such, it makes extensive use of some of their capabilities,
such as late-binding and optional parameters. Being an early-bound and
strongly-typed language, C# can be awkward, tedious, and error prone
when used in this context. The Office Interop API Extensions, with its
simplified and strongly-typed API, enables C# developers to be as
productive in this context as Visual Basic developers.
I know PowerShell 3.0 is based off of CLR4, but this assembly should still load ok. It removes the need for all of the [ref] parameters. Since a lot of this API is based on extension methods (something that doesn't exist in powershell) you'll have to pass the $word
or $doc
instance as the first parameter for a lot of the methods.