Setting password for Word doc from Powershell - vba

I'd like to make a Microsoft Word document be set with a password for opening the document. When I try to run the following code in Powershell, the script will hang once I enter the desired password.
This script will be run in Kaseya to help automate protecting Word documents. I've tried both modifying the Document.Password property and using the Document.Protect method and they both will hang the script.
$path = Read-Host("Specify path to word document")
Write-Host "Creating Word application object..."
$wordAppObj = New-Object -ComObject Word.Application
Write-Host "Creating Word document object..."
$wordDocObj = $wordAppObj.Documents.Open($path)
# Write-Host "Activating Word document object..."
# $wordDocObj.Activate
Write-Host "Setting password..."
$securePass = Read-Host("Set password as") -AsSecureString
$password = ConvertFrom-SecureString $securePass
# $wordDocObj.Protect(3, $true, $password)
$wordDocObj.Password = $password
Write-Host "Saving Word document object..."
$wordDocObj.Save
Write-Host "Closing the Word document..."
$wordDocObj.Close
Write-Host "Closing Word..."
$wordAppObj.Application.Quit()
I expect the script to run through and protect the file, but the script will hang and an instance of Microsoft Word will be running in the background taking up about 6-9% of the CPU. Nothing will happen to the file or in the script. There are no error messages that pop up.
UPDATE: As suggested, I added $wordAppObj.Visible = $true to the script to see if there were any pop-ups that happened during the execution of the script. Unfortunately, I didn't see any. I believe the script may be hanging when it prompts the user to re-enter the password. This happens when I use Word to encrypt a document with a password. Is there any way to fill this field in from Powershell?

I have developed a program in C# with the Microsoft Interop reference for Word. This program worked for me. At this point, I believe that this kind of thing cannot be done from Powershell and I would advise that anyone trying to do this seek another way to get this done. I think Powershell simply doesn't support modifying the password field of a document.

Related

Why does Word open with a different normal.dot if started via COM rather than via Start Menu?

When I start Microsoft Word on the Start Menu and then query Application.NormalTemplate.Path for the location of the normal.dotm file, I get, as expected, C:\Users\USERNAME\AppData\Roaming\Microsoft\Templates.
However, when I start Word using COM automation in PowerShell:
$wrd = new-object -com word.application
$wrd.visible = $true
I get a different path when querying the same expression:C:\Users\USERNAME\AppData\Local\Packages\Microsoft.Office.Desktop_8wekyb3d8bbwe\LocalCache\Roaming\Microsoft\Templates.
Why is that and what can I do in order for the COM invocation to open the same normal.dotm file?

Using Powershell to run a macro on an Excel document when .open causes hang

This may be a combination of two questions, but I'm open to multiple solutions.
I open an Excel file with Powershell using the following code
$step=$args[0]
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $True
$excel.WindowState = 'xlMaximized'
$workBook = $excel.Workbooks.Open($step)
When this Excel file opens, it automatically runs several macros intended to download a second Excel file. I need to close the first Excel file, and it looks like there's a macro to do it that I could call, but Powershell never actually returns to the prompt (PS C:\>) after calling Workbooks.Open(), I'm assuming because the UserForm that's generated by the macros is still open (It just contains a close button at this point, which triggers the exit macro).
So, is there either any way I can get Powershell to return to the prompt to run the exit macro, or is there another way I can close the first Excel file without closing the second one?
Because the second file is generated by macros in the first, it will always be in the same process as the first, so using Stop-Process will close both windows.
Try disabling alerts to suppress the popup:
$step=$args[0]
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $True
$excel.WindowState = 'xlMaximized'
$excel.DisplayAlerts = $false
$workBook = $excel.Workbooks.Open($step)

Convert .xlsx to .csv and save to specific directory

I have a scheduled task set up (in a separate program) which will email a .xlsx file. I have a rule set up that will save the email to an Outlook folder called 04_CFW REPORT
I need Outlook to open the file with Excel and save as .csv to a network drive.
This will happen at night, when i am away from the computer
The closest thing i've found is a function here:
http://www.devhut.net/2012/05/14/ms-access-vba-convert-excel-xls-to-csv/
but i have no idea how to put this function to use in a sub.
Any help would be greatly appreciated.
This might be a place to start. Taken from here
Then you can research into creating a powershell job to run once daily and loop until the specified email subject is found.
Another point to consider, if you have permission Powershell can perform the SQL query and output a CSV which can be converted into an XLSX.
Add-type -assembly "Microsoft.Office.Interop.Outlook" | out-null
$olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
$outlook = new-object -comobject outlook.application
$namespace = $outlook.GetNameSpace("MAPI")
$folder = $namespace.getDefaultFolder($olFolders::olFolderInBox)
Then I can filter on Inbox items using, for example any unread items.
$folder.items | where {$_.UnRead -eq $true}
***EDIT, getting PowerShell to close Excel's comobject correctly. It's a matter of properly releasing the COM object. First (assuming this isn't done) we Save the workbook and Quit Excel.
Next we release COM objects from smallest (here the variable holding a range of cells) to largest (the Excel ComObject variable) in a loop should more than one iteration be required. Now the last two lines I've noticed are not really required, but in testing scripts it's nice to do but run Garbage Collection. Watch task manager to confirm it's operation.
$xlsObj.ActiveWorkbook.SaveAs($xlsFile) | Out-Null
$xlsObj.Quit()
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsRng)) {'cleanup xlsRng'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsSh)) {'cleanup xlsSh'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsWb)) {'cleanup xlsWb'}
While ([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xlsObj)) {'cleanup xlsObj'}
[gc]::collect() | Out-Null
[gc]::WaitForPendingFinalizers() | Out-Null

Can I use CreateObject to print a .tif document with vba? If not, what?

The following vba routine works well to print a word document
If sHlink <> "" Then
Set OfficeObject = CreateObject("Word.Application")
OfficeObject.Documents.Open sHlink
OfficeObject.PrintOut Background:=False
OfficeObject.Quit
Set OfficeObject = Nothing
End If
but what I need to print are .TIF documents. They open by default with the Microsoft Photo Viewer. Is there something similar that will call the MS Photo Viewer, or failing that, Acrobat? Perhaps with Acrobat could I use some kind of command line?
Thank You
I found this shell command that prints using the Photo Editor that was formerly installed with Office:
Shell """C:\Program Files\Common Files\Microsoft Shared\PhotoEd\photoed.exe"" -p h:\misc\MyPicture.tif"
I think it can be adapted to print using the current Picture Manager - I bet it uses the same -p switch. This seems to be named "OIS.EXE" for some reason.

Access Word 'Save As' dialog box with PowerShell script

I've got a PowerShell script (running on Windows Server 2008 R2 Enterprise) that opens a Word doc in Word 2010, performs a SaveAs, and saves the doc as a PDF. In brief my code looks similar to the below:
$word = new-object -ComObject "word.application"
$word.Visible = $true
$doc = $word.documents.open("path\file.doc")
$doc.SaveAs("path\file.pdf", [ref] 17)
$doc.Close()
ps winword | kill
The above works fine, no problems at all and is converting the documents as expected.
My question is:
If I physically open Word myself and navigate to 'File > Save As' I get various options in the dialog when saving as PDF (eg. page range, optimisation etc)
How can I, if at all, access these options from within the PowerShell script when performing the same action?
Any advice would be appreciated. Maybe it's just not possible.
Thanks in advance
After much investigation I've found that option I needed was ExportAsFixedFormat().
The documentation can be found here:
http://msdn.microsoft.com/en-us/library/bb256835%28v=office.12%29.aspx
And you can see it in action within a PowerShell script here:
http://blog.coolorange.com/2012/04/20/export-word-to-pdf-using-powershell/