JSDR.Configuration.psm1

using module Microsoft.AVS.Management
<#
    Prerequisite:
    =============
    1. Module VMware.vSphere.SsoAdmin should be present
    2. CloudAdmin role is present within vcenter
    3. powershell version > 6
#>


function Get-JetDR {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function downloads JetStream DR software from MMS

    .PARAMETER Url
    Url of the bundle to download

    .PARAMETER DownloadPath
    Path where the bundle has to be downloaded

    .EXAMPLE
    Get-JetDR -Url https://example.com/file.zip -DownloadPath /home/user/downloads
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Url of the bundle to download")]
        [string]$Url,

        [Parameter(Mandatory=$true,
                    HelpMessage="Download location")]
        [string]$DownloadPath
    )

    Process {
        $Filename = Split-Path $Url -Leaf
        $download_file_path = $DownloadPath + '/' + $Filename
        download_jetdr_bundle $Url $download_file_path
    }
}

function Expand-JetDR {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function unzips JetStream DR software

    .PARAMETER Filename
    Name of the bundle

    .PARAMETER FilePath
    Path where the bundle is located

    .PARAMETER UnzipPath
    Path where bundle will be unzipped

    .EXAMPLE
    Expand-JetDR -FileName file.zip -FilePath /home/user/downloads/ -UnzipPath /home/user/downloads/jsdr/
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Name of the bundle")]
        [string]$Filename,

        [Parameter(Mandatory=$true,
                    HelpMessage="Bundle location")]
        [string]$FilePath,

        [Parameter(Mandatory=$true,
                    HelpMessage="Unzip location")]
        [string]$UnzipPath
    )

    Process {
        $js_download_path = $FilePath + '/' + $Filename
        unzip_ova $js_download_path $UnzipPath
    }
}

function Deploy-JetDRMSA {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function deploys JetStream DR Management Server Appliance(MSA), powers it on and waits for all services to be running

    .PARAMETER OvfPath
    Full path of the ova file

    .PARAMETER Network
    Network for the MSA, e.g "VM Network"

    .PARAMETER Hostname
    Hostname of the MSA

    .PARAMETER MSACredential
    MSACredential of root user

    .PARAMETER Gateway
    Gateway of MSA

    .PARAMETER Dns
    DNS IP that MSA should use

    .PARAMETER Ip
    IP of MSA

    .PARAMETER Netmask
    Netmask of MSA

    .PARAMETER Cluster
    Cluster name where MSA needs to be deployed

    .PARAMETER VmName
    Name of the MSA VM

    .PARAMETER Datastore
    Datastore where the MSA has to be deployed

    .EXAMPLE
    Deploy-JetDRMSA -OvfPath /home/user/downloads/jsdr.ova -Network "VM Network" -Hostname msavm.example.com -MSACredential <root/PSCredential object> -Gateway xxx.xxx.xxx.xxx -Dns xxx.xxx.xxx.xxx -Ip xxx.xxx.xxx.xxx -Netmask xxx.xxx.xxx.xxx -Cluster Test-Cluster -VmName JS-MSA -Datastore md3817
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Location of the ova")]
        [string]$OvfPath,

        [Parameter(Mandatory=$true,
                    HelpMessage="Location of the ova signature")]
        [string]$SignaturePath,

        [Parameter(Mandatory=$true,
                    HelpMessage="Network device for MSA")]
        [string]$Network,

        [Parameter(Mandatory=$false,
                    HelpMessage="Hostname of MSA")]
        [string]$Hostname,

        [Parameter(Mandatory=$true,
                    HelpMessage="MSA Credentials of root user")]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,

        [Parameter(Mandatory=$false,
                    HelpMessage="Gateway for MSA")]
        [string]$Gateway,

        [Parameter(Mandatory=$false,
                    HelpMessage="DNS IP that MSA should use")]
        [string]$Dns,

        [Parameter(Mandatory=$false,
                    HelpMessage="IP for MSA")]
        [string]$Ip,

        [Parameter(Mandatory=$false,
                    HelpMessage="Netmask for MSA")]
        [string]$Netmask,

        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster name where MSA will be deployed")]
        [string]$Cluster,

        [Parameter(Mandatory=$true,
                    HelpMessage="Vm name for MSA")]
        [string]$VmName,

        [Parameter(Mandatory=$true,
                    HelpMessage="Datastore where MSA will be deployed")]
        [string]$Datastore
    )

    Process {
        $Password=$MSACredential.GetNetworkCredential().Password
        $mycluster=Get-Cluster -Name $Cluster
        $msa=Get-VM -Name $VmName -Location $mycluster -ErrorAction SilentlyContinue
        if ($null -ne $msa) {
            write-host "MSA VM with the same name already exists in the Cluster $Cluster. Skipping creation"
            if($msa.PowerState -eq 'PoweredOff') {
                write-host "MSA VM is powered off, powering it on"
                start-vm $msa -confirm:$false > $null
                if (!$?) {
                    write-host "Starting MSA VM failed"
                    break
                 }
            }

                $vm_ip=get_vm_ip $VmName 600

                $rc=ms_rest_state $vm_ip "root" $Password 600
                if (!$rc) {
                    write-host "Failed to ping $vm_ip after 600 seconds"
                    break
                }
                write-host "Sleep for 2 more minute after Manamgement server becomes pingable"
                start-sleep 120
        }
        else {
            # Deploy the Management server appliance from the ova
            $vm_ip=deploy_ova $OvfPath $SignaturePath $Network $Hostname $Password $Gateway $Dns $Ip  $Netmask $Cluster $VmName $Datastore
        }
        return $vm_ip
    }
}

function Add-User {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function creates a new sso user

    .PARAMETER Username
    Username of the new sso user

    .PARAMETER Password
    Password of the new sso user

    .EXAMPLE
    Add-User -Username vsphere.local\tmpuser -Password ***
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="New sso username")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="Password of new sso user")]
        [string]$Password
    )

    Process {
        $domain = $Username.split("\")[0]
        $user = $Username.split("\")[1]
        $ssouser = Get-SsoPersonUser -Name $user -Domain $domain
        if($ssouser) {
            write-host "User $Username already exists. Deleting before creating again."
            delete_user $Username
            start-sleep 5
        }
        create_user $user $Password
    }
}

function Remove-User {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function deletes an sso user

    .PARAMETER Username
    Username of the sso user

    .EXAMPLE
    Remove-User -Username vsphere.local\tmpuser
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="sso username")]
        [string]$Username
    )

    Process {
        delete_user $Username
    }
}
function New-Role {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function creates a new role JSDR-elevated and assigns that role to the
    user created by Add-User

    .PARAMETER Username
    Username of the new sso user

    .PARAMETER Role
    Type of role to be created, elevated or operations

    .EXAMPLE
    New-Role -Username vsphere.local\tmpuser -Role elevated
    New-Role -Username vsphere.local\tmpuser -Role operations
#>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="New sso username")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="Type of role. Either elevated or operations")]
        [string]$Role
    )

    Begin {
        $extra_full_privilleges = "Maintenance", "Query patch", "CIM interaction", "Profile-driven storage update", "Register extension", "Unregister extension", "Update extension", "Security Profile and Firewall"
        $op_privilleges = "Register extension", "Unregister extension", "Update extension", "CIM interaction"
    }
    Process {
        if($Role -eq 'elevated') {
            $role = "JSDR-elevated"
            $privilleges = $extra_full_privilleges
        }
        elseif($Role -eq 'operations') {
            $role = "JSDR-operations"
            $privilleges = $op_privilleges
        }
        else {
            write-host "Invalid role specified. Must be one of 'elevated' or 'operations'"
            break
        }
        assign_new_role_to_user $role $Username $privilleges
    }
}

function Register-MS {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function registers JetStream MSA with vCenter

    .PARAMETER MS
    Management server ip/fqdn

    .PARAMETER MsaUser
    Management server user, e.g root

    .PARAMETER MsaPassword
    Management server password for MsaUser

    .PARAMETER VC
    vCenter ip/fqdn

    .PARAMETER Username
    Username of the new sso user, e.g vsphere.local\tmpuser

    .PARAMETER Password
    Password of the new sso user

    .PARAMETER RegisterWithIp
    Register MSA with IP instead of hostname

    .PARAMETER Mode
    Mode in which MSA has to be registered, e.g 'C2C'

    .EXAMPLE
    Register-MS -MS xxx.xxx.xxx.xxx -MsaUser root -MsaPassword *** -VC xxx.xxx.xxx.xxx -Username vsphere.local\tmpuser -Password *** -Mode C2C -RegisterWithIp $true
#>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of MSA")]
        [string]$MS,

        [Parameter(Mandatory=$true,
                    HelpMessage="MSA user")]
        [string]$MsaUser,

        [Parameter(Mandatory=$true,
                    HelpMessage="MSA password")]
        [string]$MsaPassword,

        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of vCenter")]
        [string]$VC,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso username with which vCenter will be registered")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso user password")]
        [string]$Password,

        [Parameter(Mandatory=$true,
                    HelpMessage="Register MSA with IP instead of hostname")]
        [bool]$RegisterWithIp,

        [Parameter(Mandatory=$true,
                    HelpMessage="Mode in which MSA will be registered C2C")]
        [string]$Mode="C2C"
    )

    Process {
        $response = get_ms_state $MS $MsaUser $MsaPassword
        if ($response.configured -eq $True) {
            write-host "MSA $MS already registered to vCenter. Skipping registration"
        }
        else {
            register_ms_with_vc $MS $MsaUser $MsaPassword $VC $Username $Password $Mode $RegisterWithIp
            start-sleep 10
        }
    }
}

function Unregister-MS {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function unregisters JetStream MSA from vCenter

    .PARAMETER MS
    Management server ip/fqdn

    .PARAMETER VC
    vCenter ip/fqdn

    .PARAMETER Username
    Username of the new sso user, e.g vsphere.local\tmpuser

    .PARAMETER Password
    Password of the new sso user

    .EXAMPLE
    Unregister-MS -MS xxx.xxx.xxx.xxx -VC xxx.xxx.xxx.xxx -Username vsphere.local\tmpuser -Password ***
#>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of MSA")]
        [string]$MS,

        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of vCenter")]
        [string]$VC,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso username with which vCenter will be registered")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso user password")]
        [string]$Password
    )

    Process {
        $fios_session_id = refresh_vc_session $MS $VC $Username $Password
        unregister_vcenter_from_ms $MS $VC $Username $Password $fios_session_id
        start-sleep 10
    }
}

function Install-Cluster {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function installs JetDR software to all hosts in the Cluster

    .PARAMETER MS
    Management server ip/fqdn

    .PARAMETER VC
    vCenter ip/fqdn

    .PARAMETER Username
    Username of the new sso user, e.g vsphere.local\tmpuser

    .PARAMETER Password
    Password of the new sso user

    .PARAMETER Cluster
    Cluster name which has to be configured

    .EXAMPLE
    Install-Cluster -MS xxx.xxx.xxx.xxx -VC xxx.xxx.xxx.xxx -Username vsphere.local\tmpuser -Password *** -Cluster prod-cluster
#>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of MSA")]
        [string]$MS,

        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of vCenter")]
        [string]$VC,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso username with which vCenter will be registered")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso user password")]
        [string]$Password,

        [Parameter(Mandatory=$true,
                    HelpMessage="Name of the cluster to be configured")]
        [string]$Cluster
    )

    Process {
        $fios_session_id = refresh_vc_session $MS $VC $Username $Password
        configure_cluster $MS $Cluster $fios_session_id
    }
}

function Uninstall-Cluster {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function uninstalls JetStream software from the cluster

    .PARAMETER MS
    Management server ip/fqdn

    .PARAMETER VC
    vCenter ip/fqdn

    .PARAMETER Username
    Username of the new sso user, e.g vsphere.local\tmpuser

    .PARAMETER Password
    Password of the new sso user

    .PARAMETER Cluster
    Cluster name which has to be unconfigured

    .EXAMPLE
    Uninstall-Cluster -MS xxx.xxx.xxx.xxx -VC xxx.xxx.xxx.xxx -Username vsphere.local\tmpuser -Password *** -Cluster prod-cluster
#>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of MSA")]
        [string]$MS,

        [Parameter(Mandatory=$true,
                    HelpMessage="ip/fqdn of vCenter")]
        [string]$VC,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso username with which vCenter will be unregistered")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="sso user password")]
        [string]$Password,

        [Parameter(Mandatory=$true,
                    HelpMessage="Name of the cluster to be unconfigured")]
        [string]$Cluster
    )

    Process {
        $fios_session_id = refresh_vc_session $MS $VC $Username $Password
        unconfigure_cluster $MS $Cluster $fios_session_id
    }
}

function Remove-Role {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function deletes a role from the vCenter and the elevated permissions from
    the sso user

    .PARAMETER Username
    Username of the new sso user

    .PARAMETER Role
    Type of role to be created, elevated or operations

    .EXAMPLE
    Remove-Role -Username vsphere.local\tmpuser -Role elevated
    Remove-Role -Username vsphere.local\tmpuser -Role operations
#>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="sso username")]
        [string]$Username,

        [Parameter(Mandatory=$true,
                    HelpMessage="Type of role. Either elevated or operations")]
        [string]$Role
    )

    Process {
        $user = $Domain + "\" + $Username
        if($Role -eq 'elevated') {
            $role = "JSDR-elevated"
        }
        elseif($Role -eq 'operations') {
            $role = "JSDR-operations"
        }
        else {
            write-host "Invalid role specified. Must be one of 'elevated' or 'operations'"
            break
        }
        $rootfolder = Get-Folder -NoRecursion
        $newly_added_permissions = Get-VIPermission -Entity $rootfolder -Principal $Username
        remove_permissions $newly_added_permissions
        remove_role $role
    }
}

function Restart-CIM {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
    .DESCRIPTION
    This function restarts CIM service on ESX hosts in the Cluster

    .PARAMETER Cluster
    Name of the cluster

    .EXAMPLE
    Restart-CIM -Cluster prod-cluster
#>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Name of the cluster")]
        [string]$Cluster
    )

    Process {
        restart_cim $Cluster
    }
}

function Install-JetDRWithStaticIP {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Deploys JetDr Management Server Appliance(MSA) with Static network IP configuration and configures one cluster

    .PARAMETER Network
    Network mapping for the MSA to be deployed, e.g 'VM Network'"

    .PARAMETER HostName
    Hostname of the MSA to be deployed

    .PARAMETER MSACredential
    root user credential of the MSA to be deployed

    .PARAMETER Gateway
    Gateway of the MSA to be deployed

    .PARAMETER Dns
    DNS IP that MSA should use

    .PARAMETER MSAIp
    Ip of the MSA to be deployed

    .PARAMETER Netmask
    Netmask of the MSA to be deployed

    .PARAMETER Cluster
    Cluster where the MSA will be deployed

    .PARAMETER VMName
    Name of the MSA VM

    .PARAMETER Datastore
    Datastore where MSA will be deployed

    .PARAMETER ProtectedCluster
    Cluster to be protected

    .PARAMETER RegisterWithIp
    Register MSA with IP instead of hostname

    .EXAMPLE

    Install-JetDRWithStaticIP -Network "VM Network" -HostName "jsdr-msa.example.com" -MSACredential <root/PSCredential Object> -Gateway xxx.xxx.xxx.xxx -Dns xxx.xxx.xxx.xxx -MSAIp xxx.xxx.xxx.xxx -Netmask xxx.xxx.xxx.xxx -Cluster MSA-Cluster -VMName jsdr-msa -Datastore shared-ds -ProtectedCluster Src-Cluster -RegisterWithIp $true

    .EXAMPLE

    Install-JetDRWithStaticIP -Network "VM Network" -HostName "jsdr-msa.example.com" -MSACredential <root/PSCredential Object> -Gateway xxx.xxx.xxx.xxx -Dns xxx.xxx.xxx.xxx -MSAIp xxx.xxx.xxx.xxx -Netmask xxx.xxx.xxx.xxx -Cluster MSA-Cluster -VMName jsdr-msa -Datastore shared-ds -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Network mapping for the MSA to be deployed, e.g 'VM Network'")]
        [String]$Network,
        [Parameter(Mandatory=$false,
                    HelpMessage="Hostname(fqdn) of the MSA to be deployed")]
        [String]$HostName,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credentials of root user of the MSA to be deployed")]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Gateway of the MSA to be deployed.")]
        [String]$Gateway,
        [Parameter(Mandatory=$true,
                    HelpMessage="DNS IP that MSA should use.")]
        [String]$Dns,
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA to be deployed.")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Netmask of the MSA to be deployed.")]
        [String]$Netmask,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster where MSA will be deployed")]
        [String]$Cluster,
        [Parameter(Mandatory=$true,
                    HelpMessage="Name of the MSA VM")]
        [String]$VMName,
        [Parameter(Mandatory=$true,
                    HelpMessage="Datastore where MSA will be deployed")]
        [String]$Datastore,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be protected")]
        [String]$ProtectedCluster,
        [Parameter(Mandatory=$false,
                    HelpMessage="Register MSA with Ip instead of hostname.")]
        [Bool]$RegisterWithIp=$true
    )
    Begin {
        $Mode = "C2C"
        # Script assumes that directory it is executed in is temporary
        $DownloadPath = "."

        $sso_user_name = "vsphere.local\jetdrusr"
        $sso_user_pwd=generate_password
        $js_url_file= "https://jsmms.blob.core.windows.net/jsdrmms/JSDR-GA-default.txt"
        $js_download_path = $DownloadPath
        $js_destination_folder = $js_download_path + "/js_unzipped/"
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()
        $VCIp = $VC_ADDRESS

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        # Run Preflight before install
        Invoke-PreflightJetDRInstall -ProtectedCluster $ProtectedCluster -Cluster $Cluster -VMName $VMName -Datastore $Datastore -Network $Network
        # Download JetDR bundle from MMS
        Invoke-WebRequest $js_url_file -OutFile $js_download_path/JSDR-GA-default.txt -Resume
        $js_url = Get-Content $js_download_path/JSDR-GA-default.txt
        $js_zip = Split-Path $js_url -Leaf
        Get-JetDR -Url $js_url -DownloadPath $js_download_path

        # Unzip JetDR bundle to specified location
        Expand-JetDR -FileName $js_zip -FilePath $js_download_path -UnzipPath $js_destination_folder

        $ovf_path = Get-ChildItem -Path $js_destination_folder -Filter "jetstream*ova" -Recurse | %{$_.FullName}
        $signature_path = Get-ChildItem -Path $js_destination_folder -Filter "signature" -Recurse | %{$_.FullName}

        # Create a new sso user
        Add-User -Username $sso_user_name -Password $sso_user_pwd

        # Create JSDR-elevated role and assign it to the newly created sso user
        New-Role -Username $sso_user_name -Role elevated

        # Deploy JetStream MSA
        $MSAIp=Deploy-JetDRMSA -OvfPath $ovf_path -SignaturePath $signature_path -Network $Network -Hostname $HostName -MSACredential $MSACredential -Gateway $Gateway -Dns $Dns -Ip $MSAIp -Netmask $Netmask -Cluster $Cluster -VmName $VMName -Datastore $Datastore

        # Register JetStream MSA with vCenter
        Register-MS -MS $MSAIp -MsaUser $UserName -MsaPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp

        # Configure cluster with JetStream software
        Install-Cluster -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Cluster $ProtectedCluster

        # Restart CIM service on hosts
        Restart-CIM $ProtectedCluster

        # Unregister JetStream MSA from vCenter
        Unregister-MS -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd

        # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
        Remove-Role -Username $sso_user_name -Role elevated

        # Create JSDR-operations role and assign it to the newly created sso user
        New-Role -Username $sso_user_name -Role operations

        # Register JetStream MSA with vCenter
        Register-MS -MS $MSAIp -MsaUser $UserName -MsaPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp

        # Delete permissions of JSDR-operations role from sso user and delete the role from vCenter
        Remove-Role -Username $sso_user_name -Role operations

        # Delete the sso user created for this task
        Remove-User -Username $sso_user_name
    }
}

function Install-JetDRWithDHCP {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Deploys JetDr Management Server Appliance(MSA) with Dynamic network IP configurations and configures one cluster

    .PARAMETER Network
    Network mapping for the MSA to be deployed, e.g 'VM Network'"

    .PARAMETER HostName
    Hostname of the MSA to be deployed

    .PARAMETER MSACredential
    root user credential of the MSA to be deployed

    .PARAMETER Cluster
    Cluster where the MSA will be deployed

    .PARAMETER VMName
    Name of the MSA VM

    .PARAMETER Datastore
    Datastore where MSA will be deployed

    .PARAMETER ProtectedCluster
    Cluster to be protected

    .PARAMETER RegisterWithIp
    Register MSA with IP instead of hostname

    .EXAMPLE

    Install-JetDRWithDHCP -Network "VM Network" -HostName "jsdr-msa.example.com" -MSACredential <root/PSCredential Object> -Cluster MSA-Cluster -VMName jsdr-msa -Datastore shared-ds -ProtectedCluster Src-Cluster
#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Network mapping for the MSA to be deployed, e.g 'VM Network'")]
        [String]$Network,
        [Parameter(Mandatory=$false,
                    HelpMessage="Hostname(fqdn) of the MSA to be deployed")]
        [String]$HostName,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credentials of root user of the MSA to be deployed")]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster where MSA will be deployed")]
        [String]$Cluster,
        [Parameter(Mandatory=$true,
                    HelpMessage="Name of the MSA VM")]
        [String]$VMName,
        [Parameter(Mandatory=$true,
                    HelpMessage="Datastore where MSA will be deployed")]
        [String]$Datastore,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be protected")]
        [String]$ProtectedCluster,
        [Parameter(Mandatory=$false,
                    HelpMessage="Register MSA with Ip instead of hostname.")]
        [Bool]$RegisterWithIp=$true
    )
    Begin {
        $Mode = "C2C"
        # Script assumes that directory it is executed in is temporary
        $DownloadPath = "."

        $sso_user_name = "vsphere.local\jetdrusr"
        $sso_user_pwd=generate_password
        $js_url_file = "https://jsmms.blob.core.windows.net/jsdrmms/JSDR-GA-default.txt"
        $js_download_path = $DownloadPath
        $js_destination_folder = $js_download_path + "/js_unzipped/"
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()
        $VCIp = $VC_ADDRESS
        $Gateway = ''
        $Dns = ''
        $MSAIp = ''
        $Netmask = ''

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        # Run Preflight before install
        Invoke-PreflightJetDRInstall -ProtectedCluster $ProtectedCluster -Cluster $Cluster -VMName $VMName -Datastore $Datastore -Network $Network
        # Download JetDR bundle from MMS
        Invoke-WebRequest $js_url_file -OutFile $js_download_path/JSDR-GA-default.txt -Resume
        $js_url = Get-Content $js_download_path/JSDR-GA-default.txt
        $js_zip = Split-Path $js_url -Leaf
        Get-JetDR -Url $js_url -DownloadPath $js_download_path

        # Unzip JetDR bundle to specified location
        Expand-JetDR -FileName $js_zip -FilePath $js_download_path -UnzipPath $js_destination_folder

        $ovf_path = Get-ChildItem -Path $js_destination_folder -Filter "jetstream*ova" -Recurse | %{$_.FullName}
        $signature_path = Get-ChildItem -Path $js_destination_folder -Filter "signature" -Recurse | %{$_.FullName}

        # Create a new sso user
        Add-User -Username $sso_user_name -Password $sso_user_pwd

        # Create JSDR-elevated role and assign it to the newly created sso user
        New-Role -Username $sso_user_name -Role elevated

        # Deploy JetStream MSA
        $MSAIp=Deploy-JetDRMSA -OvfPath $ovf_path -SignaturePath $signature_path -Network $Network -Hostname $HostName -MSACredential $MSACredential -Gateway $Gateway -Dns $Dns -Ip $MSAIp -Netmask $Netmask -Cluster $Cluster -VmName $VMName -Datastore $Datastore

        Invoke-VMScript -VM $VMName -ScriptText 'echo "jss.dr.vc.forceUnregister=true" >> /var/lib/vme2/conf/server.properties' -GuestUser $UserName -GuestPassword $Password | Out-Null
        Invoke-VMScript -VM $VMName -ScriptText '/etc/init.d/vme2 restart' -GuestUser $UserName -GuestPassword $Password | Out-Null

        # Register JetStream MSA with vCenter
        Register-MS -MS $MSAIp -MsaUser $UserName -MsaPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp

        # Configure cluster with JetStream software
        Install-Cluster -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Cluster $ProtectedCluster

        # Restart CIM service on hosts
        Restart-CIM $ProtectedCluster

        # Unregister JetStream MSA from vCenter
        Unregister-MS -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd

        # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
        Remove-Role -Username $sso_user_name -Role elevated

        # Create JSDR-operations role and assign it to the newly created sso user
        New-Role -Username $sso_user_name -Role operations

        # Register JetStream MSA with vCenter
        Register-MS -MS $MSAIp -MsaUser $UserName -MsaPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp

        # Delete permissions of JSDR-operations role from sso user and delete the role from vCenter
        Remove-Role -Username $sso_user_name -Role operations

        # Delete the sso user created for this task
        Remove-User -Username $sso_user_name
    }
}

function Uninstall-JetDR {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Unconfigures cluster, unregisters vCenter from the JetDr MSA

    .PARAMETER MSAIp
    MSA IP

    .PARAMETER MSACredential
    Credential of root user of MSA(root or PSCredential Object)

    .PARAMETER ProtectedCluster
    Cluster to be unconfigured

    .EXAMPLE

    Uninstall-JetDR -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be unconfigured")]
        [String]$ProtectedCluster
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrusr"
        $sso_user_pwd=generate_password
        $VCIp = $VC_ADDRESS

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        # Run Preflight before uninstall
        Invoke-PreflightJetDRUninstall -MSAIp $MSAIp -MSACredential $MSACredential -ProtectedCluster $ProtectedCluster

        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-elevated role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role elevated

            # Check for presence of DR Virtual appliance before unregistering
            $fios_session_id = refresh_vc_session $MSAIp $VCIp $sso_user_name $sso_user_pwd
            get_drvas $MSAIp $fios_session_id

            # Unconfigure JetStream software from cluster
            Uninstall-Cluster -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Cluster $ProtectedCluster

            # Unregister JetStream MSA from vCenter
            Unregister-MS -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd

        } finally {
            # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role elevated

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Invoke-PreflightJetDRInstall {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Checks to display current state of the system and minimum requirement are met before deploying JeDR. It also checks for minimum of 3 hosts in a cluster, jetdr plugin if already present in vcenter and if a vm exists with same name as MSA

    .PARAMETER VMName
    Name of the MSA VM

    .PARAMETER Cluster
    Cluster where the MSA will be deployed

    .PARAMETER ProtectedCluster
    Cluster to be protected

    .PARAMETER Datastore
    Datastore where MSA will be deployed

    .PARAMETER Network
    Network mapping for the MSA to be deployed, e.g 'VM Network'

    .EXAMPLE

    Invoke-PreflightJetDRInstall -VMName jsdr-msa -Cluster MSA-Cluster -ProtectedCluster Src-Cluster -Datastore datastore-name -Network network-name

#>


    [CmdletBinding()]
    [AVSAttribute(5, UpdatesSDDC = $false)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Name of MSA VM")]
        [String]$VMName,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster Name where MSA will be deployed")]
        [String]$Cluster,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be protected")]
        [String]$ProtectedCluster,
        [Parameter(Mandatory=$true,
                    HelpMessage="Datastore where MSA will be deployed")]
        [String]$Datastore,
        [Parameter(Mandatory=$true,
                    HelpMessage="Network mapping for the MSA to be deployed, e.g 'VM Network'")]
        [String]$Network
    )

    #Trimming string parameters for any leading and trailing spaces
    foreach ($key in $($PSBoundParameters.keys)) {
        if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
            $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
            Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
        }
    }

    get_system_state_install $VMName $Cluster $ProtectedCluster $Datastore $Network
}

function Invoke-PreflightJetDRUninstall {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Checks to display current state of the system and minimum requirement are met before uninstalling JeDR. It also checks for minimum of 4 hosts in a cluster

    .PARAMETER MSAIp

    Ip of the MSA

    .PARAMETER MSACredential

    root credentials of MSA

    .PARAMETER ProtectedCluster

    Cluster to be protected

    .EXAMPLE

    Invoke-PreflightJetDRUninstall -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(5, UpdatesSDDC = $false)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="IP of MSA VM")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Protected Cluster")]
        [String]$ProtectedCluster
    )

    if (!$MSACredential) {
        write-error "Please provide MSA credential, -MSACredential <root/PS Credential Object>" -ErrorAction Stop
    }
    else {
        $MSaUser = $MSACredential.UserName.trim()
        $MSaPassword = $MSACredential.GetNetworkCredential().Password.trim()
    }

    #Trimming string parameters for any leading and trailing spaces
    foreach ($key in $($PSBoundParameters.keys)) {
        if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
            $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
            Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
        }
    }

    get_system_state_uninstall $MSAIp $ProtectedCluster $MSaUser $MSaPassword
}

function Invoke-PreflightJetDRSystemCheck {
<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    This Cmdlet checks and displays current state of the system
    It checks whether the minimal requirements for the script to run are met.

    .EXAMPLE

    Invoke-PreflightJetDRSystemCheck
#>


    [CmdletBinding()]
    param()
    Begin {
        $role = "CloudAdmin"
    }
    Process {
        checkPSVersion
        checkVcaddress
        checkRole $role
        checkModule "VMware.vSphere.SsoAdmin"
        checkModule "VMware.VimAutomation.Core"
        Write-Host "Invoke-PreflightJetDRSystemCheck option only checks required configuration in the system to execute other Cmdlets. For more detailed check, try running Invoke-PreflightJetDRInstall/Invoke-PreflightJetDRUninstall."
    }
}

function Enable-JetDRForCluster {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Configures an additional cluster for protection. installs vib to all hosts in the cluster and creates storage policies.

    .PARAMETER MSAIp

    Ip of the MSA

    .PARAMETER MSACredential

    root credentials of MSA

    .PARAMETER ProtectedCluster

    Cluster to be protected

    .EXAMPLE

    Enable-JetDRForCluster -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(20, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credentials of root user of the MSA to be deployed")]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be protected")]
        [String]$ProtectedCluster
    )
    Begin {
        $Mode = "C2C"
        $VCIp = $VC_ADDRESS
        $sso_user_name = "vsphere.local\jetdrelevatedusr"
        $sso_user_pwd = generate_password
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        # Preflight checks for cluster configure
        get_system_state_configure $ProtectedCluster

        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-elevated role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role elevated

            # Configure cluster with JetStream software
            Install-Cluster -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Cluster $ProtectedCluster

            # Restart CIM service on hosts
            Restart-CIM $ProtectedCluster
        } finally {
            # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role elevated

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Disable-JetDRForCluster {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Unconfigures a cluster, uninstalls vibs from all hosts in the cluster and removes storage policies. It will not uninstall JetDR completely

    .PARAMETER MSAIp

    Ip of the MSA

    .PARAMETER MSACredential

    root credentials of MSA

    .PARAMETER ProtectedCluster

    Cluster to be unconfigured

    .EXAMPLE

    Disable-JetDRForCluster -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be unconfigured")]
        [String]$ProtectedCluster
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrelevatedusr"
        $sso_user_pwd=generate_password
        $Mode = "C2C"
        $VCIp = $VC_ADDRESS
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        # Preflight check for cluster unconfigure
        Invoke-PreflightJetDRUninstall -MSAIp $MSAIp -MSACredential $MSACredential -ProtectedCluster $ProtectedCluster

        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-elevated role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role elevated

            # Unconfigure JetStream software from cluster
            Uninstall-Cluster -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Cluster $ProtectedCluster
        } finally {
            # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role elevated

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Update-JetDRMSA {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Upgrades JetDR MSA and plugin to latest available update.

    .PARAMETER MSAIp
    Ip of the MSA

    .PARAMETER MSACredential
    root credentials of MSA

    .PARAMETER Datacenter
    Datacenter which manages the clusters

    .PARAMETER Datastore
    Datastore where upgrade iso will be copied

    .PARAMETER VMName
    MSA VM name where upgrade iso will be mounted

    .EXAMPLE

    Update-JetDRMSA -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -Datacenter Datacenter -Datastore shared-ds -VMName js-dr

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $False)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Datacenter name")]
        [String]$Datacenter,
        [Parameter(Mandatory=$true,
                    HelpMessage="Datastore where upgrade iso will be copied")]
        [String]$Datastore,
        [Parameter(Mandatory=$true,
                    HelpMessage="MSA VM name where upgrade iso will be mounted")]
        [String]$VMName
    )
    Begin {
        # Script assumes that directory it is executed in is temporary
        $DownloadPath = "."

        $js_url_file= "https://jsmms.blob.core.windows.net/jsdrmms/JSDR-GA-default.txt"
        $js_download_path = $DownloadPath
        $js_destination_folder = $js_download_path + "/js_unzipped/"
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()
        $VCIp = $VC_ADDRESS

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        # Download JetDR bundle from MMS
        Invoke-WebRequest $js_url_file -OutFile $js_download_path/JSDR-GA-default.txt -Resume
        $js_url = Get-Content $js_download_path/JSDR-GA-default.txt
        $js_zip = Split-Path $js_url -Leaf
        Get-JetDR -Url $js_url -DownloadPath $js_download_path

        # Unzip JetDR bundle to specified location
        Expand-JetDR -FileName $js_zip -FilePath $js_download_path -UnzipPath $js_destination_folder

        $iso_path = Get-ChildItem -Path $js_destination_folder -Filter "jetstream*iso" -Recurse | %{$_.FullName}
        $signature_path = Get-ChildItem -Path $js_destination_folder -Filter "signature_iso" -Recurse | %{$_.FullName}
        updateMSA $MSAIp $UserName $Password $Datacenter $Datastore $VMName $iso_path $signature_path $VCIp
    }
}

function Update-JetDRCluster {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Upgrades JetDR iofilter to latest available update.

    .PARAMETER MSAIp
    Ip of the MSA

    .PARAMETER MSACredential
    root credentials of MSA

    .PARAMETER ProtectedCluster
    Cluster to be upgraded

    .EXAMPLE

    Update-JetDRCluster -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be upgraded")]
        [String]$ProtectedCluster
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrelevatedusr"
        $sso_user_pwd=generate_password
        $Mode = "C2C"
        $VCIp = $VC_ADDRESS
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        Invoke-PreflightJetDRUninstall -MSAIp $MSAIp -MSACredential $MSACredential -ProtectedCluster $ProtectedCluster
        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-elevated role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role elevated

            $fios_session_id = refresh_vc_session $MSAIp $VCIp $sso_user_name $sso_user_pwd
            $status = updateClusters $MSAIp $ProtectedCluster $fios_session_id

            if ($status -eq 0) {
                # Restart CIM service on hosts
                Restart-CIM $ProtectedCluster
            }
        } finally {
            # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role elevated

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Resolve-HostIssue {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Resolves last failed vCenter task on the host.

    .PARAMETER MSAIp
    Ip of the MSA

    .PARAMETER MSACredential
    root credentials of MSA

    .PARAMETER ProtectedCluster
    Cluster where the host resides

    .PARAMETER ESXHost
    Host where resolve issue will be done

    .EXAMPLE

    Resolve-HostIssue -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster -ESXHost esxi-host-name

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster where the host resides")]
        [String]$ProtectedCluster,
        [Parameter(Mandatory=$true,
                    HelpMessage="Host where resolve issue will be done")]
        [String]$ESXHost
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrelevatedusr"
        $sso_user_pwd=generate_password
        $Mode = "C2C"
        $VCIp = $VC_ADDRESS
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        Invoke-PreflightJetDRUninstall -MSAIp $MSAIp -MSACredential $MSACredential -ProtectedCluster $ProtectedCluster
        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-elevated role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role elevated

            $fios_session_id = refresh_vc_session $MSAIp $VCIp $sso_user_name $sso_user_pwd
            $status = resolveHostIssue $MSAIp $ProtectedCluster $ESXHost $fios_session_id

            if ($status -eq 0) {
                # Restart CIM service on hosts
                Get-VMHost -name $ESXhost | Get-VMHostService | where {$_.key -eq 'sfcbd-watchdog'} | Stop-VMHostService -Confirm:$false
                Get-VMHost -name $ESXhost | Get-VMHostService | where {$_.key -eq 'sfcbd-watchdog'} | Start-VMHostService -Confirm:$false
            }
        } finally {
            # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role elevated

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}


function Resolve-ClusterIssue {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION

    Resolves the errors occured during an install/uninstall/upgrade operation of an IO Filter on a cluster.

    .PARAMETER MSAIp
    Ip of the MSA

    .PARAMETER MSACredential
    root credentials of MSA

    .PARAMETER ProtectedCluster
    Cluster where resolve issue will be done

    .EXAMPLE

    Resolve-ClusterIssue -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -ProtectedCluster Src-Cluster

#>


    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster where resolve issue will be done")]
        [String]$ProtectedCluster
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrelevatedusr"
        $sso_user_pwd=generate_password
        $Mode = "C2C"
        $VCIp = $VC_ADDRESS
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        Invoke-PreflightJetDRUninstall -MSAIp $MSAIp -MSACredential $MSACredential -ProtectedCluster $ProtectedCluster
        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-elevated role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role elevated

            $fios_session_id = refresh_vc_session $MSAIp $VCIp $sso_user_name $sso_user_pwd
            $status = resolveClusterIssue $MSAIp $ProtectedCluster $fios_session_id

            if ($status -eq 0) {
                # Restart CIM service on all hosts
                restart_cim $ProtectedCluster
            }

        } finally {
            # Delete permissions of JSDR-elevated role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role elevated

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Register-JetDRPlugin {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION
    Registers JetDR plugin to vCenter

    .PARAMETER MSAIp
    Ip of the MSA

    .PARAMETER MSACredential
    root credentials of MSA

    .PARAMETER RegisterWithIp
    Register MSA with Ip instead of hostname

    .EXAMPLE

    Register-JetDRPlugin -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object> -RegisterWithIp:$true

#>


    [CmdletBinding()]
    [AVSAttribute(5, UpdatesSDDC = $False)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSAIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential,
        [Parameter(Mandatory=$false,
                    HelpMessage="Register MSA with Ip instead of hostname.")]
        [Bool]$RegisterWithIp=$true
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrusr"
        $sso_user_pwd=generate_password
        $Mode = "C2C"
        $VCIp = $VC_ADDRESS
        $UserName = $MSACredential.UserName.trim()
        $Password = $MSACredential.GetNetworkCredential().Password.trim()

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        try {
            # Create a new sso user
            Add-User -Username $sso_user_name -Password $sso_user_pwd

            # Create JSDR-operations role and assign it to the newly created sso user
            New-Role -Username $sso_user_name -Role operations

            # Register JetStream MSA with vCenter
            Register-MS -MS $MSAIp -MsaUser $UserName -MsaPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp
        } finally {
            # Delete permissions of JSDR-operations role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role operations

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Unregister-JetDRPlugin {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION
    Unregisters JetDR plugin from vCenter

    .PARAMETER MSAIp
    Ip of the MSA

    .PARAMETER MSACredential
    root credentials of MSA

    .EXAMPLE

    Unregister-JetDRPlugin -MSAIp xxx.xxx.xxx.xxx -MSACredential <root/PSCredential Object>

#>


    [CmdletBinding()]
    [AVSAttribute(5, UpdatesSDDC = $False)]
    param(
        [Parameter(Mandatory=$false,
                    HelpMessage="Ip of the MSA. Leave blank if MSA is not available.")]
        [String]$MSAIp,
        [Parameter(Mandatory=$false,
                    HelpMessage="Credential of the root user of MSA. Leave blank if MSA is not available.")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $MSACredential
    )
    Begin {
        $sso_user_name = "vsphere.local\jetdrusr"
        $sso_user_pwd=generate_password
        $VCIp = $VC_ADDRESS
        if ( $MSACredential -ne $null ) {
            $UserName = $MSACredential.UserName.trim()
            $Password = $MSACredential.GetNetworkCredential().Password.trim()
        }
        if (( $MSAIp -ne "" ) -And ( $MSACredential -eq $null )) {
            write-error "MSA ip is provided, but MSA credentials are missing. Please run again with proper root credentials of MSA." -ErrorAction Stop
        }

        #Trimming string parameters for any leading and trailing spaces
        foreach ($key in $($PSBoundParameters.keys)) {
            if ($PSBoundParameters[$key].GetType().Name -eq 'String') {
                $PSBoundParameters[$key] = $($PSBoundParameters[$key].trim())
                Set-Variable -Name $key -Value $($PSBoundParameters[$key].trim())
            }
        }
    }
    Process {
        try {
                # Create a new sso user
                Add-User -Username $sso_user_name -Password $sso_user_pwd

                # Create JSDR-operations role and assign it to the newly created sso user
                New-Role -Username $sso_user_name -Role operations

                if ( $MSAIp -ne "") {
                    # Unregister JetStream MSA from vCenter
                    Unregister-MS -MS $MSAIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd
                }
                else {
                    # Force unregister JetStream MSA from vCenter
                    force_unregister_ms
                }
        } finally {
            # Delete permissions of JSDR-operations role from sso user and delete the role from vCenter
            Remove-Role -Username $sso_user_name -Role operations

            # Delete the sso user created for this task
            Remove-User -Username $sso_user_name
        }
    }
}

function Restart-JetDRDaemon {
<#

    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================

    .DESCRIPTION
    Restarts JetDR daemon on every host in the cluster

    .PARAMETER ProtectedCluster
    Cluster where daemon should be restarted for all hosts

    .EXAMPLE
    Restart-JetDRDaemon -ProtectedCluster Src-Cluster

#>

[CmdletBinding()]
    [AVSAttribute(5, UpdatesSDDC = $False)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster where daemon should be restarted for all hosts")]
        [String]$ProtectedCluster
    )
    Process {
        restart_jetdr $ProtectedCluster
    }
}