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 Credential
    Credential 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 -Credential <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="Network device for MSA")]
        [string]$Network,

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

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

        [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=$Credential.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 $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 MsUser
    Management server user, e.g root
 
    .PARAMETER MsPassword
    Management server password for MsUser
 
    .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 -MsUser root -MsPassword *** -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]$MsUser,

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

        [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 $MsUser $MsPassword
        if ($response.configured -eq $True) {
            write-host "MSA $MS already registered to vCenter. Skipping registration"
        }
        else {
            register_ms_with_vc $MS $MsUser $MsPassword $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
    }
}

<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
 
    .DESCRIPTION
 
    This top level Cmdlet Downloads JetDr bundle from MMS, creates a new user, assigns
    elevated privilleges to the user, deploys JetDr Management Server Appliance(MSA),
    registers vCenter to the JetDr MSA, configures 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 Credential
    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 MSIp
    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" -Credential <root/PSCredential Object> -Gateway xxx.xxx.xxx.xxx -Dns xxx.xxx.xxx.xxx -MSIp 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" -Credential <root/PSCredential Object> -Gateway xxx.xxx.xxx.xxx -Dns xxx.xxx.xxx.xxx -MSIp xxx.xxx.xxx.xxx -Netmask xxx.xxx.xxx.xxx -Cluster MSA-Cluster -VMName jsdr-msa -Datastore shared-ds -ProtectedCluster Src-Cluster
 
#>

function Install-JetDRWithStaticIP {
    [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()]
        $Credential,
        [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]$MSIp,
        [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 = $Credential.UserName
        $Password = $Credential.GetNetworkCredential().Password
        $VCIp = $VC_ADDRESS
    }
    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}

    # 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
    $MSIp=Deploy-JetDRMSA -OvfPath $ovf_path -Network $Network -Hostname $HostName -Credential $Credential -Gateway $Gateway -Dns $Dns -Ip $MSIp -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 $MSIp -MsUser $UserName -MsPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp

    # Configure cluster with JetStream software
    Install-Cluster -MS $MSIp -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 $MSIp -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 $MSIp -MsUser $UserName -MsPassword $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
    }
}

<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
 
    .DESCRIPTION
 
    This top level Cmdlet Downloads JetDr bundle from MMS, creates a new user, assigns
    elevated privilleges to the user, deploys JetDr Management Server Appliance(MSA),
    registers vCenter to the JetDr MSA, configures 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 Credential
    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" -Credential <root/PSCredential Object> -Cluster MSA-Cluster -VMName jsdr-msa -Datastore shared-ds -ProtectedCluster Src-Cluster
#>

function Install-JetDRWithDHCP {
    [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()]
        $Credential,
        [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 = $Credential.UserName
        $Password = $Credential.GetNetworkCredential().Password
        $VCIp = $VC_ADDRESS
        $Gateway = ''
        $Dns = ''
        $MSIp = ''
        $Netmask = ''
    }
    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}

    # 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
    $MSIp=Deploy-JetDRMSA -OvfPath $ovf_path -Network $Network -Hostname $HostName -Credential $Credential -Gateway $Gateway -Dns $Dns -Ip $MSIp -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 $MSIp -MsUser $UserName -MsPassword $Password -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Mode $Mode -RegisterWithIp $RegisterWithIp

    # Configure cluster with JetStream software
    Install-Cluster -MS $MSIp -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 $MSIp -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 $MSIp -MsUser $UserName -MsPassword $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
    }
}

<#
    .NOTES
    ===========================================================================
    Created by: JetStream Software Inc
    ===========================================================================
 
    .DESCRIPTION
 
    The top level Cmdlet creates a new user, assigns elevated privilleges to the user,
    unconfigures cluster, unregisters vCenter from the JetDr MSA, removes the user.
 
    .PARAMETER MSIp
    MSA IP
 
    .PARAMETER Credential
    Credential of root user of MSA(root or PSCredential Object)
 
    .PARAMETER ProtectedCluster
    Cluster to be unconfigured
 
    .EXAMPLE
 
    Uninstall-JetDR -MSIp xxx.xxx.xxx.xxx -Credential <root/PSCredential Object> -ProtectedCluster Src-Cluster
 
#>

function Uninstall-JetDR {
    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential,
        [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
    }
    Process {
        # Run Preflight before uninstall
        Invoke-PreflightJetDRUninstall -MSIp $MSIp -Credential $Credential -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 $MSIp $VCIp $sso_user_name $sso_user_pwd
        get_drvas $MSIp $fios_session_id

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

    # Unregister JetStream MSA from vCenter
    Unregister-MS -MS $MSIp -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
        }
    }
}


<#
    .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.
    It also checks if the cluster has minimum of 4 hosts, if the cluster details are correct, if there is already a VM with the same name provided for installing MSA, if there is any jetdr plugin present in the vCenter.
 
    .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
 
#>

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

<#
    .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.
    It also checks if the cluster details are correct and if any VCenter is registered to the MSA
 
    .PARAMETER MSIp
 
    Ip of the MSA
 
    .PARAMETER Credential
 
    root credentials of MSA
 
    .PARAMETER ProtectedCluster
 
    Cluster to be protected
 
    .EXAMPLE
 
    Invoke-PreflightJetDRUninstall -MSIp xxx.xxx.xxx.xxx -Credential <root/PSCredential Object> -ProtectedCluster Src-Cluster
 
#>

function Invoke-PreflightJetDRUninstall {
    [CmdletBinding()]
    [AVSAttribute(5, UpdatesSDDC = $false)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="IP of MSA VM")]
        $MSIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Protected Cluster")]
        $ProtectedCluster
    )

    if (!$Credential) {
        write-error "Please provide MSA credential, -Credential <root/PS Credential Object>" -ErrorAction Stop
    }
    else {
        $MSUser = $Credential.UserName
        $MSPassword = $Credential.GetNetworkCredential().Password
    }
    get_system_state_uninstall $MSIp $ProtectedCluster $MSUser $MSPassword
}

<#
.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
#>

function 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." 
    }
}

<#
.NOTES
===========================================================================
Created by: JetStream Software Inc
===========================================================================
 
.DESCRIPTION
 
This Cmdlet configures an additional cluster for protection.
It installs vibs to all hosts in the cluster and creates storage policies.
 
    .PARAMETER MSIp
 
    Ip of the MSA
 
    .PARAMETER Credential
 
    root credentials of MSA
 
    .PARAMETER ProtectedCluster
 
    Cluster to be protected
 
    .PARAMETER RegisterWithIp
    Register MSA with Ip instead of hostname
 
.EXAMPLE
 
Enable-JetDRForCluster -MSIp xxx.xxx.xxx.xxx -Credential <root/PSCredential Object> -ProtectedCluster Src-Cluster -RegisterWithIp:$true
#>

function Enable-JetDRForCluster {
    [CmdletBinding()]
    [AVSAttribute(20, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credentials of root user of the MSA to be deployed")]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential,
        [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"
        $VCIp = $VC_ADDRESS
        $sso_user_name="vsphere.local\jetdrusr"
        $sso_user_pwd=generate_password
        $UserName = $Credential.UserName
        $Password = $Credential.GetNetworkCredential().Password
    }
    Process {
        # Preflight checks for cluster configure
        get_system_state_configure $ProtectedCluster

        # 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 $MSIp -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 $MSIp -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 $MSIp -MsUser $UserName -MsPassword $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
    }
}

<#
.NOTES
===========================================================================
Created by: JetStream Software Inc
===========================================================================
 
.DESCRIPTION
 
This Cmdlet unconfigures a cluster but doesn't uninstall JetDR completely so other clusters can still be used.
It uninstalls vibs from all hosts in the cluster and removes storage policies.
 
    .PARAMETER MSIp
 
    Ip of the MSA
 
    .PARAMETER Credential
 
    root credentials of MSA
 
    .PARAMETER ProtectedCluster
 
    Cluster to be unconfigured
 
    .PARAMETER RegisterWithIp
    Register MSA with Ip instead of hostname
 
.EXAMPLE
 
Disable-JetDRForCluster -MSIp xxx.xxx.xxx.xxx -Credential <root/PSCredential Object> -ProtectedCluster Src-Cluster -RegisterWithIp:$true
#>

function Disable-JetDRForCluster {
    [CmdletBinding()]
    [AVSAttribute(30, UpdatesSDDC = $True)]
    param(
        [Parameter(Mandatory=$true,
                    HelpMessage="Ip of the MSA")]
        [String]$MSIp,
        [Parameter(Mandatory=$true,
                    HelpMessage="Credential of the root user of MSA")]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential,
        [Parameter(Mandatory=$true,
                    HelpMessage="Cluster to be unconfigured")]
        [String]$ProtectedCluster,
        [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 = $Credential.UserName
        $Password = $Credential.GetNetworkCredential().Password
    }
    Process {
        # Preflight check for cluster unconfigure
        Invoke-PreflightJetDRUninstall -MSIp $MSIp -Credential $Credential -ProtectedCluster $ProtectedCluster

        # 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 $MSIp -VC $VCIp -Username $sso_user_name -Password $sso_user_pwd -Cluster $ProtectedCluster 

        # Unregister JetStream MSA from vCenter
        Unregister-MS -MS $MSIp -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 $MSIp -MsUser $UserName -MsPassword $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
    }
}