Comment modifier un document Word via PowerShell ?

I. Présentation

Dans ce tutoriel, nous allons apprendre à modifier des documents Word (Microsoft Office) via PowerShell par l'intermédiaire de signets que l'on va utiliser comme repère. Il s'agit d'une astuce qui permet de gagner du temps dans bien des situations ! Les manipulations effectuées dans ce tutoriel n'impliquent pas d'utiliser un module PowerShell complémentaire.

II. Office : les signets dans Word

Pour commencer, faisons un rapide rappel sur les signets dans Office Word. Un signet dans Word permet de marquer un endroit que vous souhaitez retrouver facilement. Vous pouvez créer autant de signets que vous le souhaitez dans votre document, et vous pouvez leur donner un nom unique afin de les identifier facilement. Dans notre contexte, nous allons utiliser les signets pour marquer l'endroit où notre script/commande PowerShell devra insérer une information précise.

Nous utiliserons par exemple un signet AUTEUR qui sera présent dans plusieurs documents, notre script sera en mesure d'ouvrir ces documents, de trouver le signet et d'y insérer la donnée souhaitée, le tout automatiquement. Pour manipuler les signets efficacement, il est dans un premier temps préférable de les rendre visibles dans Word. Pour cela, il faut se rendre dans "FICHIER" puis "Options", aller dans l'onglet "Options avancées" et cocher "Afficher les signets" :

Rendre les signets visibles dans Word
Rendre les signets visibles dans Office Word.

Ajoutons maintenant un signet au bout d'une ligne AUTEUR. Après avoir placé notre curseur à l'endroit où nous souhaitons ajouter le signet, il faut se rendre dans "INSERTION" puis "Signet", donner le nom que l'on souhaite à notre signet (et ne pas l'oublier) puis cliquer sur "Ajouter" :

Ajouter un signet dans Office Word.
Ajouter un signet dans Office Word.

À présent, nous pouvons voir notre signet par un marquage spécifique dans notre document. Nous pouvons également retourner dans notre menu "Signet" et utiliser le bouton "Atteindre" pour retrouver un signet spécifique (cas d'un grand document ou plusieurs signets sont utilisés). Sachez également qu'un même signet peut être inséré à plusieurs endroits d'un document, ce qui permettra de modifier la même information plusieurs fois sans erreur.

III. Ouvrir et fermer un document Word via PowerShell

Maintenant que notre signet est positionné, nous allons apprendre à manipuler un document Word dans PowerShell. Il faut pour commencer, ouvrir un document et le fermer en y sauvegardant des modifications, voici les lignes de code en question, commentées :

# Chemin vers notre fichier Word
$docfile = "C:\Users\audit\Documents\Docs\Doc-02.docx"
# Création d'un objet COM de type Word.Application
$Word = New-Object -comobject Word.Application
$Word.Visible = $False

# Ouverture du document Word
$document = $Word.Documents.Open($docfile)

#[Code de manipulation/lecture/modification]

# Sauvegarde des modifications dans le fichier indiqué
$document.SaveAs($docfile)
# Fermeture du document
$document.Close()
# Fermeture de l'application
$Word.Quit()

Si vous insérez ces lignes dans un script .ps1, vous constaterez qu'il ne se passe pas grand-chose. Rien d'étonnant pour l'instant :).

IV. Word : insérer du texte dans un signet via PowerShell

À présent, nous allons insérer entre les instructions précédentes quelques lignes permettant d'insérer une donnée à l'endroit du signet nommé AUTEUR :

# Contenu de la donnée à insérer
$data="Mickael"

# Nom du signet à modifier
$signet = "AUTEUR"
# Suppression d'éventuels sauts de ligne
$data = $data.Trim()
# Recherche du signet à modifier dans le document
$bookmark = $document.Bookmarks | Where-Object -FilterScript { $_.Name -eq $signet }
$bookmarkToModify = $bookmark.Range
# Insertion de la donnée à l'endroit du signet
$bookmarkToModify.Text = $data

Pour rappel, ces instructions sont à insérer à l'endroit du [Code de manipulation/lecture/modification] dans le bout de code vu précédemment (III. Ouvrir et fermer un document Word via PowerShell).

Après exécution du script, si vous consultez le document Word ciblé, le contenu souhaité aura été inséré à l'endroit du signet AUTEUR. Cette valeur correspond à la variable $data du code ci-dessus.

Constat de l'insertion du contenu voulu dans le signet AUTEUR.
Constat de l'insertion du contenu voulu dans le signet AUTEUR.

Si vous avez plusieurs signets différents dans votre document, il vous suffit de répéter l'opération avec un nom de signet (variable $signet) différent.

V. Générer des documents Word à partir de modèles

Maintenant que nous savons faire cela, nous pouvons envisager des cas d'utilisation plus réalistes. Par exemple, lorsqu'un nouveau projet est créé dans une entreprise, plusieurs documents doivent être initialisés :

  • un document de présentation du projet (presentation.docx),
  • un document listant les intervenants sur le projet (intervenants.docx),
  • un document listant les achats à faire pour débuter le projet (achats.docx).

Tous ces documents auront un contenu différent, mais certaines informations seront communes :

  • l'auteur : le chef de projet,
  • la date : la date de création du projet,
  • le destinataire : le nom de notre client.

Saisir ces informations manuellement dans plusieurs documents est chronophage et source d'erreur. Nous devons créer un script qui va générer une arborescence pour un nouveau projet et insérer dans chaque document les informations qui peuvent l'être. Nous allons donc créer une petite arborescence de fichier dans un dossier nommé "modeles" et un script qui va prendre en entrée :

  • le nom du projet,
  • la date de création souhaitée,
  • le nom de l'auteur,
  • le nom du client.

Ce script PowerShell va ensuite initialiser l'ensemble des documents de notre projet et y insérer les données dans les signets prévus :

# Paramètres
param ( [string] $auteur, [string] $date, [string] $client, [string] $nom)

# Fonction d'écriture de données dans le signet dans l'objet "$doc" passé en paramètre
function modifySignet{
param($doc,$key,$value)
# Nom du signet à modifier
$signet = $key
# Recherche du signet à modifier dans le document
$bookmark = $document.Bookmarks | Where-Object -FilterScript { $_.Name -eq $signet }
$bookmarkToModify = $bookmark.Range
# Insertion de la donnée à l'endroit du signet
$bookmarkToModify.Text = $value.Trim()
return $doc
}

# Fonction de génération du document à partir du modèle
function createDoc {
param ($i, $o, $d, $c, $a)
# Création d'un objet COM de type Word.Application
$Word = New-Object -comobject Word.Application
$Word.Visible = $False

# Ouverture du fichier
$document = $Word.Documents.Open($i)
Write-host " [+] Insertion de données dans les signets"
# Appel de notre fonction d'insertion de données dans le signet
$document = modifySignet -doc $document -key "AUTEUR" -value $a
$document = modifySignet -doc $document -key "DATE" -value $d
$document = modifySignet -doc $document -key "CLIENT" -value $c

# Sauvegarde des modifications dans le fichier indiqué
$document.SaveAs($o)
# Fermeture du document
$document.Close()
# Fermeture de l'application
$Word.Quit()
}

# Création du répertoire projet
Write-Host "[+] Génération du répertoire projet"$nom
New-Item -itemtype directory -name $nom | Out-Null

# Pour chaque fichier du répertoire "modele"
Get-ChildItem .\modeles\ |foreach {
Write-host "[+] Génération du fichier"$_.Name"à partir du modèle"
# Chemin vers notre fichier Word
$infile = (Resolve-Path ".").Path.Replace('Microsoft.PowerShell.Core\FileSystem::', '') +"\modeles\"+$_.Name
$outfile= (Resolve-Path ".").Path.Replace('Microsoft.PowerShell.Core\FileSystem::', '') +"\"+$nom+"\"+$_.Name
# Appel de la fonction de modification des signets
createDoc -i $infile -o $outfile -d $date -c $client -a $auteur
}

En plus du code déjà présenté, nous avons en plus dans ce projet les lignes de code concernant la création du répertoire projet et le parcours du dossier "modèle" pour y trouver l'ensemble des documents à copier dans notre répertoire projet et enfin, les lignes relatives à la gestion des paramètres. L'utilisation du script sera fera comme suivant :

> generer-projet.ps1 -nom project342 -auteur "Mickael" -date "14/08/2022" -client "IT-Connect"
[+] Génération du répertoire projet project342
[+] Génération du fichier achats.docx à partir du modèle
[+] Insertion de données dans les signets
[+] Génération du fichier intervenants.docx à partir du modèle
[+] Insertion de données dans les signets
[+] Génération du fichier presentation.docx à partir du modèle
[+] Insertion de données dans les signets

Suite à l'exécution de ce script, j'aurai dans un répertoire project342 avec les documents souhaités préremplis aux signets indiqués :

Création et remplissage automatique des fichiers docx via Powershell.
Création et remplissage automatique des fichiers docx via Powershell.

Il ne s'agit bien sûr que d'un exemple qui vise à montrer ce qui est réalisable dans des contextes plus proches de la réalité :).

Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Partager sur Google+ Envoyer par mail

Mickael Dorigny

Co-fondateur d'IT-Connect.fr. Auditeur/Pentester chez Orange Cyberdéfense.

mickael has 520 posts and counting.See all posts by mickael

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.