ONTAP Discussions

Powershell Toolkit 9.14.1 Snapmirror Relationship does not work

Chuckme
5,308 Views

We upgraded the Powershell Toolkit from version 4.1.0 to version 9.14.1. Prior to the upgrade,  in Snapmirror Resync scripts,

we used the $Snapmirror.MirrorState (snapmirrored)  and $Snapmirror.RelationshipStatus (idle) to indicate the completion of a transfer. Subsequent to the upgrade, both  $Snapmirror.MirrorState  and $Snapmirror.RelationshipStatus always show a value of "Snapmirrored", even after the transfer has completed and the actual value of  $Snapmirror.RelationshipStatus is "idle". This is my first  interaction with the Community so I am not sure about the procedure  for requesting assistane, but I would like to ask whether anyone has experienced this issue.

1 ACCEPTED SOLUTION

mbeattie
5,027 Views

Hi Chuck,

 

Here's an example of SnapMirror Resync for SVM-DR. Would be easy enough to add in the parameters you need if you want to resync individual volumes. It connects to the destination cluster, checks that the snapmirror relationship is broken-off, invokes a snapmirror resync and calls a function to check the snapmirror status in a loop until completed or a timeout value is exceeded. Usage example:

 

PS E:\Scripts\PowerShell\Projects\SnapMirrorResync> .\SnapMirrorResync.ps1 -DestinationCluster cluster2.testlab.local -DestinationVserver vserver3_dr -WaitInterval 3 -TimeOut 300
[2024-02-27 16:03:43.543],[INFO],Enumerated Cached Credentials for destination cluster "cluster2.testlab.local"
[2024-02-27 16:03:43.856],[INFO],Connect to cluster "cluster2.testlab.local"
[2024-02-27 16:03:43.934],[INFO],Executed Command: Get-NcSnapmirror -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:43.949],[INFO],The vserver "vserver3_dr" is in a "idle" status and "broken-off" state
[2024-02-27 16:03:44.168],[INFO],Executed Command: Invoke-NcSnapmirrorResync -Destination "vserver3_dr:" -Source "vserver3:" -ErrorAction Stop
[2024-02-27 16:03:44.184],[INFO],Resynced SnapMirror relationship. Source vserver "vserver3". Destination vserver "vserver3_dr" on cluster "cluster2.testlab.local"
[2024-02-27 16:03:44.231],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:44.246],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:47.293],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:47.308],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:50.370],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:50.386],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:53.429],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:53.460],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:56.485],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:56.501],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:59.553],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:59.569],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:02.618],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:02.634],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:05.681],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:05.697],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:08.733],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:08.764],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:11.818],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:11.834],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:14.924],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:14.940],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:17.990],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:18.006],[INFO],The destination vserver "vserver3_dr:" is in a "idle" and "snapmirrored" snapmirror state
[2024-02-27 16:04:18.021],[INFO],The destination vserver "vserver3_dr:" reached an "idle" status and "snapmirrored" state within the timeout of "300" seconds
[2024-02-27 16:04:18.021],[INFO],Waited a total of "36" seconds for the destination vserver "vserver3_dr:" to reach an "idle" status and "snapmirrored" state
[2024-02-27 16:04:18.037],[INFO],The destination vserver "vserver3_dr" reached an "idle" status and a "snapmirrored" state within the timeout of "300" seconds

Note: This assumes you have cached credentials using the "Add-NcCredential" Cmdlet.

 

Here is the source code, you could do this in a lot less lines of code but I've included logging and error checking...

 

Source Code:

 

Param(
   [Parameter(Mandatory=$True, HelpMessage="The destination cluster name or IP Address")]
   [String]$DestinationCluster,
   [Parameter(Mandatory=$True, HelpMessage="The destination Vserver name")]
   [String]$DestinationVserver,
   [Parameter(Mandatory=$False, HelpMessage="The desired snapmirror status")]
   [ValidateSet("idle")]
   [String]$SnapMirrorStatus="idle",
   [Parameter(Mandatory=$False, HelpMessage="The desired snapmirror state")]
   [ValidateSet("snapmirrored")]
   [String]$SnapMirrorState="snapmirrored",
   [Parameter(Mandatory=$False, HelpMessage="The Snapshot copy on the source to use as the basis for the update")]
   [String]$SourceSnapshot,
   [Parameter(Mandatory=$False, HelpMessage="Specifies the upper bound, in bytes per second, at which data is transferred between clusters. The default is unlimited (0) which permits the SnapMirror relationship to fully utilize the available network bandwidth")]
   [Int64]$MaxTransferRate,
   [Parameter(Mandatory=$False, HelpMessage="By default all snapshots on the destination that are newer than the latest common snapshot will be deleted. If specified, newer snapshots are retained")]
   [Bool]$Preserve,
   [Parameter(Mandatory=$False, HelpMessage="If specified, the resync time is reduced because the resync does not incur storage efficiency overhead before the transfer of new data. Specifying this parameter is recommended if the source of the resync does not have volume efficiency enabled or if reducing resync time is more important than preserving all possible storage efficiency. When this parameter is specified, resync does not preserve the storage efficiency of the new data with existing data over the wire and on the destination. This parameter is not supported for data protection and load-sharing relationships")]
   [Bool]$QuickResync,
   [Parameter(Mandatory=$False, HelpMessage="If specified, newer snapshots are retained")]
   [Bool]$IsAutoExpandEnabled,
   [Parameter(Mandatory=$True, HelpMessage="The total Number of seconds to wait")]
   [ValidateRange(1,86400)]
   [Long]$TimeOut,
   [Parameter(Mandatory=$True, HelpMessage="The number of seconds to wait in between checks")]
   [ValidateRange(1,600)]
   [Long]$WaitInterval
)
#'------------------------------------------------------------------------------
Function Get-IsoDateTime{
   Return (Get-IsoDate) + " " + (Get-IsoTime)
}#'End Function Get-IsoDateTime.
#'------------------------------------------------------------------------------
Function Get-IsoDate{
   Return Get-Date -uformat "%Y-%m-%d"
}#'End Function Get-IsoDate.
#'------------------------------------------------------------------------------
Function Get-IsoTime{
   #Return Get-Date -uformat "%H:%M:%S"
   Return Get-Date -Format HH:mm:ss.fff
}#'End Function Get-IsoTime.
#'------------------------------------------------------------------------------
Function Write-Log{
   Param(
      [Switch]$Info,
      [Switch]$Error,
      [Switch]$Debug,
      [Switch]$Warning,
      [String]$Message
   )
   #'---------------------------------------------------------------------------
   #'Set the default log type if not provided.
   #'---------------------------------------------------------------------------
   If((-Not($Info)) -And (-Not($Debug)) -And (-Not($Warning)) -And (-Not($Error))){
      [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[INFO`]," + $Message)
   }
   #'---------------------------------------------------------------------------
   #'Add an entry to the log file and disply the output. Format: [Date],[TYPE],MESSAGE
   #'---------------------------------------------------------------------------
   [String]$lineNumber = $MyInvocation.ScriptLineNumber
   Try{
      If($Error){
         If([String]::IsNullOrEmpty($_.Exception.Message)){
            [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[ERROR`],`[LINE $lineNumber`]," + $Message)
         }Else{
            [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[ERROR`],`[LINE $lineNumber`]," + $Message + ". Error " + $_.Exception.Message)
         }
      }ElseIf($Info){
         [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[INFO`]," + $Message)
      }ElseIf($Debug){
         [String]$line = $("`[" + $(Get-IsoDateTime) + "`],`[DEBUG`],`[LINE $lineNumber`]," + $Message)
      }ElseIf($Warning){
         [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[WARNING`],`[LINE $lineNumber`]," + $Message)
      }
      #'-----------------------------------------------------------------------
      #'Display the console output.
      #'-----------------------------------------------------------------------
      If($Error){
         If(-Not([String]::IsNullOrEmpty($_.Exception.Message))){
            Write-Host $($line + ". Error " + $_.Exception.Message) -Foregroundcolor Red
         }Else{
            Write-Host $line -Foregroundcolor Red
         }
      }ElseIf($Warning){
         Write-Host $line -Foregroundcolor Yellow
      }ElseIf($Debug){
         Write-Host $line -Foregroundcolor Magenta
      }Else{
         Write-Host $line -Foregroundcolor White
      }
      Add-Content -Path "$scriptLogPath.log" -Value $line -ErrorAction Stop
      If($Error){
         Add-Content -Path "$scriptLogPath.err" -Value $line -ErrorAction Stop
      }
   }Catch{
      Write-Warning "Could not write entry to output log file ""$scriptLogPath.log"". Log Entry ""$Message"""
   }
}#'End Function Write-Log.
#'------------------------------------------------------------------------------
Function Wait-SnapMirrorResync{
   Param(
      [Parameter(Mandatory=$False, HelpMessage="The source cluster name or IP Address")]
      [String]$SourceCluster,
      [Parameter(Mandatory=$True, HelpMessage="The source vserver")]
      [String]$SourceVserver,
      [Parameter(Mandatory=$True, HelpMessage="The destination cluster name or IP Address")]
      [String]$DestinationCluster,
      [Parameter(Mandatory=$True, HelpMessage="The destination vserver")]
      [String]$DestinationVserver,
      [Parameter(Mandatory=$True, HelpMessage="The desired snapmirror status")]
      [String]$SnapMirrorStatus,
      [Parameter(Mandatory=$True, HelpMessage="The desired snapmirror state")]
      [String]$SnapMirrorState,
      [Parameter(Mandatory=$True, HelpMessage="The total Number of seconds to wait")]
      [Long]$TimeOut,
      [Parameter(Mandatory=$True, HelpMessage="The number of seconds to wait in between checks")]
      [Long]$WaitInterval
   )
   #'---------------------------------------------------------------------------
   #'Wait for the SnapMirror operation to complete or until the timeout is exceeded.
   #'---------------------------------------------------------------------------
   [Long]$waited           = 0
   [Long]$timeWaited       = $waited
   [Bool]$completionStatus = $False
   Do{
      [Long]$timeWaited += [Long]($waited + $waitInterval)
      [String]$command = "Get-NcSnapmirror -SourceLocation ""$SourceVserver`:"" -DestinationLocation ""$DestinationVserver`:"" -VserverContext $DestinationVserver -ErrorAction Stop"
      #'------------------------------------------------------------------------
      #'Invoke the command to check the snapmirror status for the destination path.
      #'------------------------------------------------------------------------
      Try{
         $result = Invoke-Expression -Command $command -ErrorAction Stop
         Write-Log -Info -Message "Executed Command`: $command"
      }Catch{
         Write-Log -Error -Message "Failed executing command`: $command"
         Break;
      }
      #'------------------------------------------------------------------------
      #'Check the snapmirror status for the destination path.
      #'------------------------------------------------------------------------
      Write-Log -Info -Message $("The destination vserver ""$DestinationVserver`:"" is in a """ + $result.Status + """ and """ + $result.MirrorState + """ snapmirror state")
      If(($result.Status -eq $SnapMirrorStatus -And $result.MirrorState -eq $SnapMirrorState) -And ($timeWaited -le $timeOut) -And $timeOut -gt 0){
         Break;
      }
      Start-Sleep -Seconds $waitInterval
   }Until(($result.Status -eq $SnapMirrorStatus -And $result.MirrorState -eq $SnapMirrorState) -Or (($timeWaited -ge $timeOut) -And $timeOut -gt 0))
   #'---------------------------------------------------------------------------
   #'Display the destination snapmirror state and set the completion status.
   #'---------------------------------------------------------------------------
   If(($result.Status -eq $SnapMirrorStatus -And $result.MirrorState -eq $SnapMirrorState) -And ($timeWaited -lt $timeOut)){
      [Bool]$completionStatus = $True
      Write-Log -Info -Message "The destination vserver ""$DestinationVserver`:"" reached an ""$SnapMirrorStatus"" status and ""$SnapMirrorState"" state within the timeout of ""$timeOut"" seconds"
      Write-Log -Info -Message "Waited a total of ""$timeWaited"" seconds for the destination vserver ""$DestinationVserver`:"" to reach an ""$SnapMirrorStatus"" status and ""$SnapMirrorState"" state"
   }
   #'---------------------------------------------------------------------------
   #'Raise an error if the timeout is exceeded.
   #'---------------------------------------------------------------------------
   If($timeWaited -ge $timeOut -And $timeOut -gt 0){
      Write-Log -Error -Message "The destination vserver ""$DestinationVserver`:"" did not reach an ""$SnapMirrorStatus"" status and ""$SnapMirrorState"" state within the timeout of ""$timeOut"" seconds"
   }
   Return $completionStatus;
}#End Function
#'------------------------------------------------------------------------------
#'Initialization Section. Define Global Variables.
#'------------------------------------------------------------------------------
[String]$scriptPath     = Split-Path($MyInvocation.MyCommand.Path)
[String]$scriptSpec     = $MyInvocation.MyCommand.Definition
[String]$scriptBaseName = (Get-Item $scriptSpec).BaseName
[String]$scriptName     = (Get-Item $scriptSpec).Name
[String]$scriptLogPath  = $("$scriptPath\Logs\" + (Get-IsoDate))
#'------------------------------------------------------------------------------
#'Enumerate the Cached Credentials for the destination cluster.
#'------------------------------------------------------------------------------
If(-Not(Test-Path -Path "$scriptPath\Logs")){
   Try{
      New-Item -type Directory -Path "$scriptPath\Logs" -ErrorAction Stop | Out-Null
      Write-Log -Info -Message "Created Directory ""$scriptPath\Logs"""
   }Catch{
      Write-Warning -Message $("Failed Creating Directory ""$scriptPath\Logs"". Error " + $_.Exception.Message)
      Exit -1
   }
}
#'------------------------------------------------------------------------------
#'Enumerate the Cached Credentials for the destination cluster.
#'------------------------------------------------------------------------------
Try{
   $Credentials = (Get-NcCredential -Controller $DestinationCluster -ErrorAction Stop).Credential
   Write-Log -Info -Message "Enumerated Cached Credentials for destination cluster ""$DestinationCluster"""
}Catch{
   Write-Log -Error -Message "Failed Enumerating Cached Credentials for destination cluster ""$DestinationCluster"""
}
If($Null -eq $Credentials){
   Write-Log -Error -Message "The credentials for destination cluster ""$DestinationCluster"" were null. Exiting"
   Exit -1
}
#'------------------------------------------------------------------------------
#'Connect to the destination cluster.
#'------------------------------------------------------------------------------
Try{
   Connect-NcController -Name $DestinationCluster -Credential $Credentials -ErrorAction Stop | Out-Null
   Write-Log -Info -Message "Connect to cluster ""$DestinationCluster"""
}Catch{
   Write-Log -Error -Message "Failed connecting to cluster ""$DestinationCluster"""
   Exit -1
}
#'------------------------------------------------------------------------------
#'Check the snapmirror status on the destination cluster.
#'------------------------------------------------------------------------------
[String]$command = "Get-NcSnapmirror -DestinationLocation ""$DestinationVserver`:"" -VserverContext $DestinationVserver -ErrorAction Stop"
Try{
   $result = Invoke-Expression -Command $command -ErrorAction Stop
   Write-Log -Info -Message "Executed Command`: $command"
}Catch{
   Write-Log -Error -Message "Failed Executing Command`: $command"
   Exit -1
}
If($Null -eq $result){
   Write-Log -Error -Message "The SnapMirror relationship for vserver ""$DestinationVserver"" does not exist on cluster ""$DestinationCluster"""
   Exit -1
}
#'------------------------------------------------------------------------------
#'Ensure the snapmirror status is broken-off and idle before attempting a resync.
#'------------------------------------------------------------------------------
If($result.Status -eq "idle" -And $result.MirrorState -eq "broken-off"){
   [Bool]$resync = $True
}Else{
   [Bool]$resync = $False
}
Write-Log -Info -Message $("The vserver ""$DestinationVserver"" is in a """ + $result.status + """ status and """ + $result.MirrorState + """ state")
#'------------------------------------------------------------------------------
#'Set the command to resync the snapmirror relationship.
#'------------------------------------------------------------------------------
[String]$SourceVserver = $result.SourceVserver
[String]$command       =  "Invoke-NcSnapmirrorResync -Destination ""$DestinationVserver`:"" -Source ""$SourceVserver`:"" "
If($MaxTransferRate){
   [String]$command += "-MaxTransferRate $MaxTransferRate "
}
If($SourceSnapshot){
   [String]$command += "-SourceSnapshot $SourceSnapshot "
}
If($Preserve){
   [String]$command += "-Preserve "
}
If($QuickResync){
   [String]$command += "-QuickResync "
}
If($IsAutoExpandEnabled){
   [String]$command += "-IsAutoExpandEnabled `$`$IsAutoExpandEnabled "
}
[String]$command += "-ErrorAction Stop"
#'------------------------------------------------------------------------------
#'Resync the SnapMirror relationship.
#'------------------------------------------------------------------------------
If($resync){
   Try{
      Invoke-Expression -Command $command -ErrorAction Stop | Out-Null
      Write-Log -Info -Message "Executed Command`: $command"
      Write-Log -Info -Message "Resynced SnapMirror relationship. Source vserver ""$SourceVserver"". Destination vserver ""$DestinationVserver"" on cluster ""$DestinationCluster"""
   }Catch{
      Write-Log -Error -Message "Failed Executing Command`: $command"
      Exit -1
   }
   #'---------------------------------------------------------------------------
   #'Wait for the snapmirror status to reach the desired state.
   #'---------------------------------------------------------------------------
   $result = Wait-SnapMirrorResync -SourceVserver $SourceVserver -DestinationCluster $DestinationCluster -DestinationVserver $DestinationVserver -SnapMirrorStatus $SnapMirrorStatus -SnapMirrorState $SnapMirrorState -TimeOut $TimeOut -WaitInterval $WaitInterval
   If($result){
      Write-Log -Info -Message "The destination vserver ""$DestinationVserver"" reached an ""$SnapMirrorStatus"" status and a ""$SnapMirrorState"" state within the timeout of ""$TimeOut"" seconds"
   }Else{
      Write-Log -Error -Message "The destination vserver ""$DestinationVserver"" failed to reach an ""$SnapMirrorStatus"" status and a ""$SnapMirrorState"" state within the timeout of ""$TimeOut"" seconds"
   }
}Else{
   Write-Log -Info -Message "The destination vserver ""$DestinationVserver"" is not in a broken-off state and idle status"
}
#'------------------------------------------------------------------------------

Hope that's a useful example

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

View solution in original post

11 REPLIES 11

mbeattie
5,247 Views

Hey Chuck

 

Are you able to share the code you are using? Which version of ONTAP are you using? I can test it in a lab and see if there's an issue I can pass onto the devs and look at a workaround.

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Chuckme
5,225 Views

Hi Matt. Thank you so much for the response.

 

We are currently using PowerShell Toolkit version 4.1.0.0 and are attempting to upgrade to version 9.14.1.2401 (I know, a big step). In a Powershell script in which we use the Invoke-NcSnapMirrorResync command, we use the $Snapmirror.MirrorState and $Snapmirror.RelationshipStatus to detect the completion of the tansfer. The following shows the result of the values of these parameters from a Get-NcSnapmirror command in our Toolkit version 4.1.0.0 and 9.14.1.2401 instances for the same Snapmirror relationship. These values were taken when the Relationship was in Idle status. During a resync, the status remais as 'Snapmirrored' causing our script not to recognize the completion of the transfer.


PowerShell Toolkit, ModuleVersion = '4.1.0.0'

PS C:\Windows\system32> $Snapmirror.MirrorState
snapmirrored

PS C:\Windows\system32> $Snapmirror.RelationshipStatus
idle

PowerShell Toolkit, ModuleVersion = '9.14.1.2401'

PS C:\Windows\system32> $Snapmirror.MirrorState
snapmirrored

PS C:\Windows\system32> $Snapmirror.RelationshipStatus
snapmirrored (should be idle)

I also think the $Snapmirror.RelationshipProgress is not being written, but I have not looked into that in detail.


The Resync scrpt. SVM is the name of the SVM and the SVMLIF is the IP of the SVM management LIF. The Jobname is not relevant for this instance.
The credentials are defined on the servers on which this script is executed.

New-Variable Jobname -scope script -value $args[0]
New-Variable Datetime -scope script -value $args[1]
New-Variable SVM -scope script -value $args[2]
New-Variable SVMLIF -scope script -value $args[3]
New-Variable Volume -scope script -value $args[4]
New-Variable Delay -scope script -value 60
New-Variable StateTest -scope script -value "snapmirrored"
New-Variable TotalTrans -scope script
New-Variable StatusTest -scope script -value "idle"
New-Variable Destination -scope script -value ${SVM}`:$Volume
New-Variable outline -scope script

Function DisplayError
{
Write-Host "`nError: $Error"
Exit(1)
}

Function Connect2Controller
{
Connect-NcController $SVMLIF -Credential (Get-NcCredential $SVMLIF -SystemScope $false).Credential
If ($Error -ne $Null)
{
DisplayError
}
}

Function ResyncMirror
{
Invoke-NcSnapmirrorResync -DestinationVserver $SVM `
-DestinationVolume $Volume `
-Confirm:$False
If ($Error -ne $Null)
{
DisplayError
}
}

Function CheckStatus
{
$outline = "Time Destination State Status KB Xfer"
Out-File -filePath $outfile -Append -inputObject $outline
Write-Host $outline
$outline = "------------------------------------------------------------------------------------"
Out-File -filePath $outfile -Append -inputObject $outline
Write-Host $outline

Do

{

$Snapmirror = Get-NcSnapmirror -Destination ($SVM + ":" + $Volume)

$State = $Snapmirror.MirrorState
$Status = $Snapmirror.RelationshipStatus
$Progress = $Snapmirror.RelationshipProgress
$Time = Get-Date -UFormat %H:%M:%S

$outline = $ExecutionContext.InvokeCommand.ExpandString(($Time).PadRight($Time.Length + (11-$Time.Length))) + `
$ExecutionContext.InvokeCommand.ExpandString(($Destination).PadRight($Destination.Length + (35-$Destination.Length))) + `
$ExecutionContext.InvokeCommand.ExpandString(($State).PadRight($State.Length + (16-$State.Length))) + `
$ExecutionContext.InvokeCommand.ExpandString(($Status).PadRight($Status.Length + (15-$Status.Length))) + `
$ExecutionContext.InvokeCommand.ExpandString($Progress)

Out-File -filePath $outfile -Append -inputObject $outline
Write-Host $outline

If ($State -ne $StateTest -or $Status -ne $StatusTest)
{
Start-Sleep $Delay
}
}
Until ($State -eq $StateTest -and $Status -eq $StatusTest)
Return $Snapmirror.TotalTransferBytes
}

Connect2Controller
ResyncMirror
$TotalTrans = CheckStatus

$outline = "Resync of volume " + $Volume + " was successful, $TotalTrans KB transferred."
Out-File -filePath $outfile -Append -inputObject $outline
Write-Host $outline

Exit(0)

/Chuck

mbeattie
5,028 Views

Hi Chuck,

 

Here's an example of SnapMirror Resync for SVM-DR. Would be easy enough to add in the parameters you need if you want to resync individual volumes. It connects to the destination cluster, checks that the snapmirror relationship is broken-off, invokes a snapmirror resync and calls a function to check the snapmirror status in a loop until completed or a timeout value is exceeded. Usage example:

 

PS E:\Scripts\PowerShell\Projects\SnapMirrorResync> .\SnapMirrorResync.ps1 -DestinationCluster cluster2.testlab.local -DestinationVserver vserver3_dr -WaitInterval 3 -TimeOut 300
[2024-02-27 16:03:43.543],[INFO],Enumerated Cached Credentials for destination cluster "cluster2.testlab.local"
[2024-02-27 16:03:43.856],[INFO],Connect to cluster "cluster2.testlab.local"
[2024-02-27 16:03:43.934],[INFO],Executed Command: Get-NcSnapmirror -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:43.949],[INFO],The vserver "vserver3_dr" is in a "idle" status and "broken-off" state
[2024-02-27 16:03:44.168],[INFO],Executed Command: Invoke-NcSnapmirrorResync -Destination "vserver3_dr:" -Source "vserver3:" -ErrorAction Stop
[2024-02-27 16:03:44.184],[INFO],Resynced SnapMirror relationship. Source vserver "vserver3". Destination vserver "vserver3_dr" on cluster "cluster2.testlab.local"
[2024-02-27 16:03:44.231],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:44.246],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:47.293],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:47.308],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:50.370],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:50.386],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:53.429],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:53.460],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:56.485],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:56.501],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:03:59.553],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:03:59.569],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:02.618],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:02.634],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:05.681],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:05.697],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:08.733],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:08.764],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:11.818],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:11.834],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:14.924],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:14.940],[INFO],The destination vserver "vserver3_dr:" is in a "transferring" and "broken-off" snapmirror state
[2024-02-27 16:04:17.990],[INFO],Executed Command: Get-NcSnapmirror -SourceLocation "vserver3:" -DestinationLocation "vserver3_dr:" -VserverContext vserver3_dr -ErrorAction Stop
[2024-02-27 16:04:18.006],[INFO],The destination vserver "vserver3_dr:" is in a "idle" and "snapmirrored" snapmirror state
[2024-02-27 16:04:18.021],[INFO],The destination vserver "vserver3_dr:" reached an "idle" status and "snapmirrored" state within the timeout of "300" seconds
[2024-02-27 16:04:18.021],[INFO],Waited a total of "36" seconds for the destination vserver "vserver3_dr:" to reach an "idle" status and "snapmirrored" state
[2024-02-27 16:04:18.037],[INFO],The destination vserver "vserver3_dr" reached an "idle" status and a "snapmirrored" state within the timeout of "300" seconds

Note: This assumes you have cached credentials using the "Add-NcCredential" Cmdlet.

 

Here is the source code, you could do this in a lot less lines of code but I've included logging and error checking...

 

Source Code:

 

Param(
   [Parameter(Mandatory=$True, HelpMessage="The destination cluster name or IP Address")]
   [String]$DestinationCluster,
   [Parameter(Mandatory=$True, HelpMessage="The destination Vserver name")]
   [String]$DestinationVserver,
   [Parameter(Mandatory=$False, HelpMessage="The desired snapmirror status")]
   [ValidateSet("idle")]
   [String]$SnapMirrorStatus="idle",
   [Parameter(Mandatory=$False, HelpMessage="The desired snapmirror state")]
   [ValidateSet("snapmirrored")]
   [String]$SnapMirrorState="snapmirrored",
   [Parameter(Mandatory=$False, HelpMessage="The Snapshot copy on the source to use as the basis for the update")]
   [String]$SourceSnapshot,
   [Parameter(Mandatory=$False, HelpMessage="Specifies the upper bound, in bytes per second, at which data is transferred between clusters. The default is unlimited (0) which permits the SnapMirror relationship to fully utilize the available network bandwidth")]
   [Int64]$MaxTransferRate,
   [Parameter(Mandatory=$False, HelpMessage="By default all snapshots on the destination that are newer than the latest common snapshot will be deleted. If specified, newer snapshots are retained")]
   [Bool]$Preserve,
   [Parameter(Mandatory=$False, HelpMessage="If specified, the resync time is reduced because the resync does not incur storage efficiency overhead before the transfer of new data. Specifying this parameter is recommended if the source of the resync does not have volume efficiency enabled or if reducing resync time is more important than preserving all possible storage efficiency. When this parameter is specified, resync does not preserve the storage efficiency of the new data with existing data over the wire and on the destination. This parameter is not supported for data protection and load-sharing relationships")]
   [Bool]$QuickResync,
   [Parameter(Mandatory=$False, HelpMessage="If specified, newer snapshots are retained")]
   [Bool]$IsAutoExpandEnabled,
   [Parameter(Mandatory=$True, HelpMessage="The total Number of seconds to wait")]
   [ValidateRange(1,86400)]
   [Long]$TimeOut,
   [Parameter(Mandatory=$True, HelpMessage="The number of seconds to wait in between checks")]
   [ValidateRange(1,600)]
   [Long]$WaitInterval
)
#'------------------------------------------------------------------------------
Function Get-IsoDateTime{
   Return (Get-IsoDate) + " " + (Get-IsoTime)
}#'End Function Get-IsoDateTime.
#'------------------------------------------------------------------------------
Function Get-IsoDate{
   Return Get-Date -uformat "%Y-%m-%d"
}#'End Function Get-IsoDate.
#'------------------------------------------------------------------------------
Function Get-IsoTime{
   #Return Get-Date -uformat "%H:%M:%S"
   Return Get-Date -Format HH:mm:ss.fff
}#'End Function Get-IsoTime.
#'------------------------------------------------------------------------------
Function Write-Log{
   Param(
      [Switch]$Info,
      [Switch]$Error,
      [Switch]$Debug,
      [Switch]$Warning,
      [String]$Message
   )
   #'---------------------------------------------------------------------------
   #'Set the default log type if not provided.
   #'---------------------------------------------------------------------------
   If((-Not($Info)) -And (-Not($Debug)) -And (-Not($Warning)) -And (-Not($Error))){
      [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[INFO`]," + $Message)
   }
   #'---------------------------------------------------------------------------
   #'Add an entry to the log file and disply the output. Format: [Date],[TYPE],MESSAGE
   #'---------------------------------------------------------------------------
   [String]$lineNumber = $MyInvocation.ScriptLineNumber
   Try{
      If($Error){
         If([String]::IsNullOrEmpty($_.Exception.Message)){
            [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[ERROR`],`[LINE $lineNumber`]," + $Message)
         }Else{
            [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[ERROR`],`[LINE $lineNumber`]," + $Message + ". Error " + $_.Exception.Message)
         }
      }ElseIf($Info){
         [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[INFO`]," + $Message)
      }ElseIf($Debug){
         [String]$line = $("`[" + $(Get-IsoDateTime) + "`],`[DEBUG`],`[LINE $lineNumber`]," + $Message)
      }ElseIf($Warning){
         [String]$line = $("`[" + (Get-IsoDateTime) + "`],`[WARNING`],`[LINE $lineNumber`]," + $Message)
      }
      #'-----------------------------------------------------------------------
      #'Display the console output.
      #'-----------------------------------------------------------------------
      If($Error){
         If(-Not([String]::IsNullOrEmpty($_.Exception.Message))){
            Write-Host $($line + ". Error " + $_.Exception.Message) -Foregroundcolor Red
         }Else{
            Write-Host $line -Foregroundcolor Red
         }
      }ElseIf($Warning){
         Write-Host $line -Foregroundcolor Yellow
      }ElseIf($Debug){
         Write-Host $line -Foregroundcolor Magenta
      }Else{
         Write-Host $line -Foregroundcolor White
      }
      Add-Content -Path "$scriptLogPath.log" -Value $line -ErrorAction Stop
      If($Error){
         Add-Content -Path "$scriptLogPath.err" -Value $line -ErrorAction Stop
      }
   }Catch{
      Write-Warning "Could not write entry to output log file ""$scriptLogPath.log"". Log Entry ""$Message"""
   }
}#'End Function Write-Log.
#'------------------------------------------------------------------------------
Function Wait-SnapMirrorResync{
   Param(
      [Parameter(Mandatory=$False, HelpMessage="The source cluster name or IP Address")]
      [String]$SourceCluster,
      [Parameter(Mandatory=$True, HelpMessage="The source vserver")]
      [String]$SourceVserver,
      [Parameter(Mandatory=$True, HelpMessage="The destination cluster name or IP Address")]
      [String]$DestinationCluster,
      [Parameter(Mandatory=$True, HelpMessage="The destination vserver")]
      [String]$DestinationVserver,
      [Parameter(Mandatory=$True, HelpMessage="The desired snapmirror status")]
      [String]$SnapMirrorStatus,
      [Parameter(Mandatory=$True, HelpMessage="The desired snapmirror state")]
      [String]$SnapMirrorState,
      [Parameter(Mandatory=$True, HelpMessage="The total Number of seconds to wait")]
      [Long]$TimeOut,
      [Parameter(Mandatory=$True, HelpMessage="The number of seconds to wait in between checks")]
      [Long]$WaitInterval
   )
   #'---------------------------------------------------------------------------
   #'Wait for the SnapMirror operation to complete or until the timeout is exceeded.
   #'---------------------------------------------------------------------------
   [Long]$waited           = 0
   [Long]$timeWaited       = $waited
   [Bool]$completionStatus = $False
   Do{
      [Long]$timeWaited += [Long]($waited + $waitInterval)
      [String]$command = "Get-NcSnapmirror -SourceLocation ""$SourceVserver`:"" -DestinationLocation ""$DestinationVserver`:"" -VserverContext $DestinationVserver -ErrorAction Stop"
      #'------------------------------------------------------------------------
      #'Invoke the command to check the snapmirror status for the destination path.
      #'------------------------------------------------------------------------
      Try{
         $result = Invoke-Expression -Command $command -ErrorAction Stop
         Write-Log -Info -Message "Executed Command`: $command"
      }Catch{
         Write-Log -Error -Message "Failed executing command`: $command"
         Break;
      }
      #'------------------------------------------------------------------------
      #'Check the snapmirror status for the destination path.
      #'------------------------------------------------------------------------
      Write-Log -Info -Message $("The destination vserver ""$DestinationVserver`:"" is in a """ + $result.Status + """ and """ + $result.MirrorState + """ snapmirror state")
      If(($result.Status -eq $SnapMirrorStatus -And $result.MirrorState -eq $SnapMirrorState) -And ($timeWaited -le $timeOut) -And $timeOut -gt 0){
         Break;
      }
      Start-Sleep -Seconds $waitInterval
   }Until(($result.Status -eq $SnapMirrorStatus -And $result.MirrorState -eq $SnapMirrorState) -Or (($timeWaited -ge $timeOut) -And $timeOut -gt 0))
   #'---------------------------------------------------------------------------
   #'Display the destination snapmirror state and set the completion status.
   #'---------------------------------------------------------------------------
   If(($result.Status -eq $SnapMirrorStatus -And $result.MirrorState -eq $SnapMirrorState) -And ($timeWaited -lt $timeOut)){
      [Bool]$completionStatus = $True
      Write-Log -Info -Message "The destination vserver ""$DestinationVserver`:"" reached an ""$SnapMirrorStatus"" status and ""$SnapMirrorState"" state within the timeout of ""$timeOut"" seconds"
      Write-Log -Info -Message "Waited a total of ""$timeWaited"" seconds for the destination vserver ""$DestinationVserver`:"" to reach an ""$SnapMirrorStatus"" status and ""$SnapMirrorState"" state"
   }
   #'---------------------------------------------------------------------------
   #'Raise an error if the timeout is exceeded.
   #'---------------------------------------------------------------------------
   If($timeWaited -ge $timeOut -And $timeOut -gt 0){
      Write-Log -Error -Message "The destination vserver ""$DestinationVserver`:"" did not reach an ""$SnapMirrorStatus"" status and ""$SnapMirrorState"" state within the timeout of ""$timeOut"" seconds"
   }
   Return $completionStatus;
}#End Function
#'------------------------------------------------------------------------------
#'Initialization Section. Define Global Variables.
#'------------------------------------------------------------------------------
[String]$scriptPath     = Split-Path($MyInvocation.MyCommand.Path)
[String]$scriptSpec     = $MyInvocation.MyCommand.Definition
[String]$scriptBaseName = (Get-Item $scriptSpec).BaseName
[String]$scriptName     = (Get-Item $scriptSpec).Name
[String]$scriptLogPath  = $("$scriptPath\Logs\" + (Get-IsoDate))
#'------------------------------------------------------------------------------
#'Enumerate the Cached Credentials for the destination cluster.
#'------------------------------------------------------------------------------
If(-Not(Test-Path -Path "$scriptPath\Logs")){
   Try{
      New-Item -type Directory -Path "$scriptPath\Logs" -ErrorAction Stop | Out-Null
      Write-Log -Info -Message "Created Directory ""$scriptPath\Logs"""
   }Catch{
      Write-Warning -Message $("Failed Creating Directory ""$scriptPath\Logs"". Error " + $_.Exception.Message)
      Exit -1
   }
}
#'------------------------------------------------------------------------------
#'Enumerate the Cached Credentials for the destination cluster.
#'------------------------------------------------------------------------------
Try{
   $Credentials = (Get-NcCredential -Controller $DestinationCluster -ErrorAction Stop).Credential
   Write-Log -Info -Message "Enumerated Cached Credentials for destination cluster ""$DestinationCluster"""
}Catch{
   Write-Log -Error -Message "Failed Enumerating Cached Credentials for destination cluster ""$DestinationCluster"""
}
If($Null -eq $Credentials){
   Write-Log -Error -Message "The credentials for destination cluster ""$DestinationCluster"" were null. Exiting"
   Exit -1
}
#'------------------------------------------------------------------------------
#'Connect to the destination cluster.
#'------------------------------------------------------------------------------
Try{
   Connect-NcController -Name $DestinationCluster -Credential $Credentials -ErrorAction Stop | Out-Null
   Write-Log -Info -Message "Connect to cluster ""$DestinationCluster"""
}Catch{
   Write-Log -Error -Message "Failed connecting to cluster ""$DestinationCluster"""
   Exit -1
}
#'------------------------------------------------------------------------------
#'Check the snapmirror status on the destination cluster.
#'------------------------------------------------------------------------------
[String]$command = "Get-NcSnapmirror -DestinationLocation ""$DestinationVserver`:"" -VserverContext $DestinationVserver -ErrorAction Stop"
Try{
   $result = Invoke-Expression -Command $command -ErrorAction Stop
   Write-Log -Info -Message "Executed Command`: $command"
}Catch{
   Write-Log -Error -Message "Failed Executing Command`: $command"
   Exit -1
}
If($Null -eq $result){
   Write-Log -Error -Message "The SnapMirror relationship for vserver ""$DestinationVserver"" does not exist on cluster ""$DestinationCluster"""
   Exit -1
}
#'------------------------------------------------------------------------------
#'Ensure the snapmirror status is broken-off and idle before attempting a resync.
#'------------------------------------------------------------------------------
If($result.Status -eq "idle" -And $result.MirrorState -eq "broken-off"){
   [Bool]$resync = $True
}Else{
   [Bool]$resync = $False
}
Write-Log -Info -Message $("The vserver ""$DestinationVserver"" is in a """ + $result.status + """ status and """ + $result.MirrorState + """ state")
#'------------------------------------------------------------------------------
#'Set the command to resync the snapmirror relationship.
#'------------------------------------------------------------------------------
[String]$SourceVserver = $result.SourceVserver
[String]$command       =  "Invoke-NcSnapmirrorResync -Destination ""$DestinationVserver`:"" -Source ""$SourceVserver`:"" "
If($MaxTransferRate){
   [String]$command += "-MaxTransferRate $MaxTransferRate "
}
If($SourceSnapshot){
   [String]$command += "-SourceSnapshot $SourceSnapshot "
}
If($Preserve){
   [String]$command += "-Preserve "
}
If($QuickResync){
   [String]$command += "-QuickResync "
}
If($IsAutoExpandEnabled){
   [String]$command += "-IsAutoExpandEnabled `$`$IsAutoExpandEnabled "
}
[String]$command += "-ErrorAction Stop"
#'------------------------------------------------------------------------------
#'Resync the SnapMirror relationship.
#'------------------------------------------------------------------------------
If($resync){
   Try{
      Invoke-Expression -Command $command -ErrorAction Stop | Out-Null
      Write-Log -Info -Message "Executed Command`: $command"
      Write-Log -Info -Message "Resynced SnapMirror relationship. Source vserver ""$SourceVserver"". Destination vserver ""$DestinationVserver"" on cluster ""$DestinationCluster"""
   }Catch{
      Write-Log -Error -Message "Failed Executing Command`: $command"
      Exit -1
   }
   #'---------------------------------------------------------------------------
   #'Wait for the snapmirror status to reach the desired state.
   #'---------------------------------------------------------------------------
   $result = Wait-SnapMirrorResync -SourceVserver $SourceVserver -DestinationCluster $DestinationCluster -DestinationVserver $DestinationVserver -SnapMirrorStatus $SnapMirrorStatus -SnapMirrorState $SnapMirrorState -TimeOut $TimeOut -WaitInterval $WaitInterval
   If($result){
      Write-Log -Info -Message "The destination vserver ""$DestinationVserver"" reached an ""$SnapMirrorStatus"" status and a ""$SnapMirrorState"" state within the timeout of ""$TimeOut"" seconds"
   }Else{
      Write-Log -Error -Message "The destination vserver ""$DestinationVserver"" failed to reach an ""$SnapMirrorStatus"" status and a ""$SnapMirrorState"" state within the timeout of ""$TimeOut"" seconds"
   }
}Else{
   Write-Log -Info -Message "The destination vserver ""$DestinationVserver"" is not in a broken-off state and idle status"
}
#'------------------------------------------------------------------------------

Hope that's a useful example

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Chuckme
5,010 Views

Hi Matt,

Thanks for your response. The thourough error checking and documentation is super impressive.  I will certainly make use of it to improvee my scripts when I have the time.

However, the problem I have is that with the 9.1.4 version of the Toolkit that I have on my server, the mirrorstate and status have constant values of "snapmrrored" when queried from the script. They do not change during the resync process, hence my script does not detect the end of the transfer. The resync continues to run until the transfer completes, but script does not detect the completion.  This does not occur with the very old  4.1.0 version we are using on our production server.  If you are using version 9.1.4, then my problem is an environmental issue on our server.

Regares,

Chuck

mbeattie
4,952 Views

Hi Chuck,

 

I don't have an old version of the PSTK to test in on but it's possible the API's may have been updated. You need to check that the snapmirror status is "idle" and the snapmirror state is "snapmirrored" (Note these are the default input parameter values in the code I posted).

 

   [Parameter(Mandatory=$False, HelpMessage="The desired snapmirror status")]
   [ValidateSet("idle")]
   [String]$SnapMirrorStatus="idle",
   [Parameter(Mandatory=$False, HelpMessage="The desired snapmirror state")]
   [ValidateSet("snapmirrored")]

 

The issue in the latest PSTK version may be caused by differences between the REST API and ZAPI implementation. To test that try your script but add the "-ZapiCall" parameter to the "Connect-NcController" CmdLet. EG:

PS C:\Scripts\PowerShell\Projects\SnapMirrorResync> Connect-NcController -Name cluster2.testlab.local -Credential (Get-NcCredential -Controller cluster2.testlab.local).Credential -ZapiCall

Name                 Address           Vserver              Version
----                 -------           -------              -------
cluster2.testlab.... 192.168.100.3                          NetApp Release 9.13.1X37: Mon Jun 19 07:42:08 UTC 2023


PS C:\Scripts\PowerShell\Projects\SnapMirrorResync> Get-NcSnapMirror

SourceLocation                                DestinationLocation                           Status       MirrorState
--------------                                -------------------                           ------       -----------
vserver1:                                     vserver1_dr:                                  idle         snapmirrored
vserver2:                                     vserver2_dr:                                  idle         snapmirrored
vserver3:                                     vserver3_dr:                                  idle         broken-off


PS C:\Scripts\PowerShell\Projects\SnapMirrorResync> Get-NaToolkitVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
9      13     1      2306

 

IE in your code try explicitly connecting via ZAPI. The default is that the PSTK will do an ONTAP version check. If the ONTAP system version is 9.6 or greater the PSTK will default to use the REST API otherwise it will use ZAPI (unless explicitly used when you connect to the cluster. Try this:

 

Function Connect2Controller{
   Connect-NcController $SVMLIF -Credential (Get-NcCredential $SVMLIF -SystemScope $false).Credential -ZapiCall
   If($Error -ne $Null){
      DisplayError
   }
}

 

There are definately differences between the CmdLet outputs of REST and ZAPI however that's really due to the ONTAP implementation of REST API's (not the PSTK as it's simply leveraging the ONTAP API's)

 

Hope that helps

 

/Matt

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Chuckme
4,923 Views

Hi Matt,

Using the ZapiCall, my Snapmirror Resync completed successfully.

Another problem I was experiencing with a New-NcClone  failure was also resolved.

The following is the failure message from this failure: 

New-NcClone : [400]: Cannot set the svm context from HTTP header using: "X-Dot-SVM-Name" or "X-Dot-SVM-UUID" while in an existing svm context.
At line:3 char:5
+ New-NcClone -Volume $SV -SourcePath $SLP -DestinationPath $DLP
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [New-NcClone], ArgumentException
+ FullyQualifiedErrorId : [400]: Cannot set the svm context from HTTP header using: "X-Dot-SVM-Name" or "X-Dot-SVM
-UUID" while in an existing svm context.,DataONTAP.C.PowerShell.SDK.Cmdlets.Clone.NewNcClone

This seems to me to indicate that the HTTP protocol is not enabled on this server.

I have requested our server team to look into this.  I will let you know the response.

mbeattie
4,917 Views

Hi Chuck,

 

Hmmm sounds like a HTTP 400 error code (bad request). Advise you ensure you are connecting to the cluster using the -ZapiCall parameter on the Connect-NcController CmdLet. There's definitely issues with some of the CmdLet's and REST API implementation. It would be safest to use the -ZapiCall on the connection unless you've thoroughly tested your code in your production environment.

 

/Matt 

If this post resolved your issue, help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Chuckme
4,670 Views

Thanks again Matt.

Yes, everything seems to work normally with the -ZapiCall and we receive failures otherwise. As I mentioned, we have an error indicating HTTP call failures and I am exploring that with our server team.

 

Thanks again!!

Uschi
4,465 Views

Is there any other solution to avoid the HTTP 400 error? Zapi is deprecated, isnt it?

Uschi
4,448 Views

Found it:

Get-NcVol -ONTAPI

Chuckme
4,219 Views

Everything works for me on version 9.14 with -ONTAPAPI. It seems we need to look at the REST API implementation.  

Public