<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic PSTK usage of Get-NcSnapshot with REST API vs ZAPI in Microsoft Virtualization Discussions</title>
    <link>https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/PSTK-usage-of-Get-NcSnapshot-with-REST-API-vs-ZAPI/m-p/452237#M6881</link>
    <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;OnTap 9.12.1P11&lt;/P&gt;&lt;P&gt;FAS2720 &amp;amp; AFF-0300&lt;/P&gt;&lt;P&gt;PSTK : 9.14.1&lt;/P&gt;&lt;P&gt;Prior to our update of OnTAP our scripts to report on snapshot usage ran by simply executing the Get-NcSnapshot cmdlet.&lt;/P&gt;&lt;P&gt;After the upgrade, running our script our script returned errors and research shows that the PSTK checks the version of OnTap and defaults to REST-API rather than ZAPI.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Our script was quickly fixed by forcing ZAPI usage with the -ZAPICALL argument on the Connect-NcController cmdlet.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'd prefer to use the REST-API as I can see ZAPI is now being deprecated.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Using the REST API the&amp;nbsp;Get-NcSnapshot cmdlet usage changes and seems to mandate the use of the -volume argument.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I re-wrote the line in the script to loop through the list of volumes and push the results into a variable.&lt;/P&gt;&lt;P&gt;This is working, but it is exceptionally slow.&lt;/P&gt;&lt;P&gt;One volume (on SSD storage) took over 7 minutes to get a list of snapshots on the volume (there were 32 snapshots).&lt;/P&gt;&lt;P&gt;Another volume took over 22 minutes (again 32 snapshots and again on SSD storage). These timings were obtained by writing out to a log file.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is there a quicker way to get this information?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Old code using ZAPI :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;$snapshots = Get-NcSnapshot -controller $controller &lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;New code using REST API:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;$volumes = Get-NcVol -controller $controller
$snapshots = ForEach ($volume in $volumes){
 Get-NcSnapshot -volume $volume -WarningAction SilentlyContinue
}
&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There is a similar article that references the changes where someone was trying to use the Get-NcSnapshot command and had issues getting the list of snapshots for their volumes (&lt;A href="https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/Powershell-Pipe-issues/td-p/445340" target="_blank"&gt;https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/Powershell-Pipe-issues/td-p/445340&lt;/A&gt;) and I based the new code used above on the information in the article.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 04 Jun 2025 09:39:05 GMT</pubDate>
    <dc:creator>rtx</dc:creator>
    <dc:date>2025-06-04T09:39:05Z</dc:date>
    <item>
      <title>PSTK usage of Get-NcSnapshot with REST API vs ZAPI</title>
      <link>https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/PSTK-usage-of-Get-NcSnapshot-with-REST-API-vs-ZAPI/m-p/452237#M6881</link>
      <description>&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;OnTap 9.12.1P11&lt;/P&gt;&lt;P&gt;FAS2720 &amp;amp; AFF-0300&lt;/P&gt;&lt;P&gt;PSTK : 9.14.1&lt;/P&gt;&lt;P&gt;Prior to our update of OnTAP our scripts to report on snapshot usage ran by simply executing the Get-NcSnapshot cmdlet.&lt;/P&gt;&lt;P&gt;After the upgrade, running our script our script returned errors and research shows that the PSTK checks the version of OnTap and defaults to REST-API rather than ZAPI.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Our script was quickly fixed by forcing ZAPI usage with the -ZAPICALL argument on the Connect-NcController cmdlet.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'd prefer to use the REST-API as I can see ZAPI is now being deprecated.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Using the REST API the&amp;nbsp;Get-NcSnapshot cmdlet usage changes and seems to mandate the use of the -volume argument.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I re-wrote the line in the script to loop through the list of volumes and push the results into a variable.&lt;/P&gt;&lt;P&gt;This is working, but it is exceptionally slow.&lt;/P&gt;&lt;P&gt;One volume (on SSD storage) took over 7 minutes to get a list of snapshots on the volume (there were 32 snapshots).&lt;/P&gt;&lt;P&gt;Another volume took over 22 minutes (again 32 snapshots and again on SSD storage). These timings were obtained by writing out to a log file.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is there a quicker way to get this information?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Old code using ZAPI :&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;$snapshots = Get-NcSnapshot -controller $controller &lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;New code using REST API:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;$volumes = Get-NcVol -controller $controller
$snapshots = ForEach ($volume in $volumes){
 Get-NcSnapshot -volume $volume -WarningAction SilentlyContinue
}
&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;There is a similar article that references the changes where someone was trying to use the Get-NcSnapshot command and had issues getting the list of snapshots for their volumes (&lt;A href="https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/Powershell-Pipe-issues/td-p/445340" target="_blank"&gt;https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/Powershell-Pipe-issues/td-p/445340&lt;/A&gt;) and I based the new code used above on the information in the article.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thank you!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 04 Jun 2025 09:39:05 GMT</pubDate>
      <guid>https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/PSTK-usage-of-Get-NcSnapshot-with-REST-API-vs-ZAPI/m-p/452237#M6881</guid>
      <dc:creator>rtx</dc:creator>
      <dc:date>2025-06-04T09:39:05Z</dc:date>
    </item>
    <item>
      <title>Re: PSTK usage of Get-NcSnapshot with REST API vs ZAPI</title>
      <link>https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/PSTK-usage-of-Get-NcSnapshot-with-REST-API-vs-ZAPI/m-p/452493#M6886</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm not sure what the issue is but have you tried testing how responsive the native REST API is if the Get-NcSnapshot CmdLet is taking an excessively long time to return results? Here's an example:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;Param(
   [Parameter(Mandatory = $True, HelpMessage = "The Cluster name or IP Address")]
   [String]$Cluster,
   [Parameter(Mandatory = $False, HelpMessage = "The Vserver name")]
   [String]$Vserver,
   [Parameter(Mandatory = $False, HelpMessage = "The Volume name")]
   [String]$Volume,
   [Parameter(Mandatory = $True, HelpMessage = "The Credential to authenticate to ONTAP")]
   [ValidateNotNullOrEmpty()]
   [System.Management.Automation.PSCredential]$Credential
)
#'------------------------------------------------------------------------------
Function Get-OntapAuthorization{
   [Alias("Get-OntapAuth")]
   [CmdletBinding()]
   Param(
      [Parameter(Mandatory = $True, HelpMessage = "The Credential to authenticate to ONTAP")]
      [ValidateNotNullOrEmpty()]
      [System.Management.Automation.PSCredential]$Credential
   )
   #'---------------------------------------------------------------------------
   #'Set the authentication header to connect to AIQUM.
   #'---------------------------------------------------------------------------
   $auth    = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Credential.UserName + ':' + $Credential.GetNetworkCredential().Password))
   $headers = @{
      "Authorization" = "Basic $auth"
      "Accept"        = "application/json"
      "Content-Type"  = "application/json"
   }
   Return $headers;
}#'End Function Get-UMAuthorization.
#'------------------------------------------------------------------------------
Function Get-OntapVolume{
   [CmdletBinding()]
   Param(
      [Parameter(Mandatory = $True, HelpMessage = "The Cluster name or IP Address")]
      [String]$Cluster,
      [Parameter(Mandatory = $False, HelpMessage = "The Vserver name")]
      [String]$Vserver,
      [Parameter(Mandatory = $False, HelpMessage = "The Volume name")]
      [String]$Volume,
      [Parameter(Mandatory = $True, HelpMessage = "The Credential to authenticate to ONTAP")]
      [ValidateNotNullOrEmpty()]
      [System.Management.Automation.PSCredential]$Credential
   )
   #'---------------------------------------------------------------------------
   #'Set the headers to authenticate to ONTAP.
   #'---------------------------------------------------------------------------
   $headers = Get-OntapAuthorization -Credential $Credential
   #'---------------------------------------------------------------------------
   #'Set the URL.
   #'---------------------------------------------------------------------------
   [String]$uri     = "https://$Cluster/api/storage/volumes?"
   [Bool]$query     = $False;
   [String]$message = $Null
   If($Volume){
      [String]$uri += "&amp;amp;name=$Volume"
      [Bool]$query  = $True;
   }
   If($Vserver){
      [String]$uri += "&amp;amp;svm.name=$Vserver"
      [Bool]$query  = $True;
   }
   If(-Not($query)){
      [String]$uri = $uri.SubString(0, ($uri.Length -1))
   }Else{
      [String]$uri = $uri.Replace("?&amp;amp;", "?")
   }
   #'---------------------------------------------------------------------------
   #'Get the volumes.
   #'---------------------------------------------------------------------------
   Try{
      $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ErrorAction Stop
      Write-Host $("Enumerated volumes on cluster ""$Cluster"" using URI ""$uri""")
   }Catch{
      Write-Warning -Message $("Failed enumerating volumes on cluster ""$Cluster"" using URI ""$uri"". Error " + $_.Exception.Message + ". Status Code " + $_.Exception.Response.StatusCode.value__)
   }
   Return $response;
}#'End Function Get-OntapVolumes.
#'------------------------------------------------------------------------------
Function Get-OntapSnapshot{
   [CmdletBinding()]
   Param(
      [Parameter(Mandatory = $True, HelpMessage = "The Cluster name or IP Address")]
      [String]$Cluster,
      [Parameter(Mandatory = $True, HelpMessage = "The Volume UUID")]
      [String]$VolumeID,
      [Parameter(Mandatory = $True, HelpMessage = "The Credential to authenticate to ONTAP")]
      [ValidateNotNullOrEmpty()]
      [System.Management.Automation.PSCredential]$Credential
   )
   #'---------------------------------------------------------------------------
   #'Set the headers to authenticate to ONTAP.
   #'---------------------------------------------------------------------------
   $headers = Get-OntapAuthorization -Credential $Credential
   #'---------------------------------------------------------------------------
   #'Set the URL.
   #'---------------------------------------------------------------------------
   [String]$uri = "https://$Cluster/api/storage/volumes/$VolumeID/snapshots?fields=volume.name"
   #'---------------------------------------------------------------------------
   #'Get the Snapshots.
   #'---------------------------------------------------------------------------
   Try{
      $response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -ErrorAction Stop
      Write-Host $("Enumerated snapshots on cluster ""$Cluster"" using URI ""$uri""")
   }Catch{
      Write-Warning -Message $("Failed enumerating snapshots on cluster ""$Cluster"" using URI ""$uri"". Error " + $_.Exception.Message + ". Status Code " + $_.Exception.Response.StatusCode.value__)
   }
   Return $response;
}#'End Function Get-OntapSnapshots.
$processTimer = [System.Diagnostics.Stopwatch]::StartNew()
#'------------------------------------------------------------------------------
#'Set the certificate policy and TLS version.
#'------------------------------------------------------------------------------
Add-Type @"
   using System.Net;
   using System.Security.Cryptography.X509Certificates;
   public class TrustAllCertsPolicy : ICertificatePolicy {
   public bool CheckValidationResult(
   ServicePoint srvPoint, X509Certificate certificate,
   WebRequest request, int certificateProblem) {
      return true;
   }
}
"@
[System.Net.ServicePointManager]::SecurityProtocol  = [System.Net.SecurityProtocolType]'Tls12'
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
#'------------------------------------------------------------------------------
#'Enumerate the Volumes.
#'------------------------------------------------------------------------------
[String]$command = "Get-OntapVolume -Cluster $Cluster "
If($Vserver){
   [String]$command += "-Vserver $Vserver "
}
If($Volume){
   [String]$command += "-Volume $Volume "
}
[String]$command += "-Credential `$Credential"
$volumes = Invoke-Expression -Command $command
#'------------------------------------------------------------------------------
#'Enumerate the snapshots on the volumes.
#'------------------------------------------------------------------------------
ForEach($volumeID In $volumes.records.uuid){
   $snapshots = Get-OntapSnapshot -Cluster $Cluster -VolumeID $volumeID -Credential $Credential
   $snapshots.records | Format-List
}
#'------------------------------------------------------------------------------
#'Display the duration.
#'------------------------------------------------------------------------------
$processTimer.Stop()
$ts = $processTimer.Elapsed
$elapsedTime = "{0:00}:{1:00}:{2:00}.{3:00}" -f $ts.Hours, $ts.Minutes, $ts.Seconds, ($ts.Milliseconds / 10)
Write-Host $("Enumerated Snapshots - Elapsed Time $elapsedTime")
#'------------------------------------------------------------------------------&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Usage:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;# Get all snapshots on a volume:

PS C:\Scripts\PowerShell\Projects\ONTAP\GetSnapshots&amp;gt; .\GetSnapshots.ps1 -Cluster cluster1 -Vserver svm1_cluster1 -Volume volume_001 -Credential $credential

# Get all snapshots on all volumes on a vserver:

PS C:\Scripts\PowerShell\Projects\ONTAP\GetSnapshots&amp;gt; .\GetSnapshots.ps1 -Cluster cluster1 -Vserver svm1_cluster1 -Credential $credential

# Get all snapshots on all volumes on all vservers on a cluster:

PS C:\Scripts\PowerShell\Projects\ONTAP\GetSnapshots&amp;gt; .\GetSnapshots.ps1 -Cluster cluster1 -Credential $credential&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'll look into it further as I've got some snapshot automation (currently using ZAPI) that will break when migrating to REST by the sounds of it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hope this gives you some ideas in the interim.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;/Matt&lt;/P&gt;</description>
      <pubDate>Thu, 02 May 2024 13:53:46 GMT</pubDate>
      <guid>https://community.netapp.com/t5/Microsoft-Virtualization-Discussions/PSTK-usage-of-Get-NcSnapshot-with-REST-API-vs-ZAPI/m-p/452493#M6886</guid>
      <dc:creator>mbeattie</dc:creator>
      <dc:date>2024-05-02T13:53:46Z</dc:date>
    </item>
  </channel>
</rss>

