Dela via


Skript: Extrahera .msu- och .cab-filer

Den här artikeln innehåller en guide om hur du använder ett PowerShell-skript för att extrahera .msu och .cab filer till en angiven katalog. Skriptet är utformat för att hantera olika scenarier, säkerställa smidiga extraheringar och till och med skapa kataloger om det behövs.

Skriptöversikt

Skriptet behöver två obligatoriska parametrar:

  • Filsökvägen för .msu filen eller .cab
  • Målsökvägen där de extraherade filerna lagras

Skriptet söker efter förekomsten av den angivna filen och målkatalogen och skapar målkatalogen om den inte finns. Skriptet fortsätter sedan att extrahera innehållet i .msu filerna eller .cab och hanterar kapslade .cab filer i processen.

Stegvisa instruktioner för att använda skriptet

  1. Förbered skriptet.

    Kopiera det angivna PowerShell-skriptet till en .ps1 fil (till exempel Extract-MSUAndCAB.ps1).

  2. Kör skriptet.

    Öppna PowerShell som administratör. Gå till katalogen där skriptet sparas. I det här exemplet kör du skriptet genom att köra .\Extract-MSUAndCAB.ps1.

  3. Ange filsökvägar.

    När du uppmanas till det anger du sökvägarna till de .msu eller .cab filer som du vill extrahera. Ange målsökvägen där de extraherade filerna ska sparas.

Här är ett användningsexempel:

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

Viktigt!

Det här exempelskriptet stöds inte under microsofts standardsupportprogram eller -tjänst.

Exempelskriptet tillhandahålls som is utan garanti av något slag. Microsoft frånsäger sig ytterligare alla underförstådda garantier, inklusive, utan begränsning, underförstådda garantier för säljbarhet eller lämplighet för ett visst syfte.

Hela risken som uppstår till följd av användning eller prestanda för exempelskripten och dokumentationen finns kvar hos dig. Under inga omständigheter ska Microsoft, dess författare eller någon annan som är involverad i skapandet, produktionen eller leveransen av skripten vara ansvariga för några som helst skador (inklusive, utan begränsning, skador för förlust av affärsvinster, avbrott i verksamheten, förlust av affärsinformation eller annan ekonomisk förlust) som uppstår på grund av användning av eller oförmåga att använda exempelskripten eller dokumentationen, även om Microsoft har informerats om risken för sådana skador.

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