janowitsch
Goto Top

Pfad der Dokumentenvorlage mit einem Powershell Script ändern?

Hallo Leute,

Anwender nehmen in Word leider viel zu oft alte Dokumente als Vorlage für neue Dokumente her und dann stimmen nach einem Wechsel des Fileservers irgendwann die Vorlagenpfade in den Addin-Einstellungen nicht mehr.

Ich beschäftige mich gerade mit Powershell. Stecke aber noch in den Anfängen fest.

Von daher meine Frage: Kann man die Änderung des Ablagepfades in den Word-Addins mit einem Powershell-Script ändern?

Im Moment gebe ich den Anwendern eine kleine Doku, mit der sie den Pfad manuell ändern können bzw. den hinterlegten Pfad löschen. Das kommt bei den Anwendern nicht gut an, da es sich in "Einzelfällen" um hunderte Dokumente handelt.
Klar könnte ich sagen, dass das ein selbstgemachtes Problem ist. Warum werden auch immer wieder alte Dokumente als Vorlage genommen und nicht einmal eine richtige Vorlage gebaut. Aber face-smile

Grüsse Janowitsch

Content-Key: 244332

Url: https://administrator.de/contentid/244332

Ausgedruckt am: 19.03.2024 um 04:03 Uhr

Mitglied: colinardo
colinardo 22.07.2014 aktualisiert um 11:59:18 Uhr
Goto Top
Hallo Janowitch,
hatten wir schon einige male diese Frage, hier bekommst du VBS-Scripte die dir die alten Vorlagenpfade aus mehreren Dokumenten entfernen:

Word mit Powershell zu automatisieren geht zwar auch über das COM-Objekt, ist aber nicht zu empfehlen da hier die Performance unterirdisch ist!

Grüße Uwe
Mitglied: Janowitsch
Janowitsch 22.07.2014 aktualisiert um 12:10:16 Uhr
Goto Top
Danke Uwe! Die entsprechenden Einträge habe ich schon gelesen. Da die Server Migration durch ist, kann ich mit den VB Scripten nicht viel anfangen. So ein Lauf würde viel zu viel Ausfall der entsprechenden Clients bedeuten.
Von daher die Frage nach einem Powershell Script. Wobei da ja auch das Dokument geöffnet werden würde? Und auch hier das Zeitproblem bestehen würde.

Grüsse Janowitsch
Mitglied: colinardo
colinardo 22.07.2014 aktualisiert um 12:33:50 Uhr
Goto Top
Zitat von @Janowitsch:
Da die Server Migration durch ist, kann ich mit den VB Scripten nicht viel anfangen. So ein Lauf würde viel zu viel Ausfall der entsprechenden Clients bedeuten.
? verstehe ich nicht wieso. In der Nacht laufen lassen ?!
Von daher die Frage nach einem Powershell Script. Wobei da ja auch das Dokument geöffnet werden würde? Und auch hier das Zeitproblem bestehen würde.
Sicher, mit Powershell würde das ganze noch wesentlich langsamer ablaufen, deswegen habe ich das mit VBS gelöst!

Zum Beschleunigen des Vorganges sollte ein DNS-Name des alten Servers auf den neuen Zeigen, dann geht das ganze wesentlich schneller !!

Grüße Uwe
Mitglied: colinardo
colinardo 22.07.2014 aktualisiert um 18:06:49 Uhr
Goto Top
So,
ich habe jetzt endlich mal Zeit gefunden mich damit nochmal zu beschäftigen (wollte ich sowieso) und eine Lösung nur mit Powershell erarbeitet, die ohne Benutzung des COM-Objektes funktioniert, und deswegen kein Öffnen der jeweiligen Datei mit Word nötig macht. Da die Word-Dokumente ja eigentlich Zip-Dateien sind in denen die entsprechenden Infos stehen, habe ich mir diese mal angeschaut und die benötigten Änderungen für das Entfernen der Vorlagen erarbeitet. Da die jeweiligen Infos dort in XML-Dateien stehen, war das eine saubere Sache.

Folgender Code ist dabei rausgekommen:

WICHTIGER HINWEIS: Der Code benötigt mindestens Powershell in Version 3.0 und das NET-Framework in Version 4.5, da erst dort die Methoden für ZIP-Dateien enthalten sind.
(Der Ordner für die Dateien wird in Zeile 9 angegeben, welcher dann rekursiv durchlaufen wird und alle *.docx und *.docm Dateien verarbeitet)
back-to-topVorlage (Template) von Word-Dokumenten entfernen (nur *.docx / *.docm)
# Entfernt die Dokumentvorlage aus OpenXML Word Dokumenten
# Benötigt wird mindestens NET-Framework 4.5 und Powershell 3.0

# benötigte Assemblies laden
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.Filesystem

# Pfad zu den Dateien
$pathFiles = "E:\Ordner\Word-Dateien"   

$files = dir "$pathFiles\*.doc[xm]" -Recurse -File  
foreach ($file in $files){
    # Word-Dokument als ZIP-Datei im Update-Modus öffnen
    $zipfile = [System.IO.Compression.ZipFile]::Open($file.FullName,[System.IO.Compression.ZipArchiveMode]::Update)
    
    # Temporäre Extrahierungs-Pfade für die Dateien die geändert werden
    $pathSettingsFile = "$pathFiles\settings.xml"  
    $pathSettingsRelsFile = "$pathFiles\settings.xml.rels"  
    
    # Falls die temoporären Dateien existieren lösche sie
    if((Test-Path $pathSettingsFile)){del $pathSettingsFile -Force}
    if((Test-Path $pathSettingsRelsFile)){del $pathSettingsRelsFile -Force}
    
    # Einträge der benötigte Dateien aus dem Dokument holen
    $entry1 = $zipfile.Entries | ?{$_.Fullname -eq 'word/settings.xml'}  
    $entry2 = $zipfile.Entries | ?{$_.Fullname -eq 'word/_rels/settings.xml.rels'}  
    # Wenn beide Dateien gefunden wurden ...
    if ($entry1 -and $entry2){
        # word/settings.xml extrahieren
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry1,$pathSettingsFile)
        # word/_rels/settings.xml.rels extrahieren
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry2,$pathSettingsRelsFile)
        $xml = New-Object XML
        $xml.Load($pathSettingsFile)
        # alle aufgeführten Templates holen
        $allTemplates = $xml.settings.attachedTemplate
        # Nur wenn Vorlagen vorhanden sind ...
        if ($allTemplates){
            write-host "Entferne Vorlage aus Dokument '$($file.Fullname)' ..." -ForegroundColor Green  
            # Template Nodes entfernen
            $allTemplates | %{$xml.settings.RemoveChild($_) | out-null}
            $xml.Save($pathSettingsFile)

            # Template-Verweise im settings-rels-File entfernen und speichern
            $xml.Load($pathSettingsRelsFile)
            $allTemplates | %{$id = $_; $xml.Relationships.Relationship | ?{$_.Id -eq $id} | %{$xml.Relationships.RemoveChild($_) | out-null}}
            $xml.Save($pathSettingsRelsFile)
        
            # alte Dateien aus der Word-Datei entfernen
            $entry1.Delete()
            $entry2.Delete()

            # geänderte Dateien wieder hinzufügen
            [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipfile,$pathSettingsFile,'word/settings.xml') | out-null  
            [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipfile,$pathSettingsRelsFile,'word/_rels/settings.xml.rels') | out-null  

            # Temporäre Files löschen
            del $pathSettingsFile -Force -ErrorAction SilentlyContinue
            del $pathSettingsRelsFile -Force -ErrorAction SilentlyContinue
        }else{
            write-host "Im Dokument '$($file.FullName)' wurde keine externe Vorlage gefunden." -ForegroundColor Magenta  
        }
    }
    # Zipfile-Resourcen freigeben
    $zipfile.Dispose()
}
Wenn man den Vorlagenpfad jedoch nicht entfernen sondern z.B. den Servernamen oder Pfad ändern möchte kann dies mit diesem Script geschehen. Zusätzlich zum Pfad in Zeile 9 sind der alte und der neue Name in Zeilen 11 und 13 anzugeben.
back-to-topVorlagenpfad von Word-Dokumenten ändern/austauschen (nur *.docx / *.docm)
# Ändert den Pfad bzw. Server einer Dokumentvorlage aus OpenXML Word Dokumenten
# Benötigt wird mindestens NET-Framework 4.5 und Powershell 3.0

# benötigte Assemblies laden
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.Filesystem

# Pfad zu den Dateien
$pathFiles = "E:\Ordner\Word-Dokumente"   
# alter Pfad
$oldPath = '\\SERVEROLD\docs'  
# neuer Pfad
$newPath = '\\SERVERNEW\docs'  

$files = dir "$pathFiles\*.doc[xm]" -Recurse -File  
foreach ($file in $files){
    # Word-Dokument als ZIP-Datei im Update-Modus öffnen
    $zipfile = [System.IO.Compression.ZipFile]::Open($file.FullName,[System.IO.Compression.ZipArchiveMode]::Update)
    
    # Temporäre Extrahierungs-Pfade für die Dateien die geändert werden
    $pathSettingsRelsFile = "$pathFiles\settings.xml.rels"  
    
    # Falls die temoporären Dateien existieren lösche sie
    if((Test-Path $pathSettingsRelsFile)){del $pathSettingsRelsFile -Force}
    
    # Einträge der benötigten Dateien aus dem Dokument holen
    $entry1 = $zipfile.Entries | ?{$_.Fullname -eq 'word/_rels/settings.xml.rels'}  

    # Wenn Datei gefunden wurde ...
    if ($entry1){
        # word/_rels/settings.xml.rels extrahieren
        [System.IO.Compression.ZipFileExtensions]::ExtractToFile($entry1,$pathSettingsRelsFile)
        $xml = New-Object XML
        $xml.Load($pathSettingsRelsFile)
        $rels = $xml.Relationships.Relationship | ?{$_.Target -like "*$oldPath*"}  
        if ($rels){
            write-host "Entferne Vorlage aus Dokument '$($file.Fullname)' ..." -ForegroundColor Green  
            $rels | %{$_.Target = $_.Target.Replace($oldPath,$newPath)}
            $xml.Save($pathSettingsRelsFile)
        
            # alte Dateien aus der Word-Datei entfernen
            $entry1.Delete()

            # geänderte Dateien wieder hinzufügen
            [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipfile,$pathSettingsRelsFile,'word/_rels/settings.xml.rels') | out-null  

            # Temporäre Files löschen
            del $pathSettingsRelsFile -Force -ErrorAction SilentlyContinue
        }else{
            write-host "Im Dokument '$($file.FullName)' wurde keine externe Vorlage die dem Server entspricht gefunden." -ForegroundColor Magenta  
        }
    }
    # Zipfile-Resourcen freigeben
    $zipfile.Dispose()
}

Hat hier mit 20 Testdateien einwandfrei funktioniert. Teste es mal bei dir face-smile

Viel Erfolg
Grüße Uwe
Mitglied: colinardo
colinardo 29.07.2014 aktualisiert um 10:55:22 Uhr
Goto Top
Wenn's das dann war, den Beitrag bitte noch auf gelöst setzen nicht vergessen. Merci.
Mitglied: ronvaradeo
ronvaradeo 13.08.2015 um 12:37:44 Uhr
Goto Top
@colinardo

Das Script schaut schon sehr gut aus. Mit Docx funktioniert es sehr gut. Unser derzeitiges Problem ist aber das wir zu 90% mit .doc und .rtf-Dateien arbeiten.

Folgender Fehler wird uns beim Ausführen des Scripts angezeigt (nur für .doc - ohne [xm] im Code):


Ausnahme beim Aufrufen von "Open" mit 2 Argument(en): "Das Ende des Datensatzes im zentralen Verzeichnis wurde nicht gefunden."
In \\Server\Kunde\ChangeDOT_Delete_template.ps1:16 Zeichen:5

back-to-top$zipfile = [System.IO.Compression.ZipFile]::Open($file.FullName,[System.IO.C ...

back-to-top~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : NotSpecified: (face-smile [], MethodInvocationException
+ FullyQualifiedErrorId : InvalidDataException
Mitglied: colinardo
colinardo 13.08.2015 aktualisiert um 13:25:07 Uhr
Goto Top
Hallo @ronvaradeo,
das Script ist nur für die neuen Dokumentformate geeignet! Die alten Binärformate lassen sich mit dieser Methode nicht bearbeiten, da sie intern keine ZIP-Struktur aufweisen ! Steht aber auch FETT gedruckt über den Skripten!

Für die alten Formate benutze die oben bereits verlinkten VBS Skripte.

Grüße Uwe