Compartilhar via


Scripts: extraia arquivos .msu e .cab

Este artigo fornece um guia sobre como usar um script do PowerShell para extrair .msu arquivos em .cab um diretório especificado. O script foi projetado para lidar com vários cenários, garantir extrações suaves e até mesmo criar diretórios, se necessário.

Visão geral do script

O script precisa de dois parâmetros obrigatórios:

  • O caminho do .msu arquivo ou .cab
  • O caminho de destino onde os arquivos extraídos serão armazenados

O script verifica a existência do arquivo especificado e do diretório de destino e cria o diretório de destino se ele não existir. Em seguida, o script prossegue para extrair o conteúdo dos .msu arquivos or .cab e manipula arquivos aninhados .cab no processo.

Instruções passo a passo para usar o script

  1. Prepare o roteiro.

    Copie o script do PowerShell fornecido em um .ps1 arquivo (por exemplo, Extract-MSUAndCAB.ps1).

  2. Execute o script.

    Abra o PowerShell como administrador. Vá para o diretório onde seu script está salvo. Neste exemplo, execute o script executando .\Extract-MSUAndCAB.ps1.

  3. Forneça caminhos de arquivo.

    Quando solicitado, forneça os caminhos para os .msu arquivos ou .cab que você deseja extrair. Especifique o caminho de destino onde os arquivos extraídos devem ser salvos.

Aqui está um exemplo de uso:

powershell -ExecutionPolicy Bypass -File .\Extract-MSUAndCAB.ps1 -filePath "C:\<path>\<yourfile>.msu" -destinationPath "C:\<path>\<destination>"

Importante

Este script de exemplo não tem suporte em nenhum programa ou serviço de suporte padrão da Microsoft.

O script de exemplo é fornecido COMO ESTÁ, sem garantia de qualquer tipo. A Microsoft também se isenta de todas as garantias implícitas, incluindo, sem limitação, quaisquer garantias implícitas de comercialização ou de adequação a uma finalidade específica.

Todo o risco decorrente do uso ou desempenho dos scripts e da documentação de exemplo permanece com você. Em nenhuma circunstância a Microsoft, seus autores ou qualquer outra pessoa envolvida na criação, produção ou entrega dos scripts serão responsáveis por quaisquer danos (incluindo, sem limitação, danos por perda de lucros comerciais, interrupção de negócios, perda de informações comerciais ou outras perdas pecuniárias) decorrentes do uso ou da incapacidade de usar os scripts de exemplo ou a documentação, mesmo que a Microsoft tenha sido avisada da possibilidade de tais danos.

param (
    [Parameter(Mandatory = $true)]
    [string]$filePath,
    [Parameter(Mandatory = $true)]
    [string]$destinationPath
)

# Display the note to the user
Write-Host "==========================="
Write-Host
Write-Host -ForegroundColor Yellow "Note: Do not close any Windows opened by this script until it is completed."
Write-Host
Write-Host "==========================="
Write-Host


# Remove quotes if present
$filePath = $filePath -replace '"', ''
$destinationPath = $destinationPath -replace '"', ''

# Trim trailing backslash if present
$destinationPath = $destinationPath.TrimEnd('\')

if (-not (Test-Path $filePath -PathType Leaf)) {
    Write-Host "The specified file does not exist: $filePath"
    return
}

if (-not (Test-Path $destinationPath -PathType Container)) {
    Write-Host "Creating destination directory: $destinationPath"
    New-Item -Path $destinationPath -ItemType Directory | Out-Null
}

$processedFiles = @{}

function Extract-File ($file, $destination) {
    Write-Host "Extracting $file to $destination"
    Start-Process -FilePath "cmd.exe" -ArgumentList "/c expand.exe `"$file`" -f:* `"$destination`" > nul 2>&1" -Wait -WindowStyle Hidden | Out-Null
    $processedFiles[$file] = $true
    Write-Host "Extraction completed for $file"
}

function Rename-File ($file) {
    if (Test-Path -Path $file) {
        $newName = [System.IO.Path]::GetFileNameWithoutExtension($file) + "_" + [System.Guid]::NewGuid().ToString("N") + [System.IO.Path]::GetExtension($file)
        $newPath = Join-Path -Path ([System.IO.Path]::GetDirectoryName($file)) -ChildPath $newName
        Write-Host "Renaming $file to $newPath"
        Rename-Item -Path $file -NewName $newPath
        Write-Host "Renamed $file to $newPath"
        return $newPath
    }
    Write-Host "File $file does not exist for renaming"
    return $null
}

function Process-CabFiles ($directory) {
    while ($true) {
        $cabFiles = Get-ChildItem -Path $directory -Filter "*.cab" -File | Where-Object { -not $processedFiles[$_.FullName] -and $_.Name -ne "wsusscan.cab" }

        if ($cabFiles.Count -eq 0) {
            Write-Host "No more CAB files found in $directory"
            break
        }

        foreach ($cabFile in $cabFiles) {
            Write-Host "Processing CAB file $($cabFile.FullName)"
            $cabFilePath = Rename-File -file $cabFile.FullName

            if ($cabFilePath -ne $null) {
                Extract-File -file $cabFilePath -destination $directory
                Process-CabFiles -directory $directory
            }
        }
    }
}

try {
    # Initial extraction
    if ($filePath.EndsWith(".msu")) {
        Write-Host "Extracting .msu file to: $destinationPath"
        Extract-File -file $filePath -destination $destinationPath
    } elseif ($filePath.EndsWith(".cab")) {
        Write-Host "Extracting .cab file to: $destinationPath"
        Extract-File -file $filePath -destination $destinationPath
    } else {
        Write-Host "The specified file is not a .msu or .cab file: $filePath"
        return
    }

    # Process all .cab files recursively
    Write-Host "Starting to process CAB files in $destinationPath"
    Process-CabFiles -directory $destinationPath
}
catch {
    Write-Host "An error occurred while extracting the file. Error: $_"
    return
}

Write-Host "Extraction completed. Files are located in $destinationPath"
return $destinationPath