RiverMeadow.Source/RiverMeadow.Source.psm1
Import-Module -Name $PSScriptRoot\..\Util\Util function Add-RMSourceToCurrentProject { param( [Alias("sip")] [string] $SourceIP, [Alias("shpa")] [bool] $SourceHasPreinstalledAgent, [Alias("scoa")] [bool] $StoreCredsOnAppliance, [Alias("un")] [string] $Username, [Alias("p")] [string] $Password, [Alias("d")] [string] $Domain, [Alias("rmt")] [string[]] $RiverMeadowTags, [Alias("ai")] [string[]] $AdvancedInstructions, [Alias("cmg")] [bool] $CreateMoveGroup, [Alias("mgn")] [string] $MoveGroupName, [Alias("tmd")] [string] $TargetMigrationDate, [Alias("are")] [string] $AssignedResourceEmail, [Alias("css")] [string] $CloudSizeSetting ) $UserLoginStatus = Test-UserLoggedIn if (!$UserLoginStatus) { return } if (0 -eq $PSBoundParameters.Count) { Add-RMSourceInteractive } else { Add-RMSourceNonInteractive @PSBoundParameters } } function Add-RMSourceInteractive { $CurrentProjectId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $ReadValue = Read-Host "Enter the source IP address" if ("" -eq $ReadValue) { throw "Source IP address is required" } $SourceIP = $ReadValue $SourceHasPreinstalledAgent = $false $ReadValue = Read-Host "Does source has preinstalled agent (true/false)[false]" if ("" -ne $ReadValue) { $SourceHasPreinstalledAgent = [System.Convert]::ToBoolean($ReadValue) } if(!$SourceHasPreinstalledAgent){ $StoreCredsOnAppliance = $false $ReadValue = Read-Host "Store the source credentials on migration appliance (true/false)[false]" if ("" -ne $ReadValue) { $StoreCredsOnAppliance = [System.Convert]::ToBoolean($ReadValue) } } if (!$SourceHasPreinstalledAgent -and !$StoreCredsOnAppliance) { $ReadValue = Read-Host "Enter the username" if ("" -eq $ReadValue) { throw "Username is required." } $Username = $ReadValue $SecurePassword = Read-Host "Enter the password" -AsSecureString $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword) $Password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) if ("" -eq $Password) { throw "Password is required." } $ReadValue = Read-Host "Enter the domain" if ("" -ne $ReadValue) { $Domain = $ReadValue } } $ReadValue = Read-Host "Enter one or more RiverMeadow tags, separated by commas [None]" if ("" -ne $ReadValue) { $RiverMeadowTags = $ReadValue.Split(",").Trim() } else { $RiverMeadowTags = @() } $ReadValue = Read-Host "Enter one or more advanced instructions in the format 'key=value' and separated by commas [None]" $AdvancedInstructions = Get-RMStringAsHashtable -InputString $ReadValue $CreateMoveGroup = $false $ReadValue = Read-Host "Create new move group (true/false)[false]" if ("" -ne $ReadValue) { $CreateMoveGroup = [System.Convert]::ToBoolean($ReadValue) if ($CreateMoveGroup) { $ReadValue = Read-Host "Enter new move group name" if ("" -eq $ReadValue) { throw "New move group name is required." } $MoveGroupName = $ReadValue $ReadValue = Read-Host "Enter target migration date in the format 'mm/dd/yyyy' [None]" if("" -ne $ReadValue) { try { [datetime]::ParseExact($ReadValue, "MM/dd/yyyy", $null) $TargetMigrationDate = $ReadValue } catch { throw "Please enter a valid target migration date in the format 'mm/dd/yyyy'." } } $AssignedResourceEmail = Read-Host "Enter assigned resource email [None]" } } if (!$CreateMoveGroup) { $MoveGroupList = @() $Response = Get-RMMoveGroupList -Organization $CurrentProjectId -PageNumber 0 $MoveGroupList += $Response for ($index = 1; $index -lt $Response.page.totalPages; $index++) { $MoveGroupList += Get-RMMoveGroupList -OrganizationId $CurrentProjectId -PageNumber $index } $MoveGroups = $MoveGroupList.content.name -join ", " $ReadValue = Read-Host "Enter the move group name to which the source should be added ($MoveGroups)" if ("" -ne $ReadValue) { $MoveGroupName = $ReadValue } } $UserInput = @{ SourceIP = $SourceIP CurrentProjectId = $CurrentProjectId SourceHasPreinstalledAgent = $SourceHasPreinstalledAgent StoreCredsOnAppliance = $StoreCredsOnAppliance Username = $Username Password = $Password Domain = $Domain RiverMeadowTags = $RiverMeadowTags AdvancedInstructions = $AdvancedInstructions CreateMoveGroup = $CreateMoveGroup MoveGroupName = $MoveGroupName TargetMigrationDate = $TargetMigrationDate AssignedResourceEmail = $AssignedResourceEmail } New-RMSource @UserInput } function Add-RMSourceNonInteractive { param ( [string] $SourceIP, [bool] $SourceHasPreinstalledAgent, [bool] $StoreCredsOnAppliance, [string] $Username, [string] $Password, [string] $Domain, [string[]] $RiverMeadowTags, [string[]] $AdvancedInstructions, [bool] $CreateMoveGroup, [string] $MoveGroupName, [string] $TargetMigrationDate, [string] $AssignedResourceEmail, [string] $CloudSizeSetting ) $UserInput = @{} $CurrentProjectId = Get-Variable -Name "RMContext-CurrentProjectId" -ValueOnly $UserInput.Add("CurrentProjectId", $CurrentProjectId) if ("" -eq $SourceIP) { throw "Source IP address is required." } $UserInput.Add("SourceIP", $SourceIP) if ($SourceHasPreinstalledAgent) { $UserInput.Add("SourceHasPreinstalledAgent", $SourceHasPreinstalledAgent) } else { if ($StoreCredsOnAppliance) { $UserInput.Add("StoreCredsOnAppliance", $StoreCredsOnAppliance) } } if (!$SourceHasPreinstalledAgent -and !$StoreCredsOnAppliance) { if ("" -eq $Username) { throw "Username is required." } $UserInput.Add("Username", $Username) if ("" -eq $Password) { throw "Password is required." } $UserInput.Add("Password", $Password) $UserInput.Add("Domain", $Domain) } if ($null -eq $RiverMeadowTags) { $RiverMeadowTags = @() } $UserInput.Add("RiverMeadowTags", $RiverMeadowTags) $AdvancedInstructionsAsHashTable = Get-RMStringArrayAsHashtable -InputItems $AdvancedInstructions $UserInput.Add("AdvancedInstructions", $AdvancedInstructionsAsHashTable) if ($CreateMoveGroup) { $UserInput.Add("CreateMoveGroup", $CreateMoveGroup) if ("" -eq $MoveGroupName) { throw "New move group name is required." } $UserInput.Add("MoveGroupName", $MoveGroupName) if("" -ne $TargetMigrationDate) { try { [datetime]::ParseExact($TargetMigrationDate, "MM/dd/yyyy", $null) |Out-Null } catch { throw "Please enter a valid target migration date in the format 'mm/dd/yyyy'." } } $UserInput.Add("TargetMigrationDate", $TargetMigrationDate) $UserInput.Add("AssignedResourceEmail", $AssignedResourceEmail) } else { $UserInput.Add("MoveGroupName", $MoveGroupName) } New-RMSource @UserInput } function New-RMSource { param( [string] $SourceIP, [string] $CurrentProjectId, [bool] $SourceHasPreinstalledAgent, [bool] $StoreCredsOnAppliance, [string] $Username, [string] $Password, [string] $Domain, [string[]] $RiverMeadowTags, [hashtable] $AdvancedInstructions, [bool] $CreateMoveGroup, [string] $MoveGroupName, [string] $TargetMigrationDate, [string] $AssignedResourceEmail, [string] $CloudSizeSetting ) $CredsStorage = "local" if ($StoreCredsOnAppliance) { $CredsStorage = "ca" } $MoveGroupID = $null if ($CreateMoveGroup) { $MoveGroupID = "00000000-0000-0000-0000-000000000000" } else { if ("" -ne $MoveGroupName) { $MoveGroup = Get-MoveGroupByName -MoveGroupName $MoveGroupName -OrganizationId $CurrentProjectId if ($null -eq $MoveGroup) { throw "Invalid move group." } $MoveGroupID = $MoveGroup.id } } $ControlConnectionType = $null if ($SourceHasPreinstalledAgent) { $ControlConnectionType = "agent" } $SourceRequest = @{ "name"= $SourceIP "host"= $SourceIP #e.g string format:"Azure:Standard_D5_v2" #TODO We will add cloud size features in the future "cloud_sizing"= "" "instructions"= $AdvancedInstructions "credentials"= @{ "storage" = $CredsStorage "username" = $Username "password" = $Password "domain" = $Domain } "move_group_id" = $MoveGroupID "move_group_name" = $MoveGroupName "target_migration_date" = $TargetMigrationDate "assigned_resource_email" = $AssignedResourceEmail "tags"= $RiverMeadowTags "organization_id" = $CurrentProjectId "control_connection_type" = $ControlConnectionType } $SourceRequestJson = $SourceRequest |ConvertTo-Json -Depth 100 $Uri = Get-Variable -Name "RMContext-ReactorURI" -ValueOnly $RMLoginResult = Get-Variable -Name "RMContext-UserLogin" -ValueOnly $Headers = @{ Accept = "application/rm+json" "X-Auth-Token" = $RMLoginResult.token } $Params = @{ Method = "Post" Uri = $Uri + "/sources" Body = $SourceRequestJson ContentType = "application/json" Headers = $Headers } $Response = Invoke-RMRestMethod -Params $Params return $Response.id } Export-ModuleMember -Function Add-RMSourceToCurrentProject |