簡體   English   中英

如何在Powershell中驗證文件是否為zip文件

[英]How to verify if a file is a zip file in Powershell

我每月從供應商那里收到要處理的文件集合。 這些文件沒有擴展名,但它們具有一致的命名約定。 但是,缺少擴展名會導致一些問題,有時其中有一個壓縮文件夾,其中包含我要處理的代碼的文件名。 所以,我正在尋找某種方法對每個文件進行布爾檢查,以確認它是否實際上是一個壓縮文件夾。 不同之處在於 Excel 文件可以像壓縮文件夾一樣打開(並且其中包含 docProps、xl、_rels。)

我一直沒有成功嘗試 get-childitem 和 Get-Content。 有沒有辦法對返回 true 的文件進行“測試”,如果它實際上是一個 zip 文件?

Carbon Powershell模塊包含一個cmdlet Test-ZipFile ,它會告訴您它是否是zipfile。

如果您無法使用該模塊,則可以查看文件頭 這有點難看(時間緊迫)但有效:

$contents = [string](get-content -raw -Encoding Unknown -path $filepath).ToCharArray();

[convert]::tostring([convert]::toint32($contents[0]),16);

對於一個已知為ZIP文件的文件,輸出為4b50 ,該文件與簽名的前兩個字節相匹配,相反。

從長遠來看,讓供應商修復他們的系統以提供有關文件的更多信息。 特別是如果它們是你想要的類型。

如果您需要區分Excel(2007+)和真正的ZIP文件,而沒有擴展名,那么您就會陷入困境 - 正如您所知,您可以將.xlsx文件重命名為.zip,它將像其他任何文件一樣打開ZIP文件 - 沒有什么可以區分的。

我最終做了這樣的事情,希望有人發現它很有用:

$ErrorStatus=Start-Process -FilePath $env:7ZipExe -ArgumentList " x $FullFileName -o$env:ProcessingFolder"  -passthru -Wait

If (($ErrorStatus.ExitCode -eq 0) -or ($ErrorStatus.ExitCode -eq $null))
{
    $FileContents=get-childitem -path $FullFileName
    #_rels is a folder in a Word or Excel file when you open it with 7-zip. If it is able to be opened with 7-zip and 
    #  doesn't have that folder, consider the file to be a zip file.
    if (!($FileContents -like "*rels*"))
    {   
        if (!($FileContents -like "*xl*") -and (!($FullFileName.ToLower().EndsWith('.xlsx'))))
        {
            Rename-Item $FullFileName "$FullFileName.xlsx"
        }
        elseif (!($FileContents -like "*word*") -and (!($FullFileName.toLower().EndsWith('.docx')))-and (!($FullFileName.toLower().EndsWith('.xlsx'))))
        {
            Rename-Item $FullFileName "$FullFileName.docx"
        }
    }
    else
    {
        If (!($FileName.ToLower().EndsWith(".zip")))
        {
            Rename-Item $FullFileName "$FullFileName.zip"
            Add-Content $env:LogReportFile "$(Get-Date) - $FileName was a zip file. Added extension."
        }
    }
}

按照上面的答案,由於“!”,我在發布的腳本中遇到了一些問題。 字符在 If 語句中,這對我有用,

我的用例是在朋友的硬盤因斷電而損壞后恢復 DOCX 和 XLSX 文件,他們有一堆 CHK 文件,“unchk”實用程序重命名為 Zip 文件。

請注意此處提到的臨時保存目錄 - 此過程需要解壓縮您的 zip 以讀取內容,因此此代碼需要運行一個 zip 文件夾,然后將每個文件夾解壓縮到臨時文件的單獨目錄中的自己的文件夾中。

    $FolderPath = "C:\FOUND.001\"

Get-ChildItem $FolderPath -Filter *.zip | 
Foreach-Object {
#Write-Output $_.FullName

#If ($_.FullName -eq "C:\FOUND.001\FILE3640.zip"){ TEST LINE, REMOVED AFTER SUCCESSFULLY WORKING ON 1 FILE OF THOUSANDS...
    $FullFileName = $_.FullName
    Write-Output $FullFileName
    $ZipName = $_.BaseName
    

    $TempSaveDirectory = "C:\RecoveryResults\$ZipName"
    Write-Output "Creating $TempSaveDirectory"
    #Make a directory to hold zip contents
    New-Item $TempSaveDirectory -ItemType directory
    
$ErrorStatus=Start-Process -FilePath "C:\Program Files\7-Zip\7z.exe" -ArgumentList " x $FullFileName -o$TempSaveDirectory"  -passthru -Wait

If (($ErrorStatus.ExitCode -eq 0) -or ($ErrorStatus.ExitCode -eq $null))
{
    $FileContents=get-childitem -path $TempSaveDirectory
    #_rels is a folder in a Word or Excel file when you open it with 7-zip. If it is able to be opened with 7-zip and 
    #  doesn't have that folder, consider the file to be a zip file.
    if ($FileContents -like "*rels*")
    {   
    write-output "Found rels folder"
        if ($FileContents -like "*xl*")
        {
            Rename-Item $FullFileName "$FullFileName.xlsx"
            Write-Output "Renamed $FullFileName To Excel"
        }
        elseif ($FileContents -like "*word*")
        {
            Rename-Item $FullFileName "$FullFileName.docx"
            Write-Output "Renamed $FullFileName To Word Doc"
        }
    }
    else
    {
        If (!($FullFileName.ToLower().EndsWith(".zip")))
        {
            
        }
    }
}
}

#}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM