{"id":9041,"date":"2012-06-15T00:01:00","date_gmt":"2012-06-15T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2012\/06\/15\/use-powershell-to-add-bulk-autocorrect-entries-to-word\/"},"modified":"2012-06-15T00:01:00","modified_gmt":"2012-06-15T00:01:00","slug":"use-powershell-to-add-bulk-autocorrect-entries-to-word","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-add-bulk-autocorrect-entries-to-word\/","title":{"rendered":"Use PowerShell to Add Bulk AutoCorrect Entries to Word"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell and a CSV file to add bulk AutoCorrect entries to Microsoft Word.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Microsoft TechEd 2012 in Orlando, Florida is over&mdash;well, basically over. Luckily, the Scripting Wife and I were invited by one of the Windows PowerShell program managers to attend a post-event training session about Windows PowerShell&nbsp;3.0. &ldquo;Cool,&rdquo; the Scripting Wife said, &ldquo;For that, we will skip going to see a six-foot mouse (after all, it is still a rodent).&rdquo; After the Windows PowerShell&nbsp;3.0 session, we hop in the car and head to Jacksonville, Florida for the IT Pro Camp day-long event on Saturday. This is one of those &ldquo;you don&rsquo;t want to miss it&rdquo; type of events. There are still a few tickets available, so if you are anywhere near the northeastern portion of Florida, you should check it out.<\/p>\n<p><b>Note&nbsp;&nbsp;&nbsp;<\/b>Todays blog is basically Part&nbsp;2 about adding AutoCorrect entries to Microsoft Word. For Part&nbsp;1, see yesterday&rsquo;s Hey, Scripting Guy! blog, <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2012\/06\/14\/use-powershell-to-add-autocorrect-entries-to-word.aspx\" target=\"_blank\">Use PowerShell to Add AutoCorrect Entries to Word<\/a>.<\/p>\n<h2>Adding bulk AutoCorrect entries to Word<\/h2>\n<p>There is not much difference between adding bulk AutoCorrect entries or adding a single entry to the AutoCorrect feature. The same &ldquo;overhead&rdquo; applies associated with creating the Word.Application object and releasing the Word.Application object. The big difference is that entering a single entry from a command line or hardcoded into the script is a workable solution. With more than two or three entries, such a technique no longer remains viable. Therefore, storage of the bulk entries is a paramount design consideration for a script of this type. Because I might want to remove my bulk entries, I decided to write a single function to add or to delete bulk AutoCorrect entries.<\/p>\n<h2>Use a CSV file for storage<\/h2>\n<p>Perhaps the easiest way to add bulk AutoCorrect entries to Microsoft Word is to use a comma separated value (CSV) file to store the entries. Of course, XML is also a possibility, as would be an Access database, or a Microsoft Excel spreadsheet. But like I said, I am looking for the easiest storage, and there is nothing wrong with a CSV file, and Windows PowerShell makes working with CSV files very easy. To read a CSV file use the <b>Import-CSV<\/b> cmdlet and specify a path to the CSV file. For my CSV file, I used the same column headings that Microsoft Word uses in the graphical interface. <i>Replace<\/i> is the word to replace, and <i>with <\/i>is the word that makes the substitution. Part of the real power of this methodology is that I can substitute a few letters such as <i>lol <\/i>with a phrase such as laugh-out-loud. This can greatly reduce your typing requirements. My sample CSV file is shown here.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0676.HSG-6-15-12-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0676.HSG-6-15-12-01.png\" alt=\"Image of file\" title=\"Image of file\" \/><\/a><\/p>\n<p>The beginning portion of my <b>Set-AutoCorrectEntries<\/b> function defines parameters for the path to the CSV file, and switched parameters that determine whether to add or to remove the entries from Microsoft Word. This portion of the function is shown here.<\/p>\n<p style=\"padding-left: 30px\">Function Set-AutoCorrectEntries<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$path,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$add,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$remove)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$entry = Import-Csv -Path $path<\/p>\n<h2>Use the Add method to add the entries<\/h2>\n<p>Next, I create the Word.Application object, do not make it visible, and obtain the <b>AutoCorrect.entries<\/b> object. This portion of the script is shown here.<\/p>\n<p style=\"padding-left: 30px\">$word = New-Object -ComObject word.application<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$word.visible = $false<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$entries = $word.AutoCorrect.entries<\/p>\n<p>Now I determine if the function is to add or to delete the entries. If add, I use the <b>ForEach<\/b><i> <\/i>language statement to walk through the collection of entries in the <b>$entry<\/b> variable (the result of importing the CSV file). I now use <b>Try <\/b>\/<b> Catch<\/b> to provide basic error handling. In the <b>Try<\/b> scriptblock, I attempt to add the item to the entries collection from the AutoCorrect object. I use the <b>Catch<\/b> scriptblock, to catch any errors that arise and display the name of the replacement item that fails to add. This portion of the script is shown here.<\/p>\n<p style=\"padding-left: 30px\">if($add)<\/p>\n<p style=\"padding-left: 30px\">&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Foreach($e in $entry)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; Try<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { $entries.add($e.replace, $e.with) | out-null }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; Catch [system.exception]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &#8220;unable to add $($e.replace)&#8221; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; } #end foreach<\/p>\n<p style=\"padding-left: 30px\">&nbsp; &nbsp;}#end if add<\/p>\n<h2>Use the Delete method to remove entries from AutoCorrect<\/h2>\n<p>It takes a while to delete all the entries from the AutoCorrect entries object in Word. Therefore, I decide to use the <b>Write-Progress<\/b> cmdlet to produce a progress bar that indicates the status of the delete operation. I only add this progress bar to the <b>Remove<\/b><i> <\/i>portion of the function because the <b>Add<\/b> portion completes quickly. First, I need to initialize the <b>$j<\/b> variable (used as a counter) to ensure that the correct percentage completion displays. Next, I use the <b>ForEach<\/b><i> <\/i>language statement to walk through the entries stored in the <b>$entry<\/b> variable. I next increment the <b>$j<\/b> variable, and call the <b>Write-Progress<\/b> cmdlet. When this portion of the script runs, the dialog box shown here displays (if the script runs from within the Windows PowerShell ISE).<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0815.HSG-6-15-12-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0815.HSG-6-15-12-02.png\" alt=\"Image of dialog box\" title=\"Image of dialog box\" \/><\/a><\/p>\n<p>The portion of the script that begins the <b>Remove<\/b> operation and displays the progress bar is shown here.<\/p>\n<p style=\"padding-left: 30px\">if($remove)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; { $j = 0<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Foreach($e in $entry)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; { $j = $j+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Progress -Activity &#8220;deleting entries&#8221; -Status &#8220;deleting $($e.replace)&#8221; `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -percentcomplete ($j\/$entry.count*100)<\/p>\n<p>To delete the entries in the AutoCorrect entries requires using the <b>Delete<\/b><i> <\/i>method from the entries collection. To call this method, it is necessary to match an entry from the <b>$entry<\/b> collection that is created by reading the CSV file with an entry in the entries collection. This requires walking through the CSV file contents and the entries in the entries collection. When a match occurs, I call the <b>Delete<\/b><i> <\/i>method. This portion of the script is shown here.<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; foreach($i in $entries)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($i.name -eq $e.replace)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { $i.delete() } }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; } #end foreach entry<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; } #end if remove<\/p>\n<p>The last thing to do is to close word and clean up. This code appears here.<\/p>\n<p style=\"padding-left: 30px\">$word.Quit()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$word = $null<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[gc]::collect()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[gc]::WaitForPendingFinalizers()<\/p>\n<p style=\"padding-left: 30px\">} #End function Set-AutoCorrectEntries<\/p>\n<p>The complete AddRemoveAutoCorrectEntries.ps1 script appears here.<\/p>\n<p style=\"padding-left: 30px\"><b>AddRemoveAutoCorrectEntries.ps1<\/b><\/p>\n<p style=\"padding-left: 30px\">Function Set-AutoCorrectEntries<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Param(<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [string]$path,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$add,<\/p>\n<p style=\"padding-left: 30px\">&nbsp; [switch]$remove)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$entry = Import-Csv -Path $path<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$word = New-Object -ComObject word.application<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$word.visible = $false<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$entries = $word.AutoCorrect.entries<\/p>\n<p style=\"padding-left: 30px\">&nbsp;if($add)<\/p>\n<p style=\"padding-left: 30px\">&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Foreach($e in $entry)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; Try<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { $entries.add($e.replace, $e.with) | out-null }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; Catch [system.exception]<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { &#8220;unable to add $($e.replace)&#8221; }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; } #end foreach<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; }#end if add<\/p>\n<p style=\"padding-left: 30px\">&nbsp; if($remove)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; { $j = 0<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Foreach($e in $entry)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; { $j = $j+1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Progress -Activity &#8220;deleting entries&#8221; -Status &#8220;deleting $($e.replace)&#8221; `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -percentcomplete ($j\/$entry.count*100)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach($i in $entries)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($i.name -eq $e.replace)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { $i.delete() } }<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp;&nbsp; } #end foreach entry<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; } #end if remove<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$word.Quit()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$word = $null<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[gc]::collect()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;[gc]::WaitForPendingFinalizers()<\/p>\n<p style=\"padding-left: 30px\">} #End function Set-AutoCorrectEntries<\/p>\n<p>One thing to keep in mind, entries added to the AutoCorrect entries collection remain after closing Microsoft Word. But if Microsoft Word remains open during the process of adding or removing entries, the AutoCorrect entries do not update until after closing and reopening Microsoft Word.<\/p>\n<p>Well, that is about all there is to using a CSV file to add or to delete entries for the AutoCorrect feature in Microsoft Word. This also concludes Microsoft Word Automation Week. Join me tomorrow for more cool Windows PowerShell stuff as I create a function to copy stuff from one Windows PowerShell ISE tab to a new one. This function is so cool that I added it to my Windows PowerShell ISE profile.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell and a CSV file to add bulk AutoCorrect entries to Microsoft Word. Microsoft Scripting Guy, Ed Wilson, is here. Microsoft TechEd 2012 in Orlando, Florida is over&mdash;well, basically over. Luckily, the Scripting Wife and I were invited by one of the Windows PowerShell [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[84,49,3,45],"class_list":["post-9041","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-microsoft-word","tag-office","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, shows how to use Windows PowerShell and a CSV file to add bulk AutoCorrect entries to Microsoft Word. Microsoft Scripting Guy, Ed Wilson, is here. Microsoft TechEd 2012 in Orlando, Florida is over&mdash;well, basically over. Luckily, the Scripting Wife and I were invited by one of the Windows PowerShell [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/9041","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=9041"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/9041\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=9041"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=9041"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=9041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}