neverfail.psm1
<#
.SYNOPSIS General purpose functions for the Neverfail API. .DESCRIPTION This module is for functions that are used in a multitude of scripts in the VEC viewpoint.local environment. .NOTES Version: 0.0.2 Author: Michael G. Brown Update: 02/14/2019 Purpose/Change: Reference: http://petstore.swagger.io/#/ | https://viewpoint.neverfail.com/api/v3/swagger.json #> #region-----modules and global variables--------------------------------------------------------------------# #-----------------------------------------------------------------------------------------------------------# Add-Type -AssemblyName System.Security Import-Module ActiveDirectory Import-Module PoshBot Import-Module 'C:\Repositories\PoshBot\plugins\PoshBot.Personality\PoshBot.Personality.psm1' Import-Module 'C:\Repositories\PoshBot\plugins\viewpoint.local\viewpoint.local.psm1' $CommandsToExport = @() #endregion #region-----functions---------------------------------------------------------------------------------------# #-----------------------------------------------------------------------------------------------------------# #region-----Neverfail Authentication---------------# #--------------------------------------------------# function Get-NfAPISession { [CmdletBinding()] param( #neverfail username [string]$nfU, #neverfail password [string]$nfP, #use the wstraining.neverfail.com site instead [switch]$test ) Add-Type -AssemblyName System.Web $EncodedUsername = [System.Web.HttpUtility]::UrlEncode($nfU) $EncodedPassword = [System.Web.HttpUtility]::UrlEncode($nfp) if ($test) { $server = "https://wstraining.neverfail.com" #testing environment } else { $server = "https://viewpoint.neverfail.com" } $version = "v3" $api = "$server/api/$version" $login_Uri = "$api/session/login?username=$EncodedUsername&password=$EncodedPassword" $token = Invoke-RestMethod -Uri $login_Uri -Method Post -ContentType "application/json" | Select-Object SessionId $authcode = "Session " + $token.sessionId $Headers = @{} $Headers.Add('Authorization', $authcode) $session = @{ api = $api headers = $Headers site = $server } Return $session } #endregion $CommandsToExport += 'Get-NfAPISession' #region-----Neverfail Domains----------------------# #--------------------------------------------------# function Get-NfDomains { [CmdletBinding()] param ( $session ) $api = $session.api $Domains_Uri = "$api/domains" $Domains = Invoke-RestMethod -Uri $Domains_Uri -Method Get -Headers $session.Headers -ContentType 'application/json' return $Domains } function Get-NfDomain { [CmdletBinding()] param ( $session, [string]$domainName, [string]$domainId ) if ($domainName) { $domains = Get-NfDomains -session $session foreach ($domain in $domains) { if ($domainName -eq $domain.domain) { $domainId = $domain.id } } } $api = $session.api $Domain_Uri = "$api/domains/$domainId" $Domain = Invoke-RestMethod -Uri $Domain_Uri -Method Get -Headers $session.Headers -ContentType 'application/json' return $Domain } #endregion #region-----Neverfail Clouds-----------------------# #--------------------------------------------------# function Get-NfClouds { [CmdletBinding()]param ( $session ) $api = $session.api $Clouds_Uri = "$api/clouds" $Clouds = Invoke-RestMethod -Uri $Clouds_Uri -Method Get -Headers $session.Headers -ContentType 'application/json' return $Clouds } function Get-NfCloud { [CmdletBinding()]param ( $session, [string]$cloudName, [String]$cloudId ) $api = $session.api if ($cloudName) { $clouds = Get-NfClouds -session $session foreach ($cloud in $clouds) { if ($cloudName -eq $cloud.name) { $cloudId = $cloud.id } } } $Cloud_Uri = "$api/clouds/$cloudId" $Cloud = Invoke-RestMethod -Uri $Cloud_Uri -Method Get -Headers $session.Headers -ContentType 'application/json' return $Cloud } function Get-NfCloudVirtualNetworks { [CmdletBinding()] param( $session, [String]$cloudName, [String]$cloudId ) if ($cloudName) { $cloudId = (Get-NfCloud -session $session -cloudName $cloudName).Id } $api = $session.api $CloudVNets_Uri = "$api/clouds/$cloudId/virtualNetworks" $CloudVnets = Invoke-RestMethod -Uri $CloudVNets_Uri -Method Get -Headers $session.Headers -ContentType 'application/json' return $CloudVnets } #endregion #region-----Neverfail Cloudstorage-----------------# #--------------------------------------------------# function Get-NfCloudstorages { [CmdletBinding()]param ($session, $cloudId) $api = $session.api $CloudStorages_Uri = "$api/clouds/$cloudId/storage" $CloudStorages = Invoke-RestMethod -Uri $CloudStorages_Uri -Method Get -Headers $session.Headers -ContentType 'application/json' return $CloudStorages } function Get-NfMostAvailableStorage { [CmdletBinding()]param ($session, $cloudId) $cloudStorages = Get-NfCloudstorages -session $session -cloudId $cloudId $maxFreeSpace = ($cloudStorages |Measure-Object -Property freeSpace -Maximum).Maximum $mostFreeCloudStorage = $cloudStorages | Where-Object {$_.freeSpace -eq $maxFreeSpace} return $mostFreeCloudStorage } #endregion #region-----Neverfail Organizations----------------# #--------------------------------------------------# function Get-NfOrganizations { [cmdletbinding()] param($Session) $Organizations_Uri = $Session.api + "/organizations" $Organizations = Invoke-RestMethod -Uri $Organizations_Uri -Method Get -Headers $Session.headers -ContentType "application/json" return $Organizations } function Get-NfOrganization { [cmdletbinding()] param($Session, $orgName, $orgId) if ($orgName) { $organizations = Get-NfOrganizations -Session $Session foreach ($org in $organizations) { if ($orgName -like $org.Name) { return $org } } } elseif ($orgId) { $org_Uri = $Session.api + "/organizations/" + $orgId $org = Invoke-RestMethod -Uri $org_Uri -Method Get -Headers $Session.headers -ContentType "application/json" return $org } } function New-NfOrganization { <# .SYNOPSIS Creates a new organization via the Neverfail API. #> [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('newOrg'), Permissions = 'create' )] param ( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [parameter(mandatory)] [String]$name, [string]$domain = "viewpoint.local", [parameter(mandatory)] [String]$upnDomain, [string]$orgAdminP = 'Enterpr1se66', [int]$retryAttempts = 1, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test $domain = "training.local" } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site $newOrganization_Uri = "$api/organizations" $Headers = $session.headers $domainId = (Get-NfDomain -session $session -domainName $domain).id $newOrganization_Json = [PSCustomObject]@{ "name" = $name; "domainId" = $domainId; "upnDomain" = $upnDomain; "orgAdminPassword" = $orgAdminP; } $body = $newOrganization_Json | ConvertTo-Json $newOrganization = Invoke-RestMethod -Uri $newOrganization_Uri -Headers $Headers -Method Post -ContentType "application/json" -Body $Body $organizationWorkflow = Find-NfWorkflow -Session $session -wfName "Provision an Organization: $name" $wf = Watch-NFWorkflowStatus -session $session -wfId $organizationWorkflow.id -retryAttempts $retryAttempts if ($wf.Status -eq "complete") { $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $user = $aff.User $emoji = $aff.Emoji New-PoshBotTextResponse -Text ("$response, $user! The organization *" + $newOrganization.Name + "* has been created. $emoji") $org = Get-NfOrganization -Session $session -orgName $newOrganization.Name $fields = [ordered]@{ Status = '' Website = $org.upnDomain } if ($org.status -eq 'valid') { $fields.Status = ':heavy_check_mark:' } else { $fields.Status = ':question:' } $title = $org.name $link = "$site/#/organizations/" + $org.Id New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link } } $CommandsToExport += 'New-NfOrganization' function Remove-NfOrganization { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('removeOrg'), Permissions = 'delete' )] param ( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [string]$Name, [string]$orgId, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $orgId = (Get-NfOrganization -Session $session -orgName $Name).Id $api = $session.api $site = $session.site $removeOrganization_Uri = "$api/organizations/$orgId" $Headers = $session.headers $removedOrganizationWF = Invoke-RestMethod -Uri $removeOrganization_Uri -Headers $Headers -Method Delete -ContentType "application/json" $wf = Watch-NFWorkflowStatus -session $session -wfId $removedOrganizationWF if ($wf.Status -eq "complete") { $aff = Get-VectoriaResponse -Type Confirmation $response = $aff.Response $emoji = $aff.emoji $user = $aff.User New-PoshBotTextResponse -Text ("$response, $user! The organization *" + $Name + "* has been deleted. $emoji") $fields = [ordered]@{ Status = ':x:' } $title = "Delete Organization Workflow" #for some reason $wf.name woudln't work through Slack $wfId = $wf.Id $link = "$site/#/workflows/" + $wfId #where is the "%20" coming from??? New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link } } $CommandsToExport += 'Remove-NfOrganization' #endregion #region-----Neverfail Workspaces-------------------# #--------------------------------------------------# function Get-NfWorkspaces { [cmdletbinding()]param($Session, $cloudId) $workspaces_Uri = $Session.api + "/clouds/$cloudId/workspaces" $workspaces = Invoke-RestMethod -Uri $workspaces_Uri -Method Get -Headers $Session.headers -ContentType "application/json" return $workspaces } function Get-NfWorkspace { [cmdletbinding()] param($Session, $orgName, $orgId, $cloudId) if ($orgName) { $orgId = (Get-NfOrganization -Session $Session -orgName $orgName).Id } if ($orgId) { $workspaces = Get-NfWorkspaces -Session $Session -cloudId $cloudId foreach ($workspace in $workspaces) { if ($orgId -eq $workspace.orgId) { $orgWorkspace = $workspace } } return $orgWorkspace } } function New-NfWorkspace { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('newWS'), Permissions = ('create') )] param ( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [ValidateSet("Las Vegas", "Vegas", "Austin", "Sydney", "Ashburn", "Training")] [parameter(mandatory)] [String]$cloud, [parameter(mandatory)] [String]$orgName, #newVmSpecs [ValidateLength(5, 10)] [String]$shortOrgName, [Int]$cores = 2, [int]$ram = 6, [int]$retryAttempts = 1, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site #cloud id switch ($cloud) { "Las Vegas" { $cloud = 'Las Vegas' $cloudId = '4af64a4c-3310-40d3-b433-292708eca59c' $networkId = 'c55c2ef5-09eb-489b-bc22-a2d5efc52218' $templateId = 'eea063ca-5a25-4493-aa89-d14fcde8429b' } "Vegas" { $cloud = 'Las Vegas' $cloudId = '4af64a4c-3310-40d3-b433-292708eca59c' $networkId = 'c55c2ef5-09eb-489b-bc22-a2d5efc52218' $templateId = 'eea063ca-5a25-4493-aa89-d14fcde8429b' } "Austin" { $cloud = 'Austin' $cloudId = '396b53b6-739f-4c65-aaaa-85bf4b22fed4' $networkId = 'dfe18cbb-1220-49e9-812c-10f486ee7f99' $templateId = 'c908895c-70a3-4376-b772-a9b0589e5ca5' } "Sydney" { $cloud = 'Sydney' $cloudId = 'def0af1a-1ac6-4136-b89a-6d5dc19c53b0' $networkId = 'cc7a271d-4cbc-4d35-97c1-b0487c37f32d' $templateId = 'a1c603c3-1f13-49d9-81c8-07d6b7dd9313' } "Ashburn" { $cloudId = '78291dc5-d4fe-47af-ae5d-cb1e4d6dab24' $networkId $templateId = '808103d2-d970-4365-813c-36096f3ce76d' } "Training" { $cloudId = '9e902052-4658-4763-a57e-606e740f5dc0' $networkId = '4cb83a9a-b10e-4f2b-94ba-2663889e4d51' $templateId = '9f94136b-ea6e-4cd3-be1f-45480637e680' } } $orgId = (Get-NfOrganization -Session $session -orgName $orgName).id $templateType = 'persistent_host' $roles = @("windows") $newWorkspace_Uri = "$api/clouds/$cloudId/workspaces" $sessionHostName = "vs-$shortOrgName" + "01" $pshSpec = [PSCustomObject]@{ 'name' = $sessionHostName; 'disk' = 40; 'roles' = $roles; 'cores' = $cores; 'ram' = $ram; } $newWorkspace_Json = [PSCustomObject]@{ 'cloudId' = $cloudId; 'orgId' = $orgId; 'networkId' = $networkId; 'templateId' = $templateId; 'templateType' = $templateType; 'pshSpec' = $pshSpec; } $Body = $newWorkspace_Json | ConvertTo-Json $newWorkspace = Invoke-RestMethod -Uri $newWorkspace_Uri -Headers $session.Headers -Method Post -ContentType "application/json" -Body $Body #$newWorkspace = Get-NfWorkspace -Session $session -orgId $orgId -cloudId $cloudId $name = $newWorkspace.name $workspaceWorkflow = Find-NfWorkflow -Session $session -wfName "Create Workspace: $name" $wf = Watch-NFWorkflowStatus -session $session -wfId $workspaceWorkflow.Id -Timeout 1800 -retryInterval 30 -retryAttempts $retryAttempts if ($wf.Status -eq "complete") { $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $emoji = $aff.Emoji $user = $aff.User New-PoshBotTextResponse -Text ("$response, $user! The workspace *" + $newWorkspace.Name + "* has been created. $emoji") $ws = Get-NfWorkspace -Session $session -orgId $orgId -cloudId $cloudId $fields = [ordered]@{ Status = '' Cloud = $cloud 'Distinguished Name' = $ws.wsDn } if ($ws.status -eq 'valid') { $fields.Status = ':heavy_check_mark:' } else { $fields.Status = ':question:' } $title = $ws.name $link = "$site/#/workspaces/" + $ws.Id New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link $psh = Get-NfVirtualMachine -Session $session -vmName $sessionHostName -cloudId $cloudId if (!$test) { $ip = (Get-ADComputer -Identity $sessionHostName -Properties IPv4Address).IPv4Address } else { $ip = $psh.profile.ipAddress } $fields = [ordered]@{ Status = '' IP = $ip } if ($psh.profile.status -eq 'normal') { $fields.Status = ':heavy_check_mark:' } else { $fields.Status = ':question:' } $title = $psh.profile.hostname $link = "$site/#/virtual-machines/" + $psh.Id New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link if (!$test) { Set-VecComputerDescription -computerName $sessionHostName } } } $CommandsToExport += 'New-NfWorkspace' function Remove-NfWorkspace { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('removeWS'), Permissions = ('delete') )] param( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [ValidateSet("Las Vegas", "Vegas", "Austin", "Sydney", "Ashburn", "Training")] [parameter(mandatory)] [String]$cloud, [parameter(mandatory)] [String]$orgName, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site switch ($cloud) { "Las Vegas" { $cloud = 'Las Vegas' $cloudId = '4af64a4c-3310-40d3-b433-292708eca59c' } "Vegas" { $cloud = 'Las Vegas' $cloudId = '4af64a4c-3310-40d3-b433-292708eca59c' } "Austin" { $cloud = 'Austin' $cloudId = '396b53b6-739f-4c65-aaaa-85bf4b22fed4' } "Sydney" { $cloud = 'Sydney' $cloudId = 'def0af1a-1ac6-4136-b89a-6d5dc19c53b0' } "Ashburn" { $cloud = 'Ashburn' $cloudId = '78291dc5-d4fe-47af-ae5d-cb1e4d6dab24' } "Training" { $cloud = 'Training' $cloudId = '9e902052-4658-4763-a57e-606e740f5dc0' } } $workspace = Get-NfWorkspace -Session $session -orgName $orgName -cloudId $cloudId $wsId = $workspace.Id $workspaceName = $workspace.Name $removeWorkspace_Uri = "$api/clouds/$cloudId/workspaces/$wsId" $removedWorkspaceWF = Invoke-RestMethod -Uri $removeWorkspace_Uri -Headers $session.Headers -Method Delete -ContentType "application/json" $wf = Watch-NFWorkflowStatus -session $session -wfId $removedWorkspaceWF if ($wf.Status -eq "complete") { $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $emoji = $aff.emoji $user = $aff.User New-PoshBotTextResponse -Text ("$response, $user! The workspace *" + $workspaceName + "* has been deleted. $emoji") $fields = [ordered]@{ Status = ':x:' } $title = $wf.name $link = "$site/#/workflows/" + $wf.Id New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link } } $CommandsToExport += 'Remove-NfWorkspace' #endregion #region-----Neverfail Virtual Machines-------------# #--------------------------------------------------# function Get-NfVirtualMachines { [cmdletbinding()]param($Session, $cloudId) if ($cloudId) { $virtualMachines_Uri = $Session.api + "/clouds/$cloudId/vms" $virtualMachines = Invoke-RestMethod -Uri $virtualMachines_Uri -Method Get -Headers $Session.headers -ContentType "application/json" return $virtualMachines } else { $clouds = Get-NfClouds -session $Session $virtualMachines = @() foreach ($cloud in $clouds) { $cloudId = $cloud.Id $virtualMachines_Uri = $Session.api + "/clouds/$cloudId/vms" $cloudVMs = Invoke-RestMethod -uri $virtualMachines_Uri -Method Get -Headers $Session.headers -ContentType 'application/json' $virtualMachines += $cloudVMs } return $virtualMachines } } function Get-NfVirtualMachine { [cmdletbinding()] param($Session, $vmName, $vmId, $cloudId) if ($cloudId) { $virtualMachines = Get-NfVirtualMachines -Session $Session -cloudId $cloudId } else { $virtualMachines = Get-NfVirtualMachines -Session $Session } foreach ($vm in $virtualMachines) { if (($vmId -eq $vm.Id) -or ($vmName -eq ($vm.profile.hostname -split "\.")[0])) { $virtualMachine = $vm } } return $virtualMachine } function Get-NfVirtualMachineDrives { [cmdletbinding()] param($Session, $vmName) $vm = Get-NfVirtualMachine -Session $Session -vmName $vmName $vmId = $vm.Id $api = $session.api $cId = $vm.profile.cloudId $vmDrives_Uri = "$api/clouds/$cId/vms/$vmId/drives/tiles" $vmDrives = Invoke-RestMethod -Uri $vmDrives_Uri -Headers $Session.headers -Method Get -ContentType "application/json" return $vmDrives } function New-NfVirtualMachine { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('newVM'), Permissions = ('create') )] param ( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [ValidateSet("Las Vegas", "Vegas", "Austin", "Sydney", "Ashburn", "Training")] [parameter(mandatory)] [String]$cloud, [parameter(mandatory)] [String]$orgName, #session host information [parameter(Mandatory)] [ValidateSet("Vista", "Web", "Field Time")] [String]$serverType, [ValidateLength(5, 15)] [String]$vmName, [ValidateRange(40, 100)] [Int]$disksize = 40, [ValidateRange(2, 16)] [Int]$cores = 2, [ValidateRange(4, 64)] [Int]$ram = 6, [int]$retryAttempts, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site $roles = @("windows") #cloud id switch ($cloud) { "Las Vegas" { $cloudId = '4af64a4c-3310-40d3-b433-292708eca59c' } "Vegas" { $cloudId = '4af64a4c-3310-40d3-b433-292708eca59c' } "Austin" { $cloudId = '396b53b6-739f-4c65-aaaa-85bf4b22fed4' } "Sydney" { $cloudId = 'def0af1a-1ac6-4136-b89a-6d5dc19c53b0' } "Ashburn" { $cloudId = '78291dc5-d4fe-47af-ae5d-cb1e4d6dab24' } "Training" { $cloudId = '9e902052-4658-4763-a57e-606e740f5dc0' } } $Orgworkspace = Get-NfWorkspace -Session $session -orgName $orgName -cloudId $cloudId $workspaceId = $Orgworkspace.Id $newVirtualMachine_Uri = "$api/clouds/$cloudId/vms?wsId=$workspaceId" if (!$vmName) { $vms = Get-NfVirtualMachines -Session $session -cloudId $cloudId $workspaceVMs = @() foreach ($vm in $vms) { if ($vm.profile.wsId -eq $workspaceId) { $workspaceVMs += $vm } } foreach ($vm in $workspaceVMs) { if ($vm.profile.hostname -like "VS-*") { $sessionHost = $vm } } $vmNameBase = ((($sessionHost.profile.hostname -replace "VS-", "") -replace "01", "") -split "\.")[0] switch ($serverType) { "Vista" { $vmName = $vmNameBase + "-v" $cores = 2 $ram = 6 } "Web" { $vmName = $vmNameBase + "-w" } "Field Time" { $vmName = $vmNameBase + "-ft" } } } $newVirtualMachine_json = [PSCustomObject]@{ 'name' = $vmName 'disk' = $disksize 'ip' = '' 'roles' = $roles 'templateId' = '' 'networkId' = '' 'cloudStorageId' = '' 'cores' = $cores 'ram' = $ram } $Body = ConvertTo-Json $newVirtualMachine_json #$newVirtualMachine = Invoke-RestMethod -Uri $newVirtualMachine_Uri -Method Post -Headers $session.Headers -ContentType "application/json" -Body $Body $newVirtualMachine = Get-NfVirtualMachine -Session $session -vmName $vmName -cloudId $cloudId $newHostName = (($newVirtualMachine.profile.hostname) -replace ".viewpoint.local*", "") $newVmWorkflow = Find-NfWorkflow -Session $session -wfName "Create New Host: $newHostName" $wf = Watch-NFWorkflowStatus -session $session -wfId $newVmWorkflow.id -retryAttempts $retryAttempts if ($wf.status -eq "complete") { if (!$test) { Set-VecComputerDescription -computerName $vmName #Set-VecComputerFirewall -computerName $vmName } $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $user = $aff.User $vm = Get-NfVirtualMachine -Session $session -vmName $vmName -cloudId $cloudId New-PoshBotTextResponse -Text ("$response, $user! The virtual machine *" + $vm.profile.hostname + "* has been created. :woman-raising-hand: ") $fields = [ordered]@{ Status = '' Cloud = $cloud IP = '' } if (!$test) { $ip = ((Get-ADComputer -Identity $vmName -Properties IPv4Address).IPv4Address) $field.IP = $ip } else { $fields.IP = "n/a" } if ($vm.profile.status -eq 'normal') { $fields.Status = ':heavy_check_mark:' } else { $fields.Status = ':question:' } $title = $vm.profile.hostname $link = "$site/#/virtual-machines/" + $vm.Id New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link if ($serverType -eq "Vista") { Add-NfVirtualMachineDrive -neverfail $neverfail -vmName $vmName -size 150 -label 'E' } } } $CommandsToExport += 'New-NfVirtualMachine' function Remove-NfVirtualMachine { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('removeVM'), Permissions = ('delete') )] param( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [parameter(mandatory)] [String]$vmName, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site $vm = Get-NfVirtualMachine -Session $session -vmName $vmName $vmId = $vm.Id $cloudId = $vm.profile.cloudId $removeVM_Uri = "$api/clouds/$cloudId/vms/$vmId" $removedVm = Invoke-RestMethod -Uri $removeVM_Uri -Headers $session.Headers -Method Delete -ContentType "application/json" $wf = Find-NfWorkflow -Session $session -wfName "Delete Guest" $wf = Watch-NFWorkflowStatus -session $session -wfId $wf.Id if ($wf.Status -eq "complete") { $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $emoji = $aff.emoji $user = $aff.User New-PoshBotTextResponse -Text ("$response, $user! The virtual machine *" + $vmName + "* has been deleted. $emoji") $fields = [ordered]@{ Status = ':x:' } $title = $wf.name $link = "$site/#/workflows/" + $wf.Id New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link } } $CommandsToExport += 'Remove-NfVirtualMachine' function Add-NfVirtualMachineDrive { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('newVMDrive'), Permissions = ('create') )] param ( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [string]$vmName, [parameter(Mandatory)] [int]$size, [parameter(Mandatory)] [string]$label, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site $vm = Get-NfVirtualMachine -Session $session -vmName $vmName $vmId = $vm.Id $cId = $vm.profile.cloudId $storage = Get-NfMostAvailableStorage -session $session -cloudId $cId $newVirtualMachineDrive_json = [PSCustomObject]@{ 'datastore' = $storage.Id; 'size' = $size; 'label' = $label; } $Body = ConvertTo-Json $newVirtualMachineDrive_json $newVirtualMachineDrive_Uri = "$api/clouds/$cId/vms/$vmId/drives" $newVMDrive = Invoke-RestMethod -Uri $newVirtualMachineDrive_Uri -Method Post -Headers $session.Headers -ContentType 'application/json' -Body $Body $wfId = (Find-NfWorkflow -Session $session -wfName 'Provision Storage').Id $wf = Watch-NFWorkflowStatus -session $session -wfId $wfId -retryAttempts 1 -retryInterval 5 if ($wf.status -eq "complete") { $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $emoji = $aff.emoji $user = $aff.User New-PoshBotTextResponse -Text ("$response, $user! A new drive has been created and attached to *" + $vm.profile.hostname + "*. $emoji") $capacity = $newVMDrive.Capacity / 1Gb $fields = [ordered]@{ Capacity = "$capacity GB" Label = $newVMDrive.label + ":" } if ($vm.profile.status -eq 'normal') { $fields.Status = ':heavy_check_mark:' } else { $fields.Status = ':question:' } $title = $vm.profile.hostname $link = "$site/#/virtual-machines/" + $vm.Id + "?cloudId=" + $cId New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link } } $CommandsToExport += 'Add-NfVirtualMachineDrive' function Remove-NfVirtualMachineDrive { [CmdletBinding()] [PoshBot.BotCommand( Aliases = ('removeVMDrive'), Permissions = ('delete') )] param ( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [string]$vmName, [parameter(Mandatory)] [string]$label, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $api = $session.api $site = $session.site $vm = Get-NfVirtualMachine -Session $session -vmName $vmName $vmId = $vm.Id $cId = $vm.profile.cloudId $drives = Get-NfVirtualMachineDrives -Session $session -vmName $vmName foreach ($drive in $drives) { if ($drive.label -eq $label) { $driveId = $drive.id } } $removeVirtualMachineDrive_Uri = "$api/clouds/$cId/vms/$vmId/drives/$driveId" $wfId = Invoke-RestMethod -Uri $removeVirtualMachineDrive_Uri -Method Delete -Headers $session.Headers -ContentType 'application/json' $wf = Watch-NFWorkflowStatus -session $session -wfId $wfId -retryAttempts 1 -retryInterval 5 if ($wf.status -eq "complete") { $aff = Get-VectoriaResponse -type Confirmation $response = $aff.Response $emoji = $aff.emoji $user = $aff.User New-PoshBotTextResponse -Text ("$response, $user! The $label drive has been removed from *" + $vm.profile.hostname + "*. $emoji") $fields = [ordered]@{ Label = $label + ":" Status = ":x:" } $title = $vm.profile.hostname $link = "$site/#/virtual-machines/" + $vm.Id + "?cloudId=" + $cId New-PoshBotCardResponse -Type Normal -Title $title -Fields $fields -LinkUrl $link } } $CommandsToExport += 'Remove-NfVirtualMachineDrive' #endregion #region-----Neverfail Workflows--------------------# #--------------------------------------------------# function Get-NfWorkflow { [CmdletBinding()]param ($session, $wfId) $api = $session.api $workflow_Uri = "$api/workflows/$wfId" $workflow = Invoke-RestMethod -Uri $workflow_Uri -Headers $session.headers -method Get -ContentType "application/json" return $workflow } function Get-NfWorkflowTasks { [CmdletBinding()]param ($session, $wfId) $api = $session.api $workflowTasks_Uri = "$api/workflows/$wfId/tasks" $workflowTasks = Invoke-Restmethod -Uri $workflowTasks_Uri -Headers $session.Headers -method Get -ContentType "application/json" return $workflowTasks } function Get-NfWorkflowCurrentTask { [CmdletBinding()]param ($session, $wfId) $workflow = Get-NfWorkflow -session $session -wfId $wfId $workflowTasks = Get-NfWorkflowTasks -session $session -wfId $wfId $currentTask = $workflowTasks | Where-Object {$_.ordinal -eq ($workflow.loadedTasks - 1)} return $currentTask } function Find-NfWorkflow { [cmdletbinding()] param($Session, $wfName) $api = $session.api $workflow_Uri = "$api/workflows" $workflow_json = [PSCustomObject]@{ 'name' = $wfName; } $Body = ConvertTo-Json $workflow_json $workflows = Invoke-RestMethod -Uri $workflow_Uri -Method Post -Headers $session.Headers -ContentType "application/json" -Body $Body $mostRecentWF = $workflows.entities[0] foreach ($wf in $workflows.entities) { if ($wf.startTime -ge $mostRecentWF.startTime) { $mostRecentWf = $wf } } return $mostRecentWF } function Find-NfWorkflows { [cmdletbinding()] param($Session) $api = $session.api $Workflows_Uri = "$api/workflows" $status = @('complete', 'error', 'stopped', 'stopping') <#$orderBy = @(@{ 'attr' = 'startTime' 'direction' = 'asc' })#> $workflows_json = [PSCustomObject]@{ 'status' = $status #'pageNumber' = 0 #'pageSize' = 100 #'orderBy' = $orderBy } $Body = ConvertTo-Json $workflows_json $Workflows = Invoke-RestMethod -Uri $Workflows_Uri -Method Post -Headers $session.Headers -ContentType "application/json" -Body $Body return $Workflows } function Remove-NfWorkflows { [cmdletbinding()] param( $Session, [string[]]$workflowIds ) $api = $session.api $deleteWorkflows_Uri = "$api/workflows/delete" $Body = ConvertTo-Json $workflowIds $deleteWorkflows = Invoke-RestMethod -Uri $deleteWorkflows_Uri -Method Post -Headers $session.Headers -ContentType "application/json" -Body $Body return $deleteWorkflows } function Optimize-NfWorkflows { [cmdletbinding()] param( [PoshBot.FromConfig('Credential')] [parameter(mandatory)] $neverfail, [switch]$test ) if ($test) { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password -test } else { $session = Get-NfAPISession -nfU $neverfail.Username -nfP $neverfail.GetNetworkCredential().password } $wfs = Find-NfWorkflows -session $session $wfsToDelete = @() foreach ($WF in $wfs.entities) { $start = $WF.startTime / 1000 $epoch = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0 $start = $epoch.AddSeconds($start) #delete workflow if Older than 10 days $days = 10 if ($start -lt (get-date).AddDays(-$days) -or (($wf.status -eq 'error') -and (!$wf.resumedFromWorkflow))) { $wfsToDelete += $wf.id } } $removedWorkflows = Remove-NfWorkflows -Session $session -workflowIds $wfsToDelete if(!$removedWorkflows){ New-PoshBotTextResponse -Text "No workflows removed. Already optimized." }else{ $removedWorkflows = $removedWorkflows |Format-List |Out-String New-PoshBotTextResponse -Text "Neverfail Workflows older than $days days removed. $removedWorkFlows" } } $CommandsToExport += 'Optimize-NfWorkflows' function Restart-NfWorflow { [CmdletBinding()]param ($session, $wfId) $api = $session.api $restartWorkflow_Uri = "$api/workflows/$wfId/restart" $restartedWorkflow = Invoke-RestMethod -Uri $restartWorkflow_Uri -Method Put -Headers $session.Headers -ContentType "application/json" return $restartedWorkflow } function Watch-NFWorkflowStatus { [CmdletBinding()]param ( $session, [String]$wfId, [Int]$Timeout = 1800, [Int]$retryInterval = 20, [Int]$retryAttempts = 1 ) $wf = Get-NfWorkflow -session $session -wfId $wfId $site = $session.site $workflowInProgress = $true $retriedCount = 0 $timer = [Diagnostics.Stopwatch]::StartNew() $i = 0 $halfway = $Timeout / 2 while ($workflowInProgress -and $timer.Elapsed.TotalSeconds -lt $Timeout) { $totalSeconds = [math]::Round($timer.Elapsed.TotalSeconds, 0) if ($i -eq 0) { Send-SlackMessage -Token 'xoxb-2614483880-541541209732-kL3fRhyaQtuXWethevFqP1Jv' -Channel $global:PoshBotContext.To -Text ("Workflow *" + $wf.name + "* in progress...") -AsUser } elseif ($i -eq $halfway) { Send-SlackMessage -Token 'xoxb-2614483880-541541209732-kL3fRhyaQtuXWethevFqP1Jv' -Channel $Global:PoshBotContext.To -Text "Just checking in. We're halfway until the Watch-WorkflowStatus timesout. Workflow *" + $wf.name + "* still in progress..." -AsUser } if ($wf.status -eq "complete") { $workflowInProgress = $false } elseif ($wf.status -eq "error") { if ($retriedCount -ge $retryAttempts) { $ref = Get-VectoriaResponse -type Refutation $response = $ref.Response $emoji = $ref.emoji $user = $ref.User $task = (Get-NfWorkflowCurrentTask -session $session -wfId $wf.Id).Name if ($retryAttempts -eq 1) { $restartText = "Something went wrong with the workflow on task: *$task*, even after 1 workflow restart" } elseif ($retryAttempts -ge 2) { $restartText = "Something went wrong with the workflow on task: *$task*, even after $retryAttempts workflow restarts" } elseif ($retryAttempts -eq 0) { $restartText = "Something went wrong with the workflow on task: *$task*" } New-PoshBotTextResponse -Text ("$response, $user. $restartText! $emoji") $title = $wf.Name $link = "$site/#/workflows/" + $wf.Id New-PoshBotCardResponse -Type Normal -Title $title -LinkUrl $link $workflowInProgress = $false } else { $restartedWorkflow = Restart-NfWorflow -session $session -wfId $wf.Id Send-SlackMessage -Token 'xoxb-2614483880-541541209732-kL3fRhyaQtuXWethevFqP1Jv' -Channel $global:PoshBotContext.To -Text ("Workflow *" + $wf.name + "* failed...Restarting...") -AsUser $wf = Get-NfWorkflow -session $session -wfId $restartedWorkflow.Id $retriedCount += 1 } } elseif ($wf.status -eq "stopped" -or $wf.status -eq "stopping") { $ref = Get-VectoriaResponse -type Refutation $response = $ref.Response $emoji = $ref.emoji $user = $ref.User $task = Get-NfWorkflowCurrentTask -session $session -wfId $wf.Id New-PoshBotTextResponse -Text ("$response, $user. Someone stopped the worflow on task: *$task*. $emoji") $title = $wf.Name $link = "$site/#/workflows/" + $wf.Id New-PoshBotCardResponse -Type Normal -Title $title -LinkUrl $link $workflowInProgress = $false } elseif ($wf.status -eq "running" -or $wf.status -eq "init" -or $wf.status -eq "resumed") { Start-Sleep -Seconds $retryInterval $wf = Get-NfWorkflow -session $session -wfId $wf.Id } else { $workflowInProgress = $false } $i += $retryInterval } $timer.Stop() if ($totalSeconds -gt $Timeout) { $def = Get-VectoriaResponse -type Deflection $response = $def.Response $emoji = $def.Emoji $user = $def.user New-PoshBotTextResponse -Text "$response, $user. The workflow is still going and my Watch-Workflow function timed out. $emoji" $title = $wf.Name $link = "$site/#/workflows/" + $wf.Id New-PoshBotCardResponse -Type Normal -Title $title -LinkUrl $link } return $wf } $CommandsToExport += 'Watch-NFWorkflowStatus' #endregion #endregion #Export-ModuleMember -Function $CommandsToExport #endregion #endregion |