Add AUTOTEXT to MS Word Document with Power Shell - powershell

I am working on a project where I need to add AUTOTEXT entries like the Page 1 of X listings to the header and footer of a Power Shell generated MS Word document. I have tried extracting ideas from the following C# examples, but I cannot seem to figure out how to make it work. I was curious if someone could share some code to help me with this.

A starting point. This function add page number to the footer of document passed as parameter ( used on word 2010):
function Add-PageFooter ([string]$Document) {
add-type -AssemblyName "Microsoft.Office.Interop.Word"
set-variable -name wdAlignPageNumberCenter -value 1 -option constant
$fc1 = "Page"
$word = New-Object -comobject Word.Application
$Word.Visible = $True
#$Word.Visible = $False
$fc2 = [ref] "" -as [Type]
$OpenDoc = $Word.Documents.Open($Document)
$c = $OpenDoc.Sections.Item(1).Footers.Item(1).PageNumbers.Add($wdAlignPageNumberCenter)
$range1 = $openDoc.Sections.Item(1).Footers.Item(1).range
$field1 = $OpenDoc.Fields.Add($range1, -1, $fc2)
$field1.Code.Text = $fc1
$field1.Update
#$OpenDoc.Close()
}
Another way is to create a Word Macro and execute from powershell:
$wd = new-object -comobject word.application # create a com object interface (word application)
$wd.documents.open("C:\word\test.doc") # open doc
$wd.run("Macro01") # exec macro named macro01 that add custom footer and/or header
$wd.quit() # exit application
The macro must be saved on normal.dot (normal.dotm for 2010 and above) to have it in all open documents.
In this way you can customize what you want in a word document and not just header/footer recording in a macro your actions in the docs.

Related

how to create dynamic link list from .lnk files in a folder with powershell

I would like to be able to create a dynamic link list from .lnk files in a folder with powershell. I want the link list to be presented to the user in a form that can be minimzed, but will stay active for the entire session, even if the user launch one of them the main form will remain active.
I'm having a hard time moving from VBS to powershell, so any help would be appreciated.
Finally I have managed to have a begining of solution here is my code.
$linklist = #(
("MyFisrtApp" , "\\Path\To\MyFisrtApp.exe"),
("MySecondApp" , "\\Path\To\MySecondApp.exe"),
("MyThirdApp" , "\\Path\To\MyThirdApp.exe"),
("MyFourthApp" , "\\Path\To\MyFourthApp.exe")
)
#Create Form Object
$mainform = New-Object System.Windows.Forms.Form
$mainform.Size = New-Object System.Drawing.Size(400,300)
$mainform.Text = " My Virtual Applications"
$mainform.StartPosition = "CenterScreen" #loads the window in the center of the screen
# convert the array of arrays into an ordered Hashtable
$linkHash = [ordered]#{}
$linklist | ForEach-Object { $linkHash[$_[0]] = $_[1] }
$calculatedPosition =40
$linkHash.GetEnumerator() | ForEach-Object {
$lnk = New-Object System.Windows.Forms.LinkLabel
$lnk.Text = $_.Name # set the name for the label
$lnk.Tag = $_.Value # store the link url inside the control's Tag property
$lnk.Location = New-Object System.Drawing.Point(60, $calculatedPosition)
# inside the scriptblock, $this refers to the LinkLabel control itself
$lnk.Add_Click({ Start-Process $this.Tag })
$mainform.Controls.Add($lnk)
$calculatedPosition += 40 # just a guess, you may want different vertical spacing
}
#Show Form
$mainform.ShowDialog()
My next move now is to display the icon of the .lnk file on the left of each link and also dynamically construct the linklist hashtable from the properties of a list of .lnk files in a specific folder. Also having the form to auto-size as needed if more links need to be shown, would be interesting. I'm trying different setting with mitigated results.

PowerShell - DataGridView Windows Form Drag and Drop Issue

Hello StackOverflow members,
Hoping for some guidance with a Windows Form DataGridView Control issue. I've stumbled to create a simple Windows Form-based PowerShell Script that should make use of Drag and Drop Events. The issue that I am facing is that when I load/run the PowerShell Script within PowerShell ISE interface, the drag over event does not seem to function. However, if I run it again (without doing anything else), the drag over event seems to work (I am simply dragging a few Files from File Explorer over and to a DataGridView Form Control).
Here is my code:
<#==============================================+
| BEGIN SECTION: Form Control Declarations. |
+==============================================#>
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
# [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Windows.Forms.Application]::EnableVisualStyles()
# Create the "ProjectWise File Replacer" Form Control.
$ProjectWiseFileReplacer = New-Object System.Windows.Forms.Form
$ProjectWiseFileReplacer.ClientSize = New-Object System.Drawing.Point(604,460)
$ProjectWiseFileReplacer.Text = "ProjectWise File Replacer (Version 1.0.0) - By Patel, Greene & Associates, LLC"
$ProjectWiseFileReplacer.TopMost = $True
$ProjectWiseFileReplacer.MinimumSize = $ProjectWiseFileReplacer.ClientSize
$ProjectWiseFileReplacer.FormBorderStyle = 'FixedDialog'
$ProjectWiseFileReplacer.Icon = "C:\PGA\Information Technology\ProjectWise\Administration\PowerShell\Scripts\ProjectWise_Icon.ico"
$ProjectWiseFileReplacer.StartPosition = "CenterScreen"
# Create "Files" Data Grid View Form Control.
$DataGridView_Files = New-Object System.Windows.Forms.DataGridView
$DataGridView_Files.Width = 572
$DataGridView_Files.Height = 213
$DataGridView_Files.ColumnCount = 2
$DataGridView_Files.ColumnHeadersVisible = $True
$DataGridView_Files.Columns[0].Name = "Path and File Name"
$DataGridView_Files.Columns[1].Name = "Status"
$DataGridView_Files.Location = New-Object System.Drawing.Point(16,107)
$DataGridView_Files.SelectionMode = 'FullRowSelect'
$DataGridView_Files.MultiSelect = $False
$DataGridView_Files.TabIndex = 0
$DataGridView_Files.RowHeadersVisible = $False
$DataGridView_Files.AutoSizeColumnsMode = 'Fill'
$DataGridView_Files.AllowUserToAddRows = $False
$DataGridView_Files.AllowUserToDeleteRows = $True
$DataGridView_Files.AllowUserToResizeRows = $False
$DataGridView_Files.ReadOnly = $True
$DataGridView_Files.AllowDrop = $True
$DataGridView_Files.RowTemplate.Height = 17
$DataGridView_Files.ColumnHeadersHeight = 22
$DataGridView_Files.Enabled = $True
$DataGridView_Files.Add_DragDrop($DataGridView_Files_DragDrop)
$DataGridView_Files.Add_DragOver($DataGridView_Files_DragOver)
# Add Form Controls to the "ProjectWise File Replacer" Form.
$ProjectWiseFileReplacer.Controls.AddRange(#($DataGridView_Files))
<#================================================+
| BEGIN SECTION: Declare Form Control Events. |
+================================================#>
# "Files" Data Grid View Form Control (Drag Over Event).
$DataGridView_Files_DragOver=[System.Windows.Forms.DragEventHandler]{
# Files have been selected to drag over the "Files" Data Grid View Form Control.
If ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop))
{
# Set Drag Over Event Handler Effect.
$_.Effect = 'Copy'
}
# Files have not been selected to drap over the "Files" Data Grid View Form Control.
Else
{
# Set Drag Over Event Handler Effect.
$_.Effect = 'None'
}
}
# "Files" Data Grid View Form Control (Drag Drop Event).
$DataGridView_Files_DragDrop=[System.Windows.Forms.DragEventHandler]{
# Create a String Array for File Collection.
$Files = $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)
# Files have been selected, dragged and dropped.
If ($Files)
{
# Loop through each File within the File Collection.
ForEach ($File in $Files)
{
# Add File to "Files" Data Grid View Control.
[void]$DataGridView_Files.Rows.Add($File,"")
}
}
}
<#========================================+
| BEGIN SECTION: Main Body of Script. |
+========================================#>
# Display (Show) the "ProjectWise File Replacer" Form Window.
[void]$ProjectWiseFileReplacer.ShowDialog()
Any ideas as to why this won't work the first time I run it?
P.S...I get the same result (of not working as expected) when running the script from outside of the PowerShell ISE program.
Notes:
Windows 10 Pro (64-bit)
Running Script in 64-bit mode.
Move the definitions for $DataGridView_Files_DragOver and $DataGridView_Files_DragDrop above the place where you call on them. Now you are using them when they are not yet defined.
The second time the code runs, they are known and the functionality works.
$DataGridView_Files.Enabled = $True
**Here would be a good spot**
$DataGridView_Files.Add_DragDrop($DataGridView_Files_DragDrop)
$DataGridView_Files.Add_DragOver($DataGridView_Files_DragOver)

How add autocorrect entries with an hyperlink using powershell script

In MS Outlook, is there a way to automatically replace some words like Google, MSN, Facebook, etc (I have an exhausting list in a CSV file), by the hyperlink that redirects to correct website.
So basically when I type google it transforms it to a hyperlink.
My CSV file:
Word, URL
Facebook, https://facebook.com
MSN, https://msn.com
Google, https://google.com
What I have so far is a script that add to the object autocorrect entries a word and replaces it by another word not using a CSV but a word document. But I'm not able to replace it by an hyperlink. It causes an error saying that autocorrect entries accept only string format and not object (hyperlink).
Reference: Add formatted text to Word autocorrect via PowerShell
When I create manually via outlook an hyperlink and I add this hyperlink to autocorrect and I run the following PowerShell script I can't find this autocorrect entry:
(New-Object -ComObject word.application).AutoCorrect.Entries | where{$_.Value -like "*http*"}
I want to adapt this code coming from Use PowerShell to Add Bulk AutoCorrect Entries to Word
If someone has an idea on how to add a hyperlink to the autocorrect entries, I would be grateful.
Thanks!
I finally managed how to add autocorrect entries for both word and outlook.
I need to create a .docx file with 'X row' and '2 Columns', the first column contain the word that i want an autocorrect like 'google' and the second column the 'google' link.
$objWord = New-Object -Com Word.Application
$filename = 'C:\Users\id097109\Downloads\test3.docx'
$objDocument = $objWord.Documents.Open($filename)
$LETable = $objDocument.Tables.Item(1)
$LETableCols = $LETable.Columns.Count
$LETableRows = $LETable.Rows.Count
$entries = $objWord.AutoCorrect.entries
for($r=1; $r -le $LETableRows; $r++) {
$replace = $LETable.Cell($r,1).Range.Text
$replace = $replace.Substring(0,$replace.Length-2)
$withRange = $LETable.Cell($r,2).Range
$withRange.End = $withRange.End -1
# $with = $withRange.Text
Try {
$entries.AddRichText($replace, $withRange) | out-null
}
Catch [system.exception] {
Write-Host $_.Exception.ToString()
}
}
$objDocument.Close()
$objWord.Quit()
[gc]::collect()
[gc]::WaitForPendingFinalizers()
$rc = [System.Runtime.Interopservices.Marshal]::ReleaseComObject($objWord)
This code allow to modify the file Normal.dotm that contains all the autocorrect to an object link (C:\Users{your user id}\AppData\Roaming\Microsoft\Templates)
But then to apply those change to Outlook you have delete the 'NormalEmail.dotm' and the copy/paste 'Normal.dotm' and the rename it to 'NormalEmail.dotm'
This is the script to avoid to do it manually :
$FileName='C:\Users\{your id}\AppData\Roaming\Microsoft\Templates\Normal.dotm'
$SaveTo='C:\Users\{your id}\AppData\Roaming\Microsoft\Templates\NormalEmail.dotm'
Remove-Item –path $SaveTo
$Word = New-Object –ComObject Word.Application
$Document=$Word.Documents.Open($Filename)
$Document.SaveAs($SaveTo)
$Document.Close

Columns Page Layout in Word with Powershell

I'm creating a word document with Powershell and I need to create a two-column column similar to the GUI method shown in the screen shot below:
I've researched other websites that explain basic Powershell Word objects, properties and methods, such as this one. However, there seems to be a lot more functionality that is "hidden" deep in the pages and pages of properties and methods. I'm looking to create a two-column column in my word doc. Here is the code I used to create the document and write to it:
$fileName = 'C:\template.docx'
$word = New-Object -Com Word.Application
$word.Visible = $true
$document = $word.Documents.Open($fileName)
$selection = $word.Selection
$text = "Test Text."
$selection.TypeText($text)
$document.SaveAs($fileName)
$document.Close()
$word.Quit()
$word = $null
Having worked with Excel ComObjects, it's not the easiest to figure out how to make it work with PowerShell.
You're missing this line:
$selection.PageSetup.TextColumns.SetCount(2)
How to get there?
Check the Word Interop Com Object MSDN page
It's probably the PageSetup object we're interesting in (because in the GUI the two columns appear under Layout > Page Setup > Columns)
Googling "word com object pagesetup" leds to a better MSDN documentation page that lists the properties
Repeat this process for TextColumns - it has the methods in the "Remarks" but I prefer to a doc page which lists the members
Finally, finding the SetCount method.
Hopefully this helps you to figure out how to navigate the Word ComObject document in future. The examples are in VBA or C# at best and need to be translated to PowerShell.
$fileName = 'C:\Template.docx'
$binding = "System.Reflection.BindingFlags" -as [type]
$word = New-Object -Com Word.Application
$word.Visible = $true
$document = $word.Documents.Open($fileName)
$selection = $word.Selection
$text = "Test Text."
$selection.TypeText($text)
$selection.PageSetup.TextColumns.SetCount(2)
# check the GUI here.
# You will see the Layout > Page Setup > Columns > Two is selected
$document.SaveAs($fileName)
$document.Close()
$word.Quit()
$word = $null

Powershell Select-All from Word Doc

I want to open, then select all of the text from a word document, not any of the properties, formatting, etc. Ihave searched this site and googled it to no end. Basically similar to opening a Word doc and pressing Ctrl-A and assigning the result to a variable.
$word = New-Object -ComObject Word.Application
$word.visible = $True
$wordfilepath = "\\symphony1\powershell\Phones\Phone.docx"
$doc = $word.Documents.Open($wordfilepath)
????
$selection" >> $textfilepath
Basically a newbie question, but can anyone help?
Thanks.
This will probably suit your needs. It creates a new word object, opens your existing file, and pulls the text from it.
$filePath = <your file here>
$doc = New-Object -com word.application
$fileToOpen = $doc.Documents.Open("$filePath")
$text = $fileToOpen.Range().text
Be forewarned that it will strip out even very basic formatting features such as new lines. Here's a nice list of other range members and properties that you may find helpful.