NetApp.CBS.AVS.psm1
using module Microsoft.AVS.Management <# Copyright 2021 Netapp, Inc. #> # # Script module for module 'NetApp.SC' # Set-StrictMode -Version Latest <# .SYNOPSIS This cmdlet installs the OVA package. The OVA package contains a virtual appliance. .DESCRIPTION This cmdlet installs the OVA package. The OVA package contains a virtual appliance. .PARAMETER ApplianceVirtualMachineName Specify the virtual machine name for the appliance. .PARAMETER EsxHost Specify the destination ESXi hostname for the virtual appliance. .PARAMETER VmDatastore Specify the datastore to be used for the virtual appliance. .PARAMETER NetworkMapping Specify the destination network for each source network .PARAMETER ApplianceNetworkName Specifies the appliance network name. .PARAMETER ApplianceIPAddress IPV4 address of the virtual appliances. .PARAMETER Netmask Specify the subnet to be used on the deployed network. .PARAMETER Gateway Gateway of the deployed network. .PARAMETER PrimaryDNS Primary DNS server IP address. .EXAMPLE Install-NetAppCBSAppliance -AcceptNetAppEulaAggrement $true -ApplianceVirtualMachineName "VM1" -EsxHost "10.212.11.119" -VmDatastore "datastore1" -NetworkMapping "VM Network" -ApplianceNetworkName "scvova" -ApplianceIPAddress "19.132.15.124" -Netmask "255.255.255.0" -Gateway "11.252.1.1" -PrimaryDNS "10.232.1.60" Description --------------------------------------- Installs the OVA file using static IP address. #> function Install-NetAppCBSAppliance { [AVSAttribute(45, UpdatesSDDC = $True)] [CmdletBinding()] param( [Parameter( Mandatory = $true, HelpMessage = "Do you accept <a href='https://www.netapp.com/pdf.html?item=/media/14114-enduserlicenseagreementworldwide.pdf'>End User License Aggrement</a> ?")] [ValidateNotNullOrEmpty()] [boolean] $AcceptNetAppEulaAggrement, [Parameter( Mandatory = $true, HelpMessage = 'Specify the virtual machine name for the appliance.')] [ValidateNotNullOrEmpty()] [string] $ApplianceVirtualMachineName, [Parameter( Mandatory = $true, HelpMessage = 'Specify the destination ESXi hostname for the virtual appliance.')] [ValidateNotNullOrEmpty()] [string] $EsxHost, [Parameter( Mandatory = $true, HelpMessage = 'Specify the datastore to be used for the appliance')] [ValidateNotNullOrEmpty()] [string] $VmDatastore, [Parameter( Mandatory = $true, HelpMessage = 'Specify the destination network for each source network')] [ValidateNotNullOrEmpty()] [string] $NetworkMapping, [Parameter( Mandatory = $true, HelpMessage = 'Specify the network name of the virtual appliance.')] [string] $ApplianceNetworkName, [Parameter( Mandatory = $true, HelpMessage = 'IPV4 address for the appliance')] [string] $ApplianceIPAddress, [Parameter( Mandatory = $true, HelpMessage = 'Subnet mask')] [string] $Netmask, [Parameter( Mandatory = $true, HelpMessage = 'Gateway on the deployed network')] [string] $Gateway, [Parameter( Mandatory = $true, HelpMessage = 'Primary DNS server IP address')] [string] $PrimaryDNS, [Parameter( Mandatory = $true, HelpMessage = 'Appliance user name.')] [ValidateNotNullOrEmpty()] [string] $ApplianceUser, [Parameter( Mandatory = $true, HelpMessage = 'Appliance password')] [ValidateNotNullOrEmpty()] [Security.SecureString] $AppliancePassword ) $ApplianceIPAddress = $ApplianceIPAddress.Trim() $Netmask = $Netmask.Trim() $Gateway = $Gateway.Trim() $PrimaryDNS = $PrimaryDNS.Trim() $ApplianceUser = $ApplianceUser.Trim() $scvcredential = New-Object System.Management.Automation.PSCredential ($ApplianceUser, $AppliancePassword) Install-Appliance -AcceptNetAppEulaAggrement $AcceptNetAppEulaAggrement -ApplianceVirtualMachine $ApplianceVirtualMachineName -EsxHost $EsxHost -VmDatastore $VmDatastore -NetworkMapping $NetworkMapping -ApplianceNetworkName $ApplianceNetworkName -ApplianceIPAddress $ApplianceIPAddress -Netmask $Netmask -Gateway $Gateway -PrimaryDNS $PrimaryDNS -scvcredential $scvcredential } <# .SYNOPSIS This cmdlet installs the OVA package. The OVA package contains a virtual appliance. .DESCRIPTION This cmdlet installs the OVA package. The OVA package contains a virtual appliance. .PARAMETER ApplianceVirtualMachineName Specify the virtual machine name for the appliance. .PARAMETER EsxHost Specify the destination ESXi hostname for the virtual appliance. .PARAMETER VmDatastore Specify the datastore to be used for the virtual appliance. .PARAMETER NetworkMapping Specify the destination network for each source network .PARAMETER ApplianceNetworkName Specifies the appliance network name. .EXAMPLE Install-NetAppCBSApplianceUsingDHCP -AcceptNetAppEulaAggrement $true -ApplianceVirtualMachineName "VM1" -EsxHost "10.212.11.119" -VmDatastore "datastore1" -NetworkMapping "VM Network" -ApplianceNetworkName "scvova" Description --------------------------------------- Installs the OVA file using dynamic IP address. #> function Install-NetAppCBSApplianceUsingDHCP { [AVSAttribute(45, UpdatesSDDC = $True)] [CmdletBinding()] param( [Parameter( Mandatory = $true, HelpMessage = "Do you accept <a href='https://www.netapp.com/pdf.html?item=/media/14114-enduserlicenseagreementworldwide.pdf'>End User License Aggrement</a> ? [y/n]")] [ValidateNotNullOrEmpty()] [boolean] $AcceptNetAppEulaAggrement, [Parameter( Mandatory = $true, HelpMessage = 'Specify the virtual machine name for the appliance.')] [ValidateNotNullOrEmpty()] [string] $ApplianceVirtualMachineName, [Parameter( Mandatory = $true, HelpMessage = 'Specify the destination ESXi hostname for the virtual appliance.')] [ValidateNotNullOrEmpty()] [string] $EsxHost, [Parameter( Mandatory = $true, HelpMessage = 'Specify the datastore to be used for the appliance')] [ValidateNotNullOrEmpty()] [string] $VmDatastore, [Parameter( Mandatory = $true, HelpMessage = 'Specify the destination network for each source network')] [ValidateNotNullOrEmpty()] [string] $NetworkMapping, [Parameter( Mandatory = $true, HelpMessage = 'Specify the network name of the virtual appliance.')] [string] $ApplianceNetworkName, [Parameter( Mandatory = $true, HelpMessage = 'Appliance user name.')] [ValidateNotNullOrEmpty()] [string] $ApplianceUser, [Parameter( Mandatory = $true, HelpMessage = 'Appliance password')] [ValidateNotNullOrEmpty()] [Security.SecureString] $AppliancePassword ) $scvcredential = New-Object System.Management.Automation.PSCredential ($ApplianceUser, $AppliancePassword) Install-Appliance -AcceptNetAppEulaAggrement $AcceptNetAppEulaAggrement -ApplianceVirtualMachine $ApplianceVirtualMachineName -EsxHost $EsxHost -VmDatastore $VmDatastore -NetworkMapping $NetworkMapping -ApplianceNetworkName $ApplianceNetworkName -Dhcp $true -scvcredential $scvcredential } <# .SYNOPSIS This cmdlet upgrades OVA package in the virtual appliance. .DESCRIPTION This cmdlet upgrades OVA package in the virtual appliance. .PARAMETER VmDatastore Specify the datastore for the virtual appliance .EXAMPLE Update-CBSAppliance -VmDatastore "ova_ds" Description --------------------------------------- Upgrades the virtual appliance #> function Update-NetAppCBSAppliance { [CmdletBinding()] param( [Parameter( Mandatory = $true, HelpMessage = 'Storage for the configuration and disk files')] [string] $VmDatastore, [Parameter( Mandatory = $true, HelpMessage = 'Appliance user name.')] [ValidateNotNullOrEmpty()] [string] $ApplianceUser, [Parameter( Mandatory = $true, HelpMessage = 'Appliance password')] [ValidateNotNullOrEmpty()] [Security.SecureString] $AppliancePassword ) $scvcredential = New-Object System.Management.Automation.PSCredential ($ApplianceUser, $AppliancePassword) update-netapp-cbs-appliance -VmDatastore "ova_ds" -scvcredential $scvcredential } <# .SYNOPSIS This cmdlet modifies the password of the virtual appliance. .DESCRIPTION This cmdlet modifies the password of the virtual appliance. .EXAMPLE Set-NetAppCBSAppliancePassword Description --------------------------------------- Modify the password of the virtual appliance. #> function Set-NetAppCBSAppliancePassword { <# High level task of this cmdlets 1. Check if tag AVS_ANF_CLOUD_ADMIN_VM_TAG exists. 2. If the tag does not exist, throw error. 3. If tag exist, get teh VM detail. 4. Check if VM assosicated with Tag present. 5. If VM not present, throw eror 6. IF VM present A. Change password for teh user 'NetAppSCDPAdmin' B. Update vApp options for the users new password. #> set-netapp-cbs-appliance-password } <# .SYNOPSIS This cmdlet uninstalls the virtual appliance. .DESCRIPTION This cmdlet uninstalls the virtual appliance. .EXAMPLE UnInstall-NetAppCBSAppliance Description --------------------------------------- Uninstalls the virtual appliance #> function UnInstall-NetAppCBSAppliance { [CmdletBinding()] param( [Parameter( Mandatory = $true, HelpMessage = 'Specify $True to UnInstall NetApp CBS Appliance. In interactive mode enter any value to uninstall and leave it blank to cancel the operation.')] [bool] $AreYouSureToDelete ) if ($AreYouSureToDelete -eq $True) { uninstall-netapp-cbs-appliance } } # Internal helper functions function Show-Progress { param( [Parameter(Mandatory)] [int] $TotalNoOfTimes, [Parameter(Mandatory)] [int] $SleepTime, [Parameter(Mandatory)] [string] $ActivityText, [Parameter(Mandatory)] [string] $ProgressText, [Parameter()] [boolean] $HidePercentageComplete ) $TotalNoOfTimes = $TotalNoOfTimes + 1 $i = 0 for ($i = 0; $i -lt $TotalNoOfTimes; $i++) { $percentComplete = ($i / $TotalNoOfTimes) * 100 if ($HidePercentageComplete -eq $true) { Write-DebugLog -Message "-Activity $ActivityText -Status $ProgressText" } else { Write-DebugLog -Message "-Activity $ActivityText -Status $ProgressText : $percentComplete" } Start-Sleep $SleepTime } Write-DebugLog -Message "-Activity $ActivityText -Status $ProgressText : $percentComplete" } function Restart-VMwareVM { <# .DESCRIPTION This fucntion restarts the virtual machine. .PARAMETER ApplianceVirtualMachine Specify the virtual machine for the virtual appliance. .EXAMPLE Restart-VMwareVM Description --------------------------------------- Restart virtual machine #> param( [Parameter(Mandatory)] [string] $ApplianceVirtualMachine ) $VMGuestObject = Get-VMGuest -VM $ApplianceVirtualMachine -ErrorAction SilentlyContinue -ErrorVariable GetVMError if ($GetVMError) { Write-DebugLog $GetVMError | Out-String } if ($VMGuestObject) { if ($VMGuestObject.State -eq "Running") { try { Shutdown-VMGuest -VM $ApplianceVirtualMachine -Confirm:$false -ErrorAction Stop | Out-Null Start-Sleep 5 $Count = 10 For ($i = 0; $i -le $Count; $i++) { $VMGuestObject = Get-VMGuest -VM $ApplianceVirtualMachine if ($VMGuestObject.State -eq "NotRunning") { break } else { Start-Sleep 10 } $PercentComplete = ($i / $Count) * 100 Write-DebugLog -Message "-Activity Shutdown-VMGuest -Status $i/$count : $PercentComplete % " } Write-DebugLog -Message "-Activity Shutdown-VMGuest -Status Done -complete" Start-VM -VM $ApplianceVirtualMachine | Out-Null $Count = 10 For ($i = 0; $i -le $Count; $i++) { $VMGuestObject = Get-VMGuest -VM $ApplianceVirtualMachine if ($VMGuestObject.State -eq "Running") { break } else { Start-Sleep 10 } $PercentComplete = ($i / $Count) * 100 Write-DebugLog -Message "-Activity Start-VM -Status $i/$count : $PercentComplete" } Write-DebugLog -Message "-Activity Start-VM -Status Done -complete" } catch { Write-DebugLog -Message $_.exception Write-Error -ErrorId "MOUNT_FAILED" -Message $_.exception.Message } } else { Start-VM -VM $ApplianceVirtualMachine | Out-Null $Count = 10 For ($i = 0; $i -le $Count; $i++) { $VMGuestObject = Get-VMGuest -VM $ApplianceVirtualMachine if ($VMGuestObject.State -eq "Running") { break } else { Start-Sleep 10 } $PercentComplete = ($i / $Count) * 100 Write-DebugLog -Message "-Activity Start-VM -Status $i/$count : $PercentComplete % Complete -PercentComplete $PercentComplete" } Write-DebugLog -Message "-Activity Start-VM -Status Done -complete" } } Write-DebugLog -Message "Restart vm successfull" Write-Verbose -Message "Restart vm successfull" } function Get-BlobContent { <# .DESCRIPTION This function downloads file from Azure account. .PARAMETER BlobName File name to be downladed. .PARAMETER ContainerName The Azure storage account container name used for downloading the virtual appliance .PARAMETER StorageAccountName The Azure storage account name used for downloading the virtual appliance. Contact NetApp for the account name. .EXAMPLE Get-OVA -StorageAccountName 'acountname' -ContainerName 'container' Description --------------------------------------- Downloads file from Azure account. #> param( [Parameter(Mandatory)] [string] $BlobName, [Parameter(Mandatory)] [string] $StorageAccountName, [Parameter(Mandatory)] [string] $ContainerName ) Write-DebugLog -Message " Get-BlobContent execution is started." Write-DebugLog -Message "Downloading file $BlobName" $FileUrl = 'https://' + $StorageAccountName + '.blob.core.windows.net/' + $ContainerName + '/' + $BlobName try { $GetLocation = Get-Location Write-DebugLog -Message "Downloading file to location $GetLocation" (New-Object System.Net.WebClient).DownloadFile($FileUrl, "$GetLocation/$BlobName") Write-DebugLog -Message "The file $BlobName downloaded" Write-DebugLog -Message "List of files in $GetLocation" (Get-ChildItem -Path $GetLocation).Name Write-DebugLog -Message "Downloaded file saved in the following file system folder" $GetLocation } catch { Write-DebugLog -Message $_.exception.Message write-error $_.exception.Message -ErrorAction Stop } Write-DebugLog -Message " Get-BlobContent execution is completed." } function Get-TimeStamp { return "{0:M/d/yyyy} {0:h:mm:ss tt}" -f (Get-Date) } function Write-DebugLog { param( $Message ) Write-Host -Message "$(Get-TimeStamp) $Message" } function Get-RandomCharacters ($length, $characters) { Write-DebugLog -Message "Get-RandomCharacters execution is started" $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length } $private:ofs = "" Write-DebugLog -Message "Get-RandomCharacters execution is completed" return [string]$characters[$random] } function getSuffledString ([string]$inputString) { Write-DebugLog -Message "getSuffledString execution is started." $characterArray = $inputString.ToCharArray() $scrambledStringArray = $characterArray | Get-Random -Count $characterArray.length $outputString = -join $scrambledStringArray Write-DebugLog -Message "getSuffledString execution is completed" return $outputString } function changeMaxRepeatingChar ($pwdText, $maxCharAllowed, $AllChars) { Write-DebugLog -Message "changeMaxRepeatingChar execution is started" $len = $pwdText.length; for ($i = 0; $i -lt $len; $i++) { $cur_count = 1; for ($j = $i + 1; $j -lt $len; $j++) { if ($pwdText[$i] -ne $pwdText[$j]) { break } $cur_count = $cur_count + 1; if ($cur_count -gt $maxCharAllowed) { $allcharExpectRepeated = $AllChars -replace $pwdText[$j] $pwdText = ($pwdText.substring(0, $j)) + (Get-RandomCharacters -length 1 -characters $allcharExpectRepeated) + $pwdText.substring(($j + 1)) break } } } Write-DebugLog -Message "changeMaxRepeatingChar execution is completed" return $pwdText } function Get-Password () { <# .DESCRIPTION This function generates a new password based on password policy for the appliance user .EXAMPLE Get-Password Description --------------------------------------- Returns password #> Write-DebugLog -Message "Get-Password execution is started" $password = "" #$SpecialChars ='!"ยง$%&/()=?}][{@#*+' #Password wont work properly when few special characters present. #Thats why few charactors are excluded. $SpecialChars = '!%()=}][{@#' $UppercaseChars = 'ABCDEFGHKLMNOPRSTUVWXYZ' $LowerCaseChars = 'abcdefghiklmnoprstuvwxyz' $Numerics = '1234567890' $AllAlphaBets = $UppercaseChars + $LowerCaseChars $AllChars = $AllAlphaBets + $Numerics $SsoPasswordPolicy = Get-SsoPasswordPolicy $MinNumericCount = $SsoPasswordPolicy | ForEach-Object { $_.MinNumericCount } $password += Get-RandomCharacters -length $MinNumericCount -characters $Numerics $MinSpecialCharCount = $SsoPasswordPolicy | ForEach-Object { $_.MinSpecialCharCount } $password += Get-RandomCharacters -length $MinSpecialCharCount -characters $SpecialChars $MinUppercaseCount = $SsoPasswordPolicy | ForEach-Object { $_.MinUppercaseCount } $password += Get-RandomCharacters -length $MinUppercaseCount -characters $UppercaseChars $MinLowercaseCount = $SsoPasswordPolicy | ForEach-Object { $_.MinLowercaseCount } $password += Get-RandomCharacters -length $MinLowercaseCount -characters $LowerCaseChars $MinAlphabeticCount = $SsoPasswordPolicy | ForEach-Object { $_.MinAlphabeticCount } $ExtraAlphaRequired = $MinAlphabeticCount - ($MinLowercaseCount + $MinUppercaseCount) if ($ExtraAlphaRequired -gt 0) { $password += Get-RandomCharacters -length $ExtraAlphaRequired -characters $AllAlphaBets } $MinLength = $SsoPasswordPolicy | ForEach-Object { $_.MinLength } $ExtraCharRequiredForMinLength = $MinLength - $password.length if ($ExtraCharRequiredForMinLength -gt 0) { $password += Get-RandomCharacters -length $ExtraCharRequiredForMinLength -characters ($AllAlphaBets + $Numerics + $SpecialChars) } $MaxIdenticalAdjacentCharacters = $SsoPasswordPolicy | ForEach-Object { $_.MaxIdenticalAdjacentCharacters } $pwdText = changeMaxRepeatingChar -pwdText $password -maxCharAllowed $MaxIdenticalAdjacentCharacters -AllChars $AllChars $pwdText = getSuffledString $pwdText Write-DebugLog -Message "Get-Password execution is completed" return $pwdText } function Set-Password { <# .DESCRIPTION This function removes the role from the vCenter. .PARAMETER vcUserCre Specify the credential. .EXAMPLE Set-Password Description --------------------------------------- Removes the role 'role1' #> param( [Parameter( Mandatory = $true, HelpMessage = 'Specify the credential.')] [System.Management.Automation.PSCredential] $vcUserCredential ) Write-DebugLog -Message "Set-Password execution is started" $domain = "vsphere.local" $userName = $vcUserCredential.UserName $newPassword = $vcUserCredential.GetNetworkCredential().Password Write-DebugLog -Message "Get-SsoPersonUser -Domain $domain -Name $userName" $User = Get-SsoPersonUser -Domain $domain -Name $userName Write-DebugLog -Message "SCDPAdminObject" if ($null -eq $User) { Write-DebugLog -Message "No such user" write-error "Appliance user with name NetAppSCDPAdmin does not exist" -ErrorAction Stop } else { #Change NetAppSCDPAdmin password try { Set-SsoPersonUser -User $User -NewPassword $newPassword -ErrorAction Stop | Out-Null Write-DebugLog -Message "Password changed" } catch { Write-DebugLog -Message "Password change failed" write-error "Password change failed" -ErrorAction Stop } } Write-DebugLog -Message "Set-Password execution is completed" } function Get-ApplianceVirtualMachineUsingTag { Write-DebugLog -Message " Get-ApplianceVirtualMachineUsingTag execution started" $tagName = "AVS_ANF_CLOUD_ADMIN_VM_TAG" $tagCategoryName = "AVS_ANF_CLOUD_ADMIN_VM_TAG_CATEGORY" $ApplianceVirtualMachine = "" $ApplianceVirtualMachineArray = [System.Collections.ArrayList]@() Write-DebugLog "Checking if the VM exists" $tagAssignment = $null try { $tagAssignment = Get-TagAssignment -Tag $tagName -Category $tagCategoryName -ErrorAction SilentlyContinue } catch { if ($tagAssignment) { Write-DebugLog "Inside catch block but tagAssignment is not empty" if ($tagAssignment.Entity.Name) { Write-DebugLog "Appliance name "$tagAssignment.Entity.Name | Out-String } } Write-DebugLog $_.exception | Out-String } if ($tagAssignment) { Write-DebugLog "Tag Present" if ($tagAssignment.Entity.Name -is [array]) { Write-DebugLog "More than one VM present with tag AVS_ANF_CLOUD_ADMIN_VM_TAG" $noOfVM = $tagAssignment.Entity.Name.Count For ($i = 0; $i -lt $noOfVM; $i++) { $ApplianceVirtualMachineArray.Add($tagAssignment.Entity.Name[$i]) | Out-Null } } else { Write-DebugLog "One VM present with tag AVS_ANF_CLOUD_ADMIN_VM_TAG" $ApplianceVirtualMachineArray.Add($tagAssignment.Entity.Name) | Out-Null Write-DebugLog "First element inside ApplianceVirtualMachineArray: "$ApplianceVirtualMachineArray[0] Write-DebugLog "No of VMs are: "$ApplianceVirtualMachineArray.Count } if ($ApplianceVirtualMachineArray.Count -lt 1) { Write-DebugLog "VM with the tag $tagName does not exist" return ""; } if ($ApplianceVirtualMachineArray.Count -eq 1) { return $ApplianceVirtualMachineArray[0] } if ($ApplianceVirtualMachineArray.Count -gt 1) { Write-DebugLog -Message "Below Virtual machine appliance assosiated with the tag $tagName and tag categoy $tagCategoryName." foreach ($element in $ApplianceVirtualMachineArray) { Write-DebugLog -Message $element } $ApplianceVirtualMachine = Read-Host "Appliance Virtual Machine Name " return $ApplianceVirtualMachine } } } function Test-ApplianceExistOrNot { param( [Parameter(Mandatory = $true)] $ApplianceVirtualMachine ) Write-DebugLog -Message "Test-ApplianceExistOrNot execution started" $VMObject = $null try { $VMObject = Get-VM -Name $ApplianceVirtualMachine -ErrorAction Stop } catch { if ($_.CategoryInfo.Category -eq "ObjectNotFound") { Write-DebugLog -Message "VM with name $ApplianceVirtualMachine does not exist" Write-Error -ErrorId "UNINSTALL-NO-SUCH-VM-ERROR" -Message "VM with name $ApplianceVirtualMachine does not exist" write-error $_.exception.Message -ErrorAction Stop } else { Write-DebugLog -Message $_.exception | Out-String write-error $_.exception.Message -ErrorAction Stop } } if ($VMObject) { Write-DebugLog -Message "Virtual Machine exist" } else { Write-DebugLog -Message "VM with name $ApplianceVirtualMachine does not exist" Write-DebugLog -Message "VM with name $ApplianceVirtualMachine does not exist" write-error "VM with name $ApplianceVirtualMachine does not exist" -ErrorAction Stop } return $VMObject } function Test-DataStore { param( [Parameter(Mandatory = $true)] [String] $VmDatastore, [Parameter(Mandatory = $true)] [Int] $FreeSapce ) Write-DebugLog -Message "Test-DataStoreExistOrNot execution started" try { $datastore = Get-Datastore | Where-Object { $_.Name -eq $VmDatastore } $ds_space_gb = $datastore.FreeSpaceGB if ($ds_space_gb -lt $FreeSapce) { write-error "Datastore provided for deployment doesn't have enough free space for the deployment. Minimum required $FreeSapce GB" -ErrorAction Stop } else { Write-DebugLog -Message "SUCCESS: Datastore has enough free space for ova deployment." } } catch { write-error $_.exception.Message -ErrorAction Stop } if ($datastore) { Write-DebugLog "Datastore exists" } else { write-error "Invalid datastore" -ErrorAction Stop } } function Test-IpAddress { <# .SYNOPSIS Tests one or more IP Addresses to determine if they are valid. .DESCRIPTION Test-IpAddress is a function that tests one or more IP Addresses to determine if they are valid. The detailed parameter can be used to return additional information about the IP. .PARAMETER IpAddress One or more IP Addresses to test. This parameter is mandatory. .EXAMPLE Test-IpAddress -IpAddress '192.168.0.1', '192.168.0.256' .EXAMPLE Test-IpAddress -IpAddress '192.168.0.1' .EXAMPLE '::1', '192.168.0.256' | Test-MrIpAddress .INPUTS String .OUTPUTS Boolean #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)] [string[]]$IpAddress ) PROCESS { foreach ($Ip in $IpAddress) { try { $Results = $Ip -match ([IPAddress]$Ip) } catch { Write-Output $false Continue } Write-Output $Results } } } Function Get-VMToolsStatus { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeLine = $true)] [string[]]$ApplianceVirtualMachine ) PROCESS { try { $InputObject = Get-VM $ApplianceVirtualMachine [PSCustomObject]@{ Name = $InputObject.Name Status = $InputObject.ExtensionData.Guest.ToolsStatus GuestState = $InputObject.ExtensionData.Guest.GuestState UpgradeStatus = $InputObject.ExtensionData.Guest.ToolsVersionStatus2 Version = $InputObject.ExtensionData.Guest.ToolsVersion } } catch { Write-Error $_.Exception.Message } } } function checkPSVersion { # This function checks whether Powershell version in the system is greatear than 7 or not $PowerShellVersion = $PSVersionTable.PSVersion.Major if ($PowerShellVersion -lt 7) { write-error "Powershell version is less than 7. Please install powershell version 7.x and run again." -ErrorAction Stop } else { Write-DebugLog -Message "SUCCESS: Check for powershell version passed" } } function checkModule { param( [String]$module ) $module_exists = Get-Module -Name $module if ($module_exists) { Write-DebugLog -Message "SUCCESS: Check for module $module passed" } else { write-error "Module $module not available. Please make sure the module is imported and try again." -ErrorAction Stop } } function checkVcaddress { try { if (-Not $VC_ADDRESS) { Write-Error "VC_ADDRESS is not set as a powershell variable. Please set it and run the script again" -ErrorAction Stop } else { Write-DebugLog -Message "SUCCESS: VCenter Address is set." } } catch { Write-Error "VC_ADDRESS is not set as a powershell variable. Please set it and run the script again" -ErrorAction Stop } } function Invoke-PreflightNetAppCBSAVSCheck { [CmdletBinding()] param() Process { checkPSVersion checkVcaddress checkModule "VMware.VimAutomation.Core" checkModule "VMware.vSphere.SsoAdmin" checkModule "Microsoft.AVS.Management" } } function ping_vm { param( $vm_ip = $( throw "specify vm ip" ), $timeout = 600 ) Write-DebugLog -Message "### $($MyInvocation.MyCommand) ###" $rlt = 0 while ($timeout -gt 0) { $rc = test-connection -computername $vm_ip -quiet if (!$rc) { Write-DebugLog -Message "$vm_ip is not reachable, sleep for 5 seconds.." start-sleep 5 } else { Write-DebugLog -Message "$vm_ip is pingable now." $rlt = 1 break } $timeout -= 5 } return $rlt } # Import Module Advanced Functions Implementation Get-ChildItem -Path $PSScriptRoot -Filter '*.ps1' | ForEach-Object { Write-DebugLog -Message "Importing file: $($_.BaseName)" try { .$_.FullName } catch { Write-Error -Message "Failed to import functions from $($_.Fullname): $_" } } |