Search code examples
azurepowershellazure-powershellazure-rest-api

How to use maxresult and nextmarker parameter in Azure File Share List REST API


I am trying to list all the shares present in Storage Account using List Share REST API (https://learn.microsoft.com/en-us/rest/api/storageservices/list-shares#Authorization). but I am having issues with Authorization header with marker parameter. I guess problem is with $stringtosign variable under $nextmarker If Statement.

$StorageAccount = "XXXXX"
$Accesskey = "XXXXXXX==";
$Version="2019-12-12"
$SharePropObj = @()
$date = [System.DateTime]::UtcNow.ToString("R",[Globalization.CultureInfo]::InvariantCulture)

$stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`n"+
           "x-ms-date:$date`nx-ms-version:$version`n" +
           "/$storageAccount/`ncomp:list`nmaxresults:5000" 
$hmacsha = New-Object System.Security.Cryptography.HMACSHA256
$hmacsha.key = [Convert]::FromBase64String($accesskey)
$signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
$signature = [Convert]::ToBase64String($signature)

$headers=@{"x-ms-date"=$date;
           "x-ms-version"= $version;
           "Authorization"= "SharedKey $($storageAccount):$signature";
           "ContentType"="application/xml"
}
$URI = "https://$storageAccount.file.core.windows.net/?comp=list&maxresults=5000"

Try {
    $response = Invoke-RestMethod $URI -Method 'GET' -Headers $headers
    
}Catch {
    "Error Occurred. $_.exception.message"
    }
If ($response){

[xml]$Result = [xml]($response -replace '',"")
    
    $Shareprops = $Result.EnumerationResults.ChildNodes.share | %{

        $share = $_.Name
        $Quota = $_.properties.Quota
        "$share,$Quota"
        }

        $SharePropCol = "ShareName,Quota"
        $SharePropObj += @($SharePropCol,($Shareprops | where {$_.length -gt 1})) | ConvertFrom-Csv -Delimiter ","

        $SharePropObj
        

   $NextMarker = $Result.EnumerationResults.NextMarker.Split("/")[-1]

   if ($NextMarker){

          #Write-Error "Data for some shares are missed"
          #$SharePropObj = @()
          $date = [System.DateTime]::UtcNow.ToString("R",[Globalization.CultureInfo]::InvariantCulture)

        $stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`n"+
                   "x-ms-date:$date`nx-ms-version:$version`n" +
                   "/$storageAccount/`ncomp:list`nmaxresults:5000`nmarker:$NextMarker" 
        $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
        $hmacsha.key = [Convert]::FromBase64String($accesskey)
        $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
        $signature = [Convert]::ToBase64String($signature)

        $headers=@{"x-ms-date"=$date;
                   "x-ms-version"= $version;
                   "Authorization"= "SharedKey $($storageAccount):$signature";
                   "ContentType"="application/xml"
        }
        $URI = "https://$storageAccount.file.core.windows.net/?comp=list&maxresults=5000&marker=$NextMarker"

            $response1 = Invoke-RestMethod $URI -Method 'GET' -Headers $headers
            [xml]$Result = [xml]($response1 -replace '',"")
    
    $Shareprops = $Result.EnumerationResults.ChildNodes.share | %{

        $share = $_.Name
        $Quota = $_.properties.Quota
        "$share,$Quota"
        }


        $SharePropCol = "ShareName,Quota"
        $SharePropObj += @($SharePropCol,($Shareprops | where {$_.length -gt 1})) | ConvertFrom-Csv -Delimiter ","

        $SharePropObj
    
       
   
   
   }

    }

Solution

  • Please change the following code of yours:

    1.for $NextMarker, please change this line of code

    $NextMarker = $Result.EnumerationResults.NextMarker.Split("/")[-1]
    

    to

    $NextMarker = "/$storageAccount/" + $Result.EnumerationResults.NextMarker.Split("/")[-1]
    
    1. in the if ($NextMarker){} code block -> for the $stringToSign, please place the marker:$NextMarker prior to maxresults:5000. Change it like below:

      $stringToSign = "GET`n`n`n`n`n`n`n`n`n`n`n`n"+
                  "x-ms-date:$date`nx-ms-version:$version`n" +
                  "/$storageAccount/`ncomp:list`nmarker:$NextMarker`nmaxresults:5000".
      

    3.in the if ($NextMarker){} code block -> for $URI, please also place the marker=$NextMarker prior to maxresults=5000. Change it like below:

    $URI = "https://$storageAccount.file.core.windows.net/?comp=list&marker=$NextMarker&maxresults=5000"
    

    I have tested it and it works fine. Please let me know if you still have the issue.