501 lines
20 KiB
PowerShell
501 lines
20 KiB
PowerShell
Function Get-Confirmation {
|
|
$choice = ""
|
|
while ($choice -notmatch "[y|n]"){
|
|
$choice = read-host "Do you want to continue? (Y/N)"
|
|
}
|
|
if($choice -ne 'y') {
|
|
break
|
|
}
|
|
}
|
|
|
|
Function Connect-HostedServer {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Server,
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Username,
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Password,
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Protocol = "http",
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][int]$Port = 8697
|
|
)
|
|
$pair = $Username+":"+$Password
|
|
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
|
|
$base64 = [System.Convert]::ToBase64String($bytes)
|
|
$basicAuthValue = "Basic $base64"
|
|
$headers = @{Authorization = $basicAuthValue}
|
|
|
|
$Global:DefaultHostedServer = [pscustomobject] @{
|
|
Server=$Protocol + "://" + $server + ":$Port/api";
|
|
Protcol=$Protocol
|
|
Headers=$headers
|
|
}
|
|
|
|
if($DefaultHostedServer.Protcol -eq "https") {
|
|
# PowerShell Core has a nice -SkipCertificateCheck but looks like Windows does NOT :(
|
|
if($PSVersionTable.PSEdition -eq "Core") {
|
|
$Global:fusionCommand = "Invoke-Webrequest -SkipCertificateCheck "
|
|
} else {
|
|
# Needed for Windows PowerShell to handle HTTPS scenario
|
|
# https://stackoverflow.com/a/15627483
|
|
$Provider = New-Object Microsoft.CSharp.CSharpCodeProvider
|
|
$Compiler = $Provider.CreateCompiler()
|
|
$Params = New-Object System.CodeDom.Compiler.CompilerParameters
|
|
$Params.GenerateExecutable = $false
|
|
$Params.GenerateInMemory = $true
|
|
$Params.IncludeDebugInformation = $false
|
|
$Params.ReferencedAssemblies.Add("System.DLL") > $null
|
|
$TASource=@'
|
|
namespace Local.ToolkitExtensions.Net.CertificatePolicy
|
|
{
|
|
public class TrustAll : System.Net.ICertificatePolicy
|
|
{
|
|
public bool CheckValidationResult(System.Net.ServicePoint sp,System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Net.WebRequest req, int problem)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
'@
|
|
$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
|
|
$TAAssembly=$TAResults.CompiledAssembly
|
|
## We create an instance of TrustAll and attach it to the ServicePointManager
|
|
$TrustAll = $TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
|
|
[System.Net.ServicePointManager]::CertificatePolicy = $TrustAll
|
|
$Global:fusionCommand = "Invoke-Webrequest "
|
|
}
|
|
} else {
|
|
$Global:fusionCommand = "Invoke-Webrequest "
|
|
}
|
|
$Global:DefaultHostedServer
|
|
}
|
|
|
|
Function Disconnect-HostedServer {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Server
|
|
)
|
|
|
|
$Global:DefaultHostedServer = $null
|
|
}
|
|
|
|
Function Get-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
if($Id) {
|
|
$vmUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id
|
|
try {
|
|
$params = "-Headers `$Global:DefaultHostedServer.Headers -Uri $vmUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
|
|
$vmIPUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/ip"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmIPUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmIPResults = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
$vmIP = $vmIPResults.ip
|
|
} catch {
|
|
$vmIP = "N/A"
|
|
}
|
|
|
|
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
$vmPower = "N/A"
|
|
}
|
|
|
|
$results = [pscustomobject] @{
|
|
Id = $vm.Id;
|
|
CPU = $vm.Cpu.processors;
|
|
Memory = $vm.Memory;
|
|
PowerState = $vmPower.power_state;
|
|
IPAddress = $vmIP;
|
|
}
|
|
$results
|
|
} else {
|
|
$uri = $Global:DefaultHostedServer.Server + "/vms"
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $uri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
try {
|
|
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Failed to list VMs"
|
|
}
|
|
}
|
|
}
|
|
|
|
Function Start-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
|
|
if($vmPower.power_state -eq "poweredOff" -or $vmPower.power_state -eq "suspended") {
|
|
try {
|
|
Write-Host "Powering on VM $Id ..."
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"on`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Unable to Power On VM $Id"
|
|
break
|
|
}
|
|
} else {
|
|
Write-Host "VM $Id is already Powered On"
|
|
}
|
|
}
|
|
|
|
Function Stop-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Soft,
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm = $true
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
if($Confirm) {
|
|
Get-Confirmation
|
|
}
|
|
|
|
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
|
try {
|
|
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
|
|
if($vmPower.power_state -eq "poweredOn") {
|
|
if($Soft) {
|
|
try {
|
|
Write-Host "Shutting down VM $Id ..."
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"shutdown`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Unable to Shutdown VM $Id"
|
|
break
|
|
}
|
|
} else {
|
|
try {
|
|
Write-Host "Powering off VM $Id ..."
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"off`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Unable to Power Off VM $Id"
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host "VM $Id is already Powered Off"
|
|
}
|
|
}
|
|
|
|
Function Suspend-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
if($Confirm) {
|
|
Get-Confirmation
|
|
}
|
|
|
|
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
|
|
if($vmPower.power_state -eq "poweredOn") {
|
|
try {
|
|
Write-Host "Suspending VM $Id ..."
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method PUT -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `"suspend`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vm = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Unable to suspend VM $Id"
|
|
break
|
|
}
|
|
} else {
|
|
Write-Host "VM $Id can not be suspended because it is either Powered Off or Suspended"
|
|
}
|
|
}
|
|
|
|
Function Resume-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$vmPowerUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/power"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmPowerUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmPower = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
|
|
if($vmPower.power_state -eq "suspended") {
|
|
try {
|
|
Start-HostedVM -Id $Id
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Unable to Resume VM $Id"
|
|
break
|
|
}
|
|
} else {
|
|
Write-Host "VM $Id is not Suspended"
|
|
}
|
|
}
|
|
|
|
Function New-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$ParentId,
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Name
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$vm = Get-HostedVM -Id $ParentId
|
|
|
|
if($vm -match "Invalid VM Id") {
|
|
Write-host -ForegroundColor Red "Unable to find existing VM Id $ParentId"
|
|
break
|
|
}
|
|
|
|
$vmUri = $Global:DefaultHostedServer.Server + "/vms"
|
|
$body = @{"ParentId"="$ParentId";"Name"=$Name}
|
|
$body = $body | ConvertTo-Json
|
|
|
|
try {
|
|
Write-Host "Cloning VM $ParentId to $Name ..."
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmUri -Method POST -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `$body"
|
|
$command = $Global:fusionCommand + $params
|
|
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Failed to Clone VM Id $ParentId"
|
|
break
|
|
}
|
|
}
|
|
|
|
Function Remove-HostedVM {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm = $true
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$vm = Get-HostedVM -Id $Id
|
|
|
|
if($vm -match "Invalid VM Id") {
|
|
Write-host -ForegroundColor Red "Unable to find existing VM Id $Id"
|
|
break
|
|
}
|
|
|
|
if($Confirm) {
|
|
Get-Confirmation
|
|
}
|
|
|
|
$vmUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id
|
|
try {
|
|
Write-Host "Deleting VM Id $Id ..."
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmUri -Method DELETE -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Failed to Delete VM Id $Id"
|
|
break
|
|
}
|
|
}
|
|
|
|
Function Get-HostedVMSharedFolder {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$folderUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/sharedfolders"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $folderUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
}
|
|
|
|
Function New-HostedVMSharedFolder {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$FolderName,
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$HostPath
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$body = @{"folder_id"="$FolderName";"host_path"=$HostPath;"flags"=4}
|
|
$body = $body | ConvertTo-Json
|
|
|
|
$folderUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/sharedfolders"
|
|
try {
|
|
Write-Host "Creating new Shared Folder $FolderName to $HostPath for VM Id $Id ..."
|
|
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $folderUri -Method POST -ContentType `"application/vnd.vmware.vmw.rest-v1+json`" -Body `$body"
|
|
$command = $Global:fusionCommand + $params
|
|
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Failed to create Shared Folder for VM Id $Id"
|
|
break
|
|
}
|
|
}
|
|
|
|
Function Remove-HostedVMSharedFolder {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id,
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$FolderName,
|
|
[parameter(Mandatory=$false,ValueFromPipeline=$true)][boolean]$Confirm = $true
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
if($Confirm) {
|
|
Get-Confirmation
|
|
}
|
|
|
|
$folderUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/sharedfolders/" + $FolderName
|
|
try {
|
|
Write-Host "Removing Shared Folder $FolderName for VM Id $Id ..."
|
|
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $folderUri -Method DELETE -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Failed to remove Shared Folder for VM Id $Id"
|
|
break
|
|
}
|
|
}
|
|
|
|
Function Get-HostedVMNic {
|
|
Param (
|
|
[parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id
|
|
)
|
|
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$vmNicUri = $Global:DefaultHostedServer.Server + "/vms/" + $Id + "/nic"
|
|
try {
|
|
$params += "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $vmNicUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$vmNics = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Invalid VM Id $Id"
|
|
break
|
|
}
|
|
|
|
$results = @()
|
|
foreach ($vmNic in $vmNics.nics) {
|
|
$tmp = [pscustomobject] @{
|
|
Index = $vmNic.index;
|
|
Type = $vmNic.Type;
|
|
VMnet = $vmNic.Vmnet;
|
|
}
|
|
$results+=$tmp
|
|
}
|
|
$results
|
|
}
|
|
|
|
Function Get-HostedNetworks {
|
|
if(!$Global:DefaultHostedServer) {
|
|
Write-Host -ForegroundColor Red "You are not connected to Hosted Server, please run Connect-HostedServer"
|
|
exit
|
|
}
|
|
|
|
$networksUri = $Global:DefaultHostedServer.Server + "/vmnet"
|
|
try {
|
|
$params = "-UseBasicParsing -Headers `$Global:DefaultHostedServer.Headers -Uri $networksUri -Method GET -ContentType `"application/vnd.vmware.vmw.rest-v1+json`""
|
|
$command = $Global:fusionCommand + $params
|
|
$networks = Invoke-Expression -Command $command | ConvertFrom-Json -ErrorAction Stop
|
|
} catch {
|
|
Write-host -ForegroundColor Red "Unable to retrieve Networks"
|
|
break
|
|
}
|
|
|
|
$results = @()
|
|
foreach ($network in $networks.vmnets) {
|
|
$tmp = [pscustomobject] @{
|
|
Name = $network.Name;
|
|
Type = $network.Type;
|
|
DHCP = $network.Dhcp;
|
|
Network = $network.subnet;
|
|
Netmask = $network.mask;
|
|
}
|
|
$results+=$tmp
|
|
}
|
|
$results
|
|
} |