common_utils.ps1
$ZVM_VM_NAME = "ZVML" function Start-ZVM { try { Write-Host "Starting $($MyInvocation.MyCommand)..." $ZVM = Get-VM -Name $ZVM_VM_NAME if ($null -eq $ZVM) { throw "$ZVM_VM_NAME VM does not exist" } else { if ($ZVM.PowerState -eq 'PoweredOff') { Write-Host "$ZVM_VM_NAME is powered off, going to power it on" Start-VM $ZVM -ErrorAction Stop | Out-Null } else { Write-Host "$ZVM_VM_NAME is up and running" } } } catch { throw "Failed to start $ZVM_VM_NAME. Problem: $_" } } function Stop-ZVM { try { Write-Host "Starting $($MyInvocation.MyCommand)..." $ZVM = Get-VM -Name $ZVM_VM_NAME if ($null -eq $ZVM) { Write-Error "$ZVM_VM_NAME does not exist" -ErrorAction Stop } else { if ($ZVM.PowerState -eq 'PoweredOn') { Write-Host "$ZVM_VM_NAME is powered on, going to power it off" Stop-VM -VM $ZVM -Confirm:$False -ErrorAction Stop | Out-Null } else { Write-Host "$ZVM_VM_NAME is off" } } } catch { Write-Error "Failed to stop $ZVM_VM_NAME. Problem: $_" -ErrorAction Stop #TODO:GK Remove -ErrorAction and review usages } } function New-RandomPassword { # Generate a password with at least 4 uppercase, 4 lowercase, 2 digits and 2 special characters from !@#%^*() # The first character must be a letter # The password length will vary between 12 and 14 symbols Write-Host "Starting $($MyInvocation.MyCommand)..." $extlen = { Get-SecureRandom(0, 1) } $firstRand = 'a'..'z' | Get-SecureRandom $lowerRand = 'a'..'z' | Get-SecureRandom -Count (3 + (& $extlen)) $upperRand = 'A'..'Z' | Get-SecureRandom -Count (4 + (& $extlen)) $numericRand = '0'..'9' | Get-SecureRandom -Count (2 + (& $extlen)) $specialRand = [char[]]'!@#%^*()' | Get-SecureRandom -Count (2 + (& $extlen)) $allRand = $upperRand + $lowerRand + $numericRand + $specialRand $shuffledRand = $allRand | Get-SecureRandom -Count $allRand.Length $password = $firstRand + ($shuffledRand -join '') return $password } function New-ZertoFolderOnHost { param( [Parameter(Mandatory = $true, HelpMessage = "Host Name to connect with SSH")] [string]$HostName ) process { Write-Host "Starting $($MyInvocation.MyCommand)..." $Command = "mkdir -p $ZERTO_FOLDER_ON_HOST" $Res = Invoke-SSHCommands -HostName $HostName -Commands $Command $ExitStatus = $Res["0_exitStatus"]; if ( $ExitStatus -ne '0' ) { throw "failed to create $ZERTO_FOLDER_ON_HOST on host $HostName. Exit status for ""$Command"" is $ExitStatus" } else { Write-Host "Zerto folder ($ZERTO_FOLDER_ON_HOST) was created on $HostName." } } } function Invoke-Retry { param ( [Parameter(Mandatory = $true)] [ScriptBlock]$Action, [Parameter(Mandatory = $true)] [string]$ActionName, [Parameter(Mandatory = $true)] [int]$RetryCount, [Parameter(Mandatory = $true)] [int]$RetryIntervalSeconds ) for ($i = 1; $i -le $RetryCount; $i++) { try { Write-Output "Attempt $i of $RetryCount executing $ActionName." & $Action Write-Output "$ActionName succeeded." return } catch { Write-Output "Attempt $i of $RetryCount on $ActionName wasn't successful." if ($i -ne $RetryCount) { Write-Output "Waiting for $RetryIntervalSeconds seconds before retrying $ActionName..." Start-Sleep -Seconds $RetryIntervalSeconds } else { Write-Output "Error: All attempts to execute $ActionName failed. Exiting." throw } } } } function Invoke-ZVMScriptWithTimeout { param ( [Parameter(Mandatory = $true)] [string]$ScriptText, [Parameter(Mandatory = $true)] [string]$ActionName, [int]$TimeoutMinutes = 30 ) $ZVM = Get-VM -Name $ZVM_VM_NAME Write-Output "Starting $ActionName execution." # Start the script asynchronously $task = Invoke-VMScript -VM $ZVM -ScriptText $ScriptText -GuestUser $ZAPPLIANCE_USER -GuestPassword $PersistentSecrets.ZappliancePassword -RunAsync # Calculate the timeout time $timeoutTime = (Get-Date).AddMinutes($TimeoutMinutes) while ((Get-Date) -lt $timeoutTime) { # Check the task status if ($task.State -eq 'Success') { # The 'Success' state indicates that the remote script was executed, but does not reflect the script's success or failure. Write-Output "$ActionName execution done." return $task.Result } elseif ($task.State -eq 'Error') { throw "$ActionName execution failed with error: $($task.ErrorMessage)" } # Wait for a short period before checking again Start-Sleep -Seconds 30 } # If the loop exits, it means the timeout was reached throw "$ActionName did not complete within the allotted time of $TimeoutMinutes minutes." } |