locked
PowerShell to bulk Add AutoCorrect Entries to Word 2010 RRS feed

  • Question

  • I'm trying to bulk-add a long list of autocorrect entries to Word 2010.  I know nothing about writing scripts for PowerShell so am likely making a very ignorant mistake with hopefully an obvious answer.  I've been working with two scripts I've found here, neither of which I've gotten to work for me yet:

    1. Ed Wilson's code, described in this article (http://blogs.technet.com/b/heyscriptingguy/archive/2012/06/15/use-powershell-to-add-bulk-autocorrect-entries-to-word.aspx); and

    2. the code found in this thread (https://social.technet.microsoft.com/Forums/scriptcenter/en-US/d22dba05-27e0-4256-8d7c-e176e8a8b3c3/powershell-adding-to-autocorrect-list?forum=ITCG)

    Ed Wilson's code uses a CSV file that looks like:

    Replace,With
    acsesory, "accessory"
    acomodate, "accommodate"

    [and so on]

    I've used Import-Csv to test the CSV file, and it looks okay - the command returns two columns with the right stuff in left and right columns.

    Ed's code is:

    Function Set-AutoCorrectEntries
    {
     Param(
      [string]$path,
      [switch]$add,
      [switch]$remove)
     $entry = Import-Csv -path $path
     $word = New-Object -ComObject word.application
     $word.visible = $false
     $entries = $word.AutoCorrect.entries
     if($add)
      {
       Foreach($e in $entry)
        {
         Try
           { $entries.add($e.replace, $e.with) | out-null }
         Catch [system.exception]
           { "unable to add $($e.replace)" }
         } #end foreach
       }#end if add
      if($remove)
       { $j = 0
        Foreach($e in $entry)
         { $j = $j+1
          Write-Progress -Activity "deleting entries" -Status "deleting $($e.replace)" `
          -percentcomplete ($j/$entry.count*100)
          foreach($i in $entries)
           {
            if($i.name -eq $e.replace)
             { $i.delete() } }
         } #end foreach entry
       } #end if remove
     $word.Quit()
     $word = $null
     [gc]::collect()
     [gc]::WaitForPendingFinalizers()
    } #End function Set-AutoCorrectEntries

    I think I have two problems/questions with this script: 1) Don't I need to tell it somewhere in here the path to my CSV file? I don't know how to do that - I tried, but probably guessed wrong; 2) This provides for both adding and deleting entries, but how would I tell it which of those I'm trying to do this time around?  Will it ask me when I run the script, or do I need to add a parameter to my run command?  To avoid the issue I tried to modify the code to remove the "remove" option, and I also picked a spot (probably wrong) and added the path to my CSV.  It gives me no error when I run it, but doesn't add entries to AutoCorrect, so I've done something wrong.

    So I searched the forum some more and found option #2 above, but when I use that code (below), I get a whole list of "failed to add" WriteErrorException errors all referencing line 1 character 22.  (Line 1 of my CSV doesn't have 22 characters so I'm lost there.)  After the long list of identical errors it says that AutoCorrect entries have been added (but they have not).  Perhaps my CSV file is not constructed properly for this script?  I'm using the same CSV file I noted above for use with the Ed Wilson script.  Note that in the code below I've made one change, inserted the name of my CSV file in place of MY-CSV-FILENAME-HERE.  I did put my csv file on the desktop as I assumed that's where this code expected to find it.  (I tried a different location at first - and changed 'desktop' below accordingly - but that didn't work and I perhaps don't know the correct grammar for doing that.)

    #
    # import Autocorrect List into Word 2010.ps1
    #
    Param(
        $file='MY-CSV-FILENAME-HERE.csv',
        $path=[Environment]::GetFolderPath('desktop')
    )
    $filepath="$path\$file"
    if(-not (Test-Path $filepath) ){
        Write-Host 'File not found' -ForegroundColor red
        return
    }
    $count = 0
    # file contains twio columns - name and value both are stings.
    $csv = Import-Csv -Path $filepath
    Write-Host 'csv File found. Processing...' -ForegroundColor green
    $word = New-Object -ComObject word.application
    Foreach($entry in $csv){
    	$count +=1
    	 if ($count -gt 1)
    	 {
    	    Try{
    	        if($entry.RichText){
              $word.AutoCorrect.Entries.AddRichText($entry.Name, $entry.Value)
    	        }else{
    
                $word.AutoCorrect.Entries.Add($entry.Name, $entry.Value)
    	        }
    	    }
    	    Catch{
    	        Write-Error ('Failed to add:' + $entry.Name)
    	    }
    	}
    }
    Write-Host 'Autocorrect list entries added'  -ForegroundColor green
    $word.Quit()
    $word = $null
    [gc]::collect()
    [gc]::WaitForPendingFinalizers()

    Assistance greatly appreciated!

    Friday, October 10, 2014 3:46 PM

Answers

  • This version follows the PowerShell model more closely.

    Function Add-AutoCorrectEntries{
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$true)]
            [string]$path
        )
        if(Test-Path $path){
            Write-Verbose "Loading CSV file $path"
            $entry = Import-Csv -path $path
            Write-Verbose "Loaded $($entry.Count) entries"
    	}else{
            Write-Error "Path not found: $path"
            return
    	}
        $word = New-Object -ComObject word.application
        $word.visible = $false
        $entries = $word.AutoCorrect.entries
        
        Foreach($e in $entry){
            Try{
                Write-Verbose ('Replacing entry entry {0} with {1}' -f  $e.replace, $e.with)
                $entries.add($e.replace, $e.with) | out-null 
            }
            Catch [system.exception]{
                Write-Error "unable to add $($e.replace)" 
            }
        }
    }
    
    Add-AutoCorrectEntries -path <your file> -Verbose
    


    ¯\_(ツ)_/¯

    • Marked as answer by CNZ Tuesday, October 14, 2014 8:38 PM
    Tuesday, October 14, 2014 4:47 PM

All replies

  • The script is written as a function, you would need to import it into powershell and then run it passing the parameters - 

    Set-AutoCorrectEntries -path <yourpath>

    Add and remove are switches so the behaviour of the script will change depending on which switch you tag onto the end of the command.

    Set-AutoCorrectEntries -path <yourpath> -Add
    
    or
    
    Set-AutoCorrectEntries -path <yourpath> -Remove

    Friday, October 10, 2014 3:53 PM
  • Thanks!  I chose to edit the .ps1 file which launches PowerShell and imports the contents of the ps1 into the upper pane, and I entered the following in the lower pane and ran it:

    Set-AutoCorrectEntries -path c:\MY-FILENAME-HERE.csv -Add

    (Right so far?)

    It gives me the following error:

    PS C:\> C:\AddRemoveAutoCorrect.ps1
    Missing expression after unary operator '-'.
    At C:\AddRemoveAutoCorrect.ps1:51 char:8
    +       - <<<< percentcomplete ($j/$entry.count*100)
        + CategoryInfo          : ParserError: (-:String) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : MissingExpressionAfterOperator

    If I understand correctly that the error is located at line 51, character 8, then it's referring to this line of code:

         -percentcomplete ($j/$entry.count*100)

    Help?

    Friday, October 10, 2014 8:35 PM
  • Change this

          Write-Progress -Activity "deleting entries" -Status "deleting $($e.replace)" `
          -percentcomplete ($j/$entry.count*100)

    To this:

    Write-Progress -Activity "deleting entries" -Status "deleting $($e.replace)" -percentcomplete ($j/$entry.count*100)


    ¯\_(ツ)_/¯

    Friday, October 10, 2014 9:06 PM
  • I think all you did there was take out that stray ` mark?  I'm sorry, I noticed that and tried it already, but I got the exact same error message, right down to the line & character referenced, so I figured it didn't matter and didn't think to mention I'd done it. (I also made it all one line in case that mattered - nope.)

    Or am I missing some other change you made to that line?

    Monday, October 13, 2014 1:12 PM
  • When I look at the script in the ISE that should be on line 25/26. Have you modified the script in any way to knock it all the way down to line 51?
    Monday, October 13, 2014 1:39 PM
  • Use this version because it works:

    Function Set-AutoCorrectEntries{
        [CmdletBinding()]
        Param(
            [string]$path='c:\temp3\test.csv',
            [switch]$add,
            [switch]$remove
        )
        
        $entry = Import-Csv -path $path
        $word = New-Object -ComObject word.application
        $word.visible = $false
        $entries = $word.AutoCorrect.entries
        
        if($add){
            Foreach($e in $entry){
                Try{
                    Write-Verbose ('Replacing entry entry {0} with {1}' -f  $e.replace, $e.with)
                    $entries.add($e.replace, $e.with) | out-null 
                }
                Catch [system.exception]{
                    Write-Error "unable to add $($e.replace)" 
                }
            }
        }
    
        if($remove){
            Foreach($e in $entry){
                foreach($i in $entries){
                    if($i.name -eq $e.replace){
                        Write-Verbose ('Removing entry entry {0}' -f  $e.replace)
                        $i.delete() 
                    } 
                }
            }
        }
        
        $word.Quit()
    }
    

    Call it with -verbose to see the progress.


    ¯\_(ツ)_/¯


    • Edited by jrv Monday, October 13, 2014 1:52 PM
    Monday, October 13, 2014 1:44 PM
  • When I look at the script in the ISE that should be on line 25/26. Have you modified the script in any way to knock it all the way down to line 51?

    Yes, the script I'm actually running is full of blank lines (which I removed when posting to make a shorter post, but haven't bothered to remove in the PS1 file).
    Monday, October 13, 2014 9:07 PM
  • Use this version because it works:

    ..

    Call it with -verbose to see the progress.


    ¯\_(ツ)_/¯


    Tried that one and the result I get is just:

    PS C:\> C:\MY-PS1-FILE-HERE.ps1

    The command I used was: Set-AutoCorrectEntries -path <c:\WPQC-converted.csv> -Add -verbose

    (I also tried it without the -path parameter since the path is in this script (I edited that part of the script to be my path), but I get the same result.  I suppose that makes sense ...)

    Monday, October 13, 2014 9:15 PM
  • That is not a legal path:

    Set-AutoCorrectEntries -path "c:\WPQC-converted.csv" -Add -verbose


    ¯\_(ツ)_/¯

    Monday, October 13, 2014 9:24 PM
  • It appears that you do not know anything about PowerShell.  You need to understand that a file with a function is not callable directly.  You are also not telling us the exact error.

    If the code is in a file you must dot source the file.


    ¯\_(ツ)_/¯

    Monday, October 13, 2014 9:26 PM
  • I know absolutely nothing about PowerShell (which I was careful to say in my initial post - yes that's important - I can follow instructions well, but I do need all of the instructions, nothing left out). 

    The code is in a .PS1 file.  I get its contents into PowerShell by right-clicking the .PS1 file and choosing Edit.  (I noted that in my second post.)  Am I doing that wrong?  

    As of this morning I believe the error referencing line 51 character 8 no longer applies.  (I did note that exact error message in my second post above).  I'm not sure why I continued to get that error on Friday after removing the stray ` mark, but today I note I do not get it if I remove that mark.  Perhaps I did something else wrong when removing that on Friday.  Today, both in Ed Wilson's script with that mark removed and also when using the code you posted, I get the same return - no error, simply:

    PS C:\> C:\MY-PS1-FILE-HERE.ps1

    The command I've been using is from Braham20's reply to my initial post:

    Set-AutoCorrectEntries -path <yourpath> -Add

    (to which I added -Verbose).  I note you used quotation marks around the path, which I did not, but that doesn't seem to matter.  If you recommend a different path/command I'll try that.


    Tuesday, October 14, 2014 12:48 PM
  • What happens when you run that command. What tis the message?


    ¯\_(ツ)_/¯

    Tuesday, October 14, 2014 1:56 PM
  • Have you loaded the function into powershell? The easiest way to do it is to set-location to the folder the script lives in and then dot source it. As an example, if I had written a function name Get-Cake and saved it in a script named Get-Cake.ps1 on the root of the C drive I could enter the following to use the function in powershell

    Set-location C:\
    
    . .\Get-cake.ps1
    
    

    After that I would be able to use the get-cake function in Powershell the way you would any other cmdlet, it will be useable only for that session and will be removed from memory once the Powershell window is closed.

    get-cake <parameters>

    Tuesday, October 14, 2014 4:09 PM
  • This is always a problem when a noon-tech tries to use scripts designed for a tech.  They tend to not read the instructions and fial to understand the directions.

    You cannot run a function in a file by typing the filename alone.

    You cannot get help unless you carefully report errors.

    If you keep loading many different copies of code from different sources then you will get lost.

    Without some basic technical knowledge about PowerShell and the Windows system you will go around in circles.


    ¯\_(ツ)_/¯

    Tuesday, October 14, 2014 4:15 PM
  • Open a new copy of Powershell CLI - do not use ISE for this:

    Paste the following into the console and be sure there are no errors.

    Function Set-AutoCorrectEntries{
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$true)]
            [string]$path,
            [switch]$add,
            [switch]$remove
        )
        if(Test-Path $path){
            Write-Verbose "Loading CSV file $path"
            $entry = Import-Csv -path $path
            Write-Verbose "Loaded $($entry.Count) entries"
    	}else{
            Write-Error "Path not found: $path"
            return
    	}
        $word = New-Object -ComObject word.application
        $word.visible = $false
        $entries = $word.AutoCorrect.entries
        
        if($add){
            Foreach($e in $entry){
                Try{
                    Write-Verbose ('Replacing entry entry {0} with {1}' -f  $e.replace, $e.with)
                    $entries.add($e.replace, $e.with) | out-null 
                }
                Catch [system.exception]{
                    Write-Error "unable to add $($e.replace)" 
                }
            }
        }
    
        if($remove){
            Foreach($e in $entry){
                foreach($i in $entries){
                    if($i.name -eq $e.replace){
                        Write-Verbose ('Removing entry entry {0}' -f  $e.replace)
                        $i.delete() 
                    } 
                }
            }
        }
        
        $word.Quit()
    }
    
    

    Set-AutoCorrectEntries -path <your file> -add -Verbose

    A big issue here is the poor design of the original function.  It was designed to illustrate how to do this and not to be a product for non-technical users to use.

    If you use no switches the function runs with no output and does nothing because that is whaat you told it to do.

    Type the function name and follow the instructions:

    Set-AutoCorrectEntries -verbose


    ¯\_(ツ)_/¯

    Tuesday, October 14, 2014 4:44 PM
  • This version follows the PowerShell model more closely.

    Function Add-AutoCorrectEntries{
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$true)]
            [string]$path
        )
        if(Test-Path $path){
            Write-Verbose "Loading CSV file $path"
            $entry = Import-Csv -path $path
            Write-Verbose "Loaded $($entry.Count) entries"
    	}else{
            Write-Error "Path not found: $path"
            return
    	}
        $word = New-Object -ComObject word.application
        $word.visible = $false
        $entries = $word.AutoCorrect.entries
        
        Foreach($e in $entry){
            Try{
                Write-Verbose ('Replacing entry entry {0} with {1}' -f  $e.replace, $e.with)
                $entries.add($e.replace, $e.with) | out-null 
            }
            Catch [system.exception]{
                Write-Error "unable to add $($e.replace)" 
            }
        }
    }
    
    Add-AutoCorrectEntries -path <your file> -Verbose
    


    ¯\_(ツ)_/¯

    • Marked as answer by CNZ Tuesday, October 14, 2014 8:38 PM
    Tuesday, October 14, 2014 4:47 PM
  • This version follows the PowerShell model more closely.

    Function Add-AutoCorrectEntries{
        [CmdletBinding()]
        Param(
            [Parameter(Mandatory=$true)]
            [string]$path
        )
        if(Test-Path $path){
            Write-Verbose "Loading CSV file $path"
            $entry = Import-Csv -path $path
            Write-Verbose "Loaded $($entry.Count) entries"
    	}else{
            Write-Error "Path not found: $path"
            return
    	}
        $word = New-Object -ComObject word.application
        $word.visible = $false
        $entries = $word.AutoCorrect.entries
        
        Foreach($e in $entry){
            Try{
                Write-Verbose ('Replacing entry entry {0} with {1}' -f  $e.replace, $e.with)
                $entries.add($e.replace, $e.with) | out-null 
            }
            Catch [system.exception]{
                Write-Error "unable to add $($e.replace)" 
            }
        }
    }
    
    Add-AutoCorrectEntries -path <your file> -Verbose

    Sweet success (with the code quoted, and using PowerShell CLI) - thank you so much! :D 

    I had been using the full command with parameters all along (just as used in my final successful attempt - I wasn't typing just the csv filename) but I was using Powershell ISE in all of my previous attempts, and perhaps that was the source of my troubles.  That is, it likely does not work quite as I had thought it did.  I had been specific in my posts about how I was getting my code into powershell so that someone could tell me not to do it that way if that way was incorrect (as it seems to have been).  That two-pane console is apparently Powershell ISE.  I assume the DOS-type screen I ended up using is Powershell CLI.

    A bit of a winding thread, so if I may sum up for anyone else in my position who comes along:

    1. Create your CSV file as described here: http://blogs.technet.com/b/heyscriptingguy/archive/2012/06/15/use-powershell-to-add-bulk-autocorrect-entries-to-word.aspx

    2. Copy the code above (beginning with Function, ending with -Verbose and of course being careful to copy all of it, and nothing extra)

    3. Launch Powershell either by typing that word into the Windows Run dialog (launch the Run dialog by pressing Windows Key+R) or by clicking your start button, typing Powershell into the search field, then choosing just plain "Windows Powershell" from the list.  Alternatively, find and launch powershell.exe, which is likely found (if you're running Windows 7) in a subfolder of the WindowsPowerShell subfolder of your Windows System folder - something like C:\Windows\System32\WindowsPowerShell.  This opens a very DOS-like window, labeled "Windows PowerShell", with just a command line.

    4. To paste what you've copied to this command line press Alt+Space bar, which gives you a menu (then choose Edit | Paste from the menu).

    5. In the last line of the code pasted, replace <your file> with your .csv filename, including full path and without brackets.  For example, if your csv file is named AutoCorrect.csv, that last line should read:

    Add-AutoCorrectEntries -path C:\AutoCorrect.csv -Verbose

    6. Press Enter


    • Edited by CNZ Tuesday, October 14, 2014 8:36 PM
    Tuesday, October 14, 2014 8:35 PM