excel - Excel 密码保护的 Powershell 测试

标签 excel powershell

我有一个脚本,用于转换和密码保护多个 Excel 文档。旧文档采用 Excel 2003 格式,我可以很好地转换/密码保护它们。当我查看最新的文档时,这些文件采用 Excel 2010 格式,因此只需要密码保护。我正在尝试找到一种方法来检查 xlsx 文件是否已受密码保护,因此可以跳过(可能是已处理的 2003 文件)。如果我打开文件,因为它有密码,那么即使我将可见属性设置为 false,Excel 也会弹出并在继续之前要求输入密码。我需要一种自动检查的方法,因为有很多文件需要检查。这是我到目前为止的代码:

[cmdletbinding()]
param (
    [parameter(mandatory=$true)][string]$Path,
    [parameter(mandatory=$false)][switch]$Visible,
    [parameter(mandatory=$false)][string]$ToFolder,
    [parameter(mandatory=$false)][string]$Password,
    [parameter(mandatory=$false)][switch]$Force
)
begin {
    Add-Type -AssemblyName Microsoft.Office.Interop.Excel
    $xlFixedFormat = [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault
    Write-Verbose 'Opening Excel COM object.'
    $Excel = New-Object -ComObject excel.application
    if ($Visible -eq $true) {
      $Excel.visible = $true
    } else {
      $Excel.visible = $false
      $Excel.DisplayAlerts = $false
      $Excel.ScreenUpdating = $false
      $Excel.UserControl = $false
      $Excel.Interactive = $false
    }
    $filetype = "*xls"
} process {
    if (Test-Path -Path $Path) {
        Get-ChildItem -Path $Path -Include '*.xls' -recurse | ForEach-Object {
            Write-Verbose "Processing $($_.Basename)"
            if ($ToFolder -ne '') {
                $FilePath = Join-Path $ToFolder $_.BaseName
                $FilePath += ".xlsx"
            } else {
                $FilePath = ($_.fullname).substring(0, ($_.FullName).lastindexOf("."))
                $FilePath += ".xlsx"
            }
            if (!(Test-Path $FilePath) -Or $Force) {
              Write-Verbose "Opening $($_.Basename)"
              $WorkBook = $Excel.workbooks.open($_.fullname)
              Write-Verbose "Saving $($_.Basename) to $FilePath with password $Password"
              $WorkBook.saveas($FilePath, $xlFixedFormat, $Password)
              Write-Verbose "Closing $($_.Basename)"
              $WorkBook.close()
            } else {
              Write-Verbose "$($_.Basename) already converted."
            }
        }
    } else {
        return 'No path provided or access has been denied.'
    }
} end {
    Write-Verbose 'Closing Excel'
    $Excel.Quit()
    $Excel = $null
    [gc]::collect()
    [gc]::WaitForPendingFinalizers()
}

最佳答案

很抱歉我忘记来更新这个。对于 future 的任何人来说,我最终所做的是将文件作为数据流打开并检查文件签名(文件的前 4 个字节)。标准 2010 Office 文档(.xlsx、.docx 等)实际上是 Zip 文件,并且具有标准 zip 文件签名。此 Powershell 代码为我提供了一个带有该 sig 的字节数组:

$sig = [Byte[]] (0x50,0x4b,0x03,0x04)

另一方面,加密的 Office 文档具有所有 Office 文档通用的标准文件签名,例如最近 5 个版本。因此,此代码片段显示了我如何从每个文档中读取 sig 以检查并测试它是否未加密(具有上面的 sig):

$bytes = get-content $_.fullname -encoding byte -total 4
if (@(compare-object $sig $bytes -sync 0).length -eq 0) {
  # process unencrypted file
}

majkinetor 的上述答案也可以。

关于excel - Excel 密码保护的 Powershell 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36555094/

相关文章:

Excel函数将所有实际成本加上没有计算列的空白行的估计值相加

excel - 如何根据电子表格值更改 XML 中的多个引用标签

使用 tcltk2 库在 R 中通过 DDE 检索数据

excel - 查找 Countif 排除某些列

powershell - 从非 powershell 终端传递 bool powershell 参数

windows - 在 64 位 Windows 上运行 cURL

python - Pandas 中基于规则的列重命名

windows - 如何将版本和源信息添加到 powershell 别名?

powershell - 执行 powershell 脚本 ".ps1"的最佳方式

powershell - 将函数的结果返回到运行时脚本