tsukaito
Goto Top

Custom File Properties auslesen

Hallo zusammen,

wir haben aktuell das Problem, dass wir von einer Domäne in eine andere umgezogen sind. Dabei ist der Klassiker die Fileserver-Migration. In der alten Domäne wan Microsoft Azure Protection als DRM aktiv. Jetzt haben wir nach der Migration immer wieder Dateien, welche das Flag noch haben. Im Windows-Explorer kann ich die Dateien identifizieren, da diese einen "Custom"-Reiter in den Optionen zeigen und hier MSIP-Labels zu sehen sind.
msip
Ich möchte diese nicht entfernen sondern nur die Dateien finden, welche das Flag noch besitzen. Ich habe bereits versucht mit Powershell und VBS an diese "Custom Properties" zu kommen, aber finde keinen Weg. Wenn ich sie im Expleorer sehe, dann muss ich diese doch auch per Skript auslesen können?
Ich habe hier schon mit dem Module APIService und dem Standard ItemPropery mein Glück versucht. Im VBS habe ich einen Weg gefunden mir ein Application Object zu erstellen, welches dann die Datei öffnet und prüft ob die Labels vorhanden sind. Das dauert aber bei der Menge an Dateien unendlich lange. face-sad
Hat jemand ein bessere Idee oder ein Script, wie ich an diese Properties komme?

Vielen Dank und schöne Grüße
Tsuakito

Content-ID: 3739040890

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

Ausgedruckt am: 23.11.2024 um 12:11 Uhr

13910172396
13910172396 22.07.2024 aktualisiert um 16:59:51 Uhr
Goto Top
Hi.
Sind das ausschließlich Office-Dateien also *.docx *.xlsx usw.? Den Reiter zeigt Windows in der Regel nur an wenn es den Dokumenttyp erkennt oder eine spezielle Explorer-Erweiterung installiert ist wenn es sich um non Office Files handelt.

Gruß Strods
tsukaito
tsukaito 22.07.2024 aktualisiert um 17:02:03 Uhr
Goto Top
Hallo Strods,
korrekt, das sind ausschließlich Office-Dateien. Es könnten auch PDFs dazukommen, aber die ersten Anfragen waren jetzt nur Office-Dateien und ich möchte mir einen Überblick verschaffen, ob es 20 oder 2.000 Dateien sind. Nach der ermittelten Menge würde ich die Lösung designen.

Grüße
Tsukaito
13910172396
13910172396 22.07.2024 aktualisiert um 18:01:49 Uhr
Goto Top
Dann kannst du das aus den Office Files raus holen indem du sie als ZIP-Files behandelst, hier als Beispiel für *.docx und *.xlsx, geht aber genauso mit *.pptx, *.dotm, *.dotx, *.xlsm usw., einfach nur den Filter in der Get-ChidlItem Zeile anpassen.
Das geht wesentlich schneller als ein COM-Object zu erstellen da hier nur das entsprechende Custom Property XML File extrahiert und ausgewertet wird.
# Quellordner
$folder = 'D:\archiv'  
# ------------------------
Add-Type -AssemblyName System.IO.Compression
Add-Type -AssemblyName System.IO.Compression.Filesystem
$ErrorActionPreference = 'Stop'  
# Dateien durchlaufen
$files = foreach($file in Get-ChildItem -LiteralPath $folder -File -Include *.xlsx,*.docx -Recurse){
    # Datei als ZIP-File öffnen
    $zipfile = [System.IO.Compression.ZipFile]::Open($file.Fullname,[System.IO.Compression.ZipArchiveMode]::Read)
    # temporären Dateipfad im Temp-Verzeichnis erstellen
    $tmp = join-path $env:TEMP ([IO.Path]::GetRandomFileName())    
    try{
        # Extrahiere die "custom.xml" die die custom properties enthält 
        $zipfile.Entries | ?{$_.FullName -eq 'docProps/custom.xml'} | %{  
            # extrahiere das XML-File in eine temporäre Datei
            [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$tmp)
            # suche nach den custom properties in der XML Datei die mit MSIP_* beginnen
            if (Select-XML -LiteralPath $tmp -XPath "//ns:property[starts-with(@name,'MSIP_')]" -Namespace @{ns='http://schemas.openxmlformats.org/officeDocument/2006/custom-properties'}){  
                # gib die Datei zurück wenn mindestens eine Property gefunden wurde
                $file
            }
        }
    }finally{
        # aufräumen
        $zipfile.Dispose()
        Remove-Item -LiteralPath $tmp -Force -EA SilentlyContinue
    }
}
# Dateien ausgeben die MSIP Properties besitzen.
$files

Gruß Strods
tsukaito
tsukaito 23.07.2024 um 10:36:50 Uhr
Goto Top
Hallo Strods,

die Idee ist richtig gut, aber leider funktioniert das entpacken nicht. Ich erhalte einen Error in Zeile 10. Wenn ich dem Fehler nachgehe, dann zeigt er, dass das Format kein ZIP-Format wäre oder die Datei beschädigt ist.
Ich habe dann versucht das Ganze auf "Expand-Archive" umzuschreiben, aber auch hier sagt er, dass nur ZIP das unterstützte Format wäre und entpackt die Datei nicht
Schade...die Idee war echt gut, außer Du hast noch einen Fix dafür...

Grüße
Tsuakito
13910172396
13910172396 23.07.2024 aktualisiert um 11:22:28 Uhr
Goto Top
Hier funktioniert das obige Skript einwandfrei mit über 200 Testfiles! Aber Achtung es werden mit dieser Methode nur die neuen OpenXML Formate unterstützt, nicht die alten binären Formate wie *.xls *.doc !! Denn die hatten intern noch keine ZIP-Struktur, die bekommst du nur über die COM Methode oder eine speziellen Parser ausgelesen.
Wenn das so alte Files sein sollten würde ich eh eine Konvertierung in die neuen Formate empfehlen.

Ich habe dann versucht das Ganze auf "Expand-Archive" umzuschreiben
Der Vorteil meiner Methode ist das man nicht alle Bestandteile der Datei extrahieren muss sondern man explizit nur die eine benötigte XML-Datei damit extrahiert, Expand-Archive extrahiert ja immer gleich alles und das ist bei größeren Files nicht gerade effizient.
tsukaito
Lösung tsukaito 24.07.2024 aktualisiert um 17:02:05 Uhr
Goto Top
Hallo Strods,
ich habe mich heute noch mal hingesetzt und das mit dem ZIP getestet - ich bekomme immer eine Fehlermeldung.
Ich habe dann das mit vorliegende VBS in Powershell übersetzt und konnte jetzt die Dateien mit dem Label ermitteln.
Durch das Excel-Object wird die Bearbeitung langsamer aber es funktioniert und ich habe meine List.
Hier mein Code, falls das jemand mal benötigt. Ist jetzt nicht super schön geschrieben aber funktioniert.

<# 
.SYNOPSIS
    Get Excel Document Custom Properties

.DESCRIPTION 
    Scrip to open excel files and read the custom properties

.COMPONENT 
    No other powershell module needed
#>

# Function to get Office Document Custom Properties
function Get-OfficeDocCustomProperties {
    [OutputType([HashTable])]
    Param
    (
         [Parameter(Mandatory=$true, Position=2)]
         [System.__ComObject] $Document
    )
 
    $result = @{}
    $binding = "System.Reflection.BindingFlags" -as [type]  
    $properties = $Document.CustomDocumentProperties
    foreach($property in $properties)
    {
        $pn = [System.__ComObject].invokemember("name",$binding::GetProperty,$null,$property,$null)  
        trap [system.exception]
        {
            continue
        }
        $result.Add($pn, [System.__ComObject].invokemember("value",$binding::GetProperty,$null,$property,$null))  
    }
 
    return $result
}

# Parameters
$Folder = "\\xxxx\xxxx\xxxx"  
$LogFile = "C:\temp\MSIP_Files.txt"  

# Get all Excel-Files
$Files = Get-ChildItem -LiteralPath $folder -File -Recurse -Filter *.xls*

# Create Excel Object
$excel = New-Object -Com Excel.Application

# File loop to get custom properties
foreach($file in $Files){

    Write-Host "Processing: "$file.FullName  

    # Open Workbook read-only
    $wb = $excel.Workbooks.Open($file.FullName, $null, $true)

    # Get Custom Properties
    $CustomProperties = ""  
    $CustomPropertiesKey = ""  
    $CustomProperties = Get-OfficeDocCustomProperties $wb

    #O utput Custom Properties
    $CustomProperties | ft -AutoSize

    # Check if MSIP-Label in custom prperty key
    foreach($CustomPropertiesKey in $CustomProperties.Keys){
        if($CustomPropertiesKey -like "MSIP_Label_*"){  

            # Finding MSIP_Label -> output filname to Logfile -> break foreach and process nex file
            $file.FullName | Out-File $LogFile -Append
            break
        }
    }
    # Close Workbook (not Excel App)
    $wb.Close()
}

# Close Excel
$excel.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)

Vielen Dank für die guten Ideen und die Unterstützung!
Viele Grüße
Tsukaito