BigIP F5 UCS Backup via RestAPI and PowerShell

328 views Asked by At

I am trying to back up the BigIP F5 device using RestAPI/PowerShell and I can't figure out how to download a "Partial Content"-based file.

I can grab the 1st chunk using:

$result = Invoke-WebRequest -Uri "https://$server/mgmt/shared/file-transfer/ucs-downloads/RomanTest.UCS" -Method Get -Headers $headers

Then I need to grab all the other chunks, right?

So, I am looking for the total file size:

$fileLength = ($result.Headers."Content-Range" -split "/")[-1]

Then I am trying to save it but I can't understand what should I put in the $file.Write?

$index = 0; $start = 0; $end = 0
$maxloops = [Math]::Round([Math]::Ceiling($fileLength / $partSizeBytes))

$fileName = "C:\Temp\Roman\RomanTest$(Get-Date -Format yyMMdd_HHmmss).ucs"
$file = [System.IO.FileStream]::new($fileName, [System.IO.FileMode]::Create)



    while ($fileLength -gt ($end + 1)) 
    {
        $start = $index * $partSizeBytes
        if (($start + $partSizeBytes - 1 ) -lt $fileLength) 
        {
            $end = ($start + $partSizeBytes - 1)
        }
        else 
        {
            $end = ($start + ($fileLength - ($index * $partSizeBytes)) - 1)
        }

        
        $headers = @{    
            "Content-Type" = "application/json"
            "X-F5-Auth-Token" = "$token"
            'Content-Range' = "$start-$end/$fileLength"
        }

        Write-Host "Bytes $start-$end/$fileLength | Index: $($index.ToString("000")) and ChunkSize: $partSizeBytes"

        $result = Invoke-WebRequest -Uri "https://$server/mgmt/shared/file-transfer/ucs-downloads/RomanTest.UCS" -Method Get -Headers $headers
        [byte[]]$data = $result.Content

        Write-Host "$start - $($end-$start)" 

        $file.Write($data, ?????, ?????)
        $file.Close()       
    
        $index++
    
        Write-Host "Percentage Complete: $([Math]::Ceiling($index/$maxloops*100)) %"
    }
$file.Close()

Any help appreciated

1

There are 1 answers

3
Roman Melekh On

Okay, it looks like this is the way to solve the problem, any comments are welcome!

function Start-F5ArchiveDownload
{
    param 
    (
        [Parameter(Mandatory = $true)][string]$token,        
        [Parameter(Mandatory = $true)][string]$server,
        [Parameter(Mandatory = $true)][string]$UCSFileName,        
        [Parameter(Mandatory = $true)][string]$LocalFileName
    )
    
    $headers = @{
        "Content-Type" = "application/json"
        "X-F5-Auth-Token" = "$token"
    }

    $result = Invoke-WebRequest -Uri "https://$server/mgmt/shared/file-transfer/ucs-downloads/$UCSFileName" -Method Get -Headers $headers

    if ($result.StatusCode -eq "206" -and $result.StatusDescription -eq "Partial Content")
    {
        Write-Host "This is a big file, will be transferred by chunks"
        [int]$fileLength = ($result.Headers."Content-Range" -split "/")[-1]
        Write-Host File size: $($fileLength.ToString("#,#"))
    }

    $partSizeBytes = 1048575 
    $index = 0; $start = 0; $end = 0
    
    $maxloops = [Math]::Round([Math]::Ceiling($fileLength / $partSizeBytes))

    $file = [System.IO.FileStream]::new($LocalFileName, [System.IO.FileMode]::Append)

    while ($fileLength -gt ($end + 1)) 
    {
        $start = $index * $partSizeBytes
        if (($start + $partSizeBytes - 1 ) -lt $fileLength) 
        {
            $end = ($start + $partSizeBytes - 1)
        }
        else 
        {
            $end = ($start + ($fileLength - ($index * $partSizeBytes)) - 1)
        }
        
        $headers = @{    
            "Content-Type" = "application/json"
            "X-F5-Auth-Token" = "$token"
            "Content-Range" = "$start-$end/$fileLength"
        }

        Write-Host "Bytes $start-$end/$fileLength | Index: $($index.ToString("000")) and ChunkSize: $partSizeBytes"

        $result = Invoke-WebRequest -Uri "https://$server/mgmt/shared/file-transfer/ucs-downloads/$UCSFileName" -Method Get -Headers $headers
        
        [byte[]]$data = $result.Content

        Write-Host "$start - $($end-$start)" 

        $file.Write($data, 0, $($result.Content.LongLength))
            
        $index++
    
        Write-Host "Percentage Complete: $([Math]::Ceiling($index/$maxloops*100)) %"
    }

    $file.Close()
}