From 8953a512fe58fd69f54e963364e49b3b89d5f602 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 20 Dec 2018 10:28:31 +0000 Subject: [PATCH 01/28] Create Get-Migrations.ps1 Quick function for listing the currently running and recently finished VM migrations --- Scripts/Get-Migrations.ps1 | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Scripts/Get-Migrations.ps1 diff --git a/Scripts/Get-Migrations.ps1 b/Scripts/Get-Migrations.ps1 new file mode 100644 index 0000000..8336de7 --- /dev/null +++ b/Scripts/Get-Migrations.ps1 @@ -0,0 +1,12 @@ +<# +Script name: get-migrations.ps1 +Created on: 20/12/2018 +Author: Chris Bradshaw @aldershotchris +Description: The purpose of the script is to list the currently running + recently finished VM migrations. +Dependencies: None known +#> +Function Get-Migrations{ + Get-Task | + Where-Object{$_.Name -eq "RelocateVM_Task"} | + Select-Object @{Name="VM";Expression={Get-VM -Id $_.ObjectID}}, State, @{Name="% Complete";Expression={$_.PercentComplete}},StartTime +} From ecc12a18847ae884c7ef41018d2bb3bfeeb7b9e6 Mon Sep 17 00:00:00 2001 From: Matt Frey Date: Wed, 13 Mar 2019 14:43:33 -0500 Subject: [PATCH 02/28] Address Issue #269 Both flash parameters for `New-HVPool` were limited to the validate set of `LINKED_CLONE`. This updates them to be valid for all desktop types, since it is applicable to all desktop types. See https://vdc-download.vmware.com/vmwb-repository/dcr-public/3721109b-48a5-4ffb-a0ad-6d6a44f2f288/ff45dfca-1050-4265-93ef-4e7d702322e4/vdi.resources.Desktop.AdobeFlashSettings.html for details. --- Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index c150c5f..14972ca 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -3667,13 +3667,19 @@ function New-HVPool { # flashSettings #desktopSpec.desktopSettings.flashSettings.quality [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] + [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'FULL_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'MANUAL')] [ValidateSet('NO_CONTROL', 'LOW', 'MEDIUM', 'HIGH')] - [string]$quality = 'NO_CONTROL', + [string]$Quality = 'NO_CONTROL', #desktopSpec.desktopSettings.flashSettings.throttling [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] + [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'FULL_CLONE')] + [Parameter(Mandatory = $false,ParameterSetName = 'MANUAL')] [ValidateSet('DISABLED', 'CONSERVATIVE', 'MODERATE', 'AGGRESSIVE')] - [string]$throttling = 'DISABLED', + [string]$Throttling = 'DISABLED', #mirageConfigurationOverrides #desktopSpec.desktopSettings.mirageConfigurationOverrides.overrideGlobalSetting @@ -11580,4 +11586,4 @@ Export-ModuleMember -Function Get-HVResourceStructure, Get-HVLocalSession, Get-H # Event Database related Export-ModuleMember -Function Get-HVEventDatabase, Set-HVEventDatabase, Clear-HVEventDatabase, Get-HVEvent, Connect-HVEvent, Disconnect-HVEvent # Misc/other related -Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance \ No newline at end of file +Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance From b8b48e40f806d7753c167e34375189d0dd3d69b7 Mon Sep 17 00:00:00 2001 From: William Lam Date: Thu, 14 Mar 2019 12:00:27 -0700 Subject: [PATCH 03/28] Add support for both Infra Group/Scopes related to CGW Edge Fireweall --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 2 +- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 195 ++++++++++++++++++- 2 files changed, 194 insertions(+), 3 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index b74bad7..45e549d 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo' +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index d120086..70e8ba1 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -403,6 +403,27 @@ Function Get-NSXTFirewall { } } + $scopeEntries = $rule.scope + $scopes = @() + foreach ($scopeEntry in $scopeEntries) { + $scopeLabelURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $scopeEntry + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$scopeLabelURL`n" + } + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $scopeLabelURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $scopeLabelURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + $scope = ($requests.Content | ConvertFrom-Json) + $scopes += $scope.display_name + } + $tmp = [pscustomobject] @{ SequenceNumber = $rule.sequence_number; Name = $rule.display_name; @@ -410,6 +431,7 @@ Function Get-NSXTFirewall { Source = $source; Destination = $destination; Services = $service; + Scope = $scopes; Action = $rule.action; } $results+=$tmp @@ -446,6 +468,9 @@ Function New-NSXTFirewall { [Parameter(Mandatory=$True)]$DestinationGroup, [Parameter(Mandatory=$True)]$Service, [Parameter(Mandatory=$True)][ValidateSet("ALLOW","DENY")]$Action, + [Parameter(Mandatory=$false)]$InfraScope, + [Parameter(Mandatory=$false)]$SourceInfraGroup, + [Parameter(Mandatory=$false)]$DestinationInfraGroup, [Parameter(Mandatory=$false)][Boolean]$Logged=$false, [Switch]$Troubleshoot ) @@ -464,6 +489,13 @@ Function New-NSXTFirewall { } } + if(! $DestinationInfraGroup) { + foreach ($group in $SourceInfraGroup) { + $tmp = (Get-NSXTInfraGroup -Name $group).Path + $destinationGroups+= $tmp + } + } + $sourceGroups = @() foreach ($group in $SourceGroup) { if($group -eq "ANY") { @@ -474,6 +506,13 @@ Function New-NSXTFirewall { } } + if(! $SourceInfraGroup) { + foreach ($group in $SourceInfraGroup) { + $tmp = (Get-NSXTInfraGroup -Name $group).Path + $sourceGroups+= $tmp + } + } + $services = @() foreach ($serviceName in $Service) { if($serviceName -eq "ANY") { @@ -484,6 +523,16 @@ Function New-NSXTFirewall { } } + $scopeLabels = @() + if(! $InfraScope ) { + $scopeLabels = @("/infra/labels/$($GatewayType.toLower())") + } else { + foreach ($infraScopeName in $InfraScope) { + $scope = Get-NSXTInfraScope -Name $infraScopeName + $scopeLabels += $scope.Path + } + } + $payload = @{ display_name = $Name; resource_type = "CommunicationEntry"; @@ -491,7 +540,7 @@ Function New-NSXTFirewall { destination_groups = $destinationGroups; source_groups = $sourceGroups; logged = $Logged; - scope = @("/infra/labels/$($GatewayType.toLower())"); + scope = $scopeLabels; services = $services; action = $Action; } @@ -1495,4 +1544,146 @@ If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection f ($requests.Content | ConvertFrom-Json) } } -} \ No newline at end of file +} + +Function Get-NSXTInfraScope { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 03/14/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Infrastructure Scopes + .DESCRIPTION + This cmdlet retrieves all NSX-T Infrastructure Scopes + .EXAMPLE + Get-NSXTInfraScope + .EXAMPLE + Get-NSXTInfraGroup -Name "VPN Tunnel Interface" + #> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $infraLabelURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/labels" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$infraLabelURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $infraLabelURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $infraLabelURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T Infrastructure Scopes" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $infraLables = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $infraLables = $infraLables | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($infraLabel in $infraLables) { + $tmp = [pscustomobject] @{ + Name = $infraLabel.display_name; + Id = $infraLabel.Id; + Path = $infraLabel.Path; + } + $results+=$tmp + } + $results + } + } +} + +Function Get-NSXTInfraGroup { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 03/14/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Infrastructure Groups for CGW + .DESCRIPTION + This cmdlet retrieves all NSX-T Infrastructure Groups for CGW + .EXAMPLE + Get-NSXTInfraGroup + .EXAMPLE + Get-NSXTInfraGroup -Name "S3 Prefixes" + #> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $infraGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/groups" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$infraGroupsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $infraGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $infraGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T Infrastructure Groups" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $groups = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $groups = $groups | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($group in $groups) { + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Path = $group.path; + } + $results+=$tmp + } + $results + } + } + } \ No newline at end of file From 360e190300465c476e5fe316deb5d5b9ea326414 Mon Sep 17 00:00:00 2001 From: Matt Frey Date: Thu, 14 Mar 2019 19:08:01 -0500 Subject: [PATCH 04/28] New HV Functions for vCenter and BaseImage --- .../VMware.Hv.Helper/VMware.HV.Helper.psm1 | 398 +++++++++++++++++- 1 file changed, 389 insertions(+), 9 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index c150c5f..17508d7 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -94,6 +94,159 @@ function Get-VcenterID { return $virtualCenterId } +function Get-HVvCenterServer { + <# + .Synopsis + Gets a list of all configured vCenter Servers + + .DESCRIPTION + Queries and returns the vCenter Servers configured for the pod of the specified HVServer. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered inplace of hvServer + + .PARAMETER Name + A string value to query a vCenter Server by Name, if it is known. + + .EXAMPLE + Get-HVvCenterServer + + .EXAMPLE + Get-HVvCenterServer -Name 'vCenter1' + + .OUTPUTS + Returns array of object type VMware.Hv.VirtualCenterInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $false)] + [string]$Name = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + } + + process { + + if ($null -ne $PSBoundParameters.Name) { + $vCenterList = $services.VirtualCenter.VirtualCenter_List() | Where-Object {$_.ServerSpec.ServerName -eq $Name} + } else { + $vCenterList = $services.VirtualCenter.VirtualCenter_List() + } + + } + + end { + + return $vCenterList + + } +} + +function Get-HVvCenterServerHealth { + <# + .Synopsis + Gets a the health info for a given vCenter Server. + + .DESCRIPTION + Queries and returns the VirtualCenterHealthInfo specified HVServer. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered inplace of hvServer + + .PARAMETER VirtualCenter + A parameter to specify which vCenter Server to check health for. If not specified, this function will return the + health info for all vCenter Servers. + + .EXAMPLE + Get-HVvCenterServerHealth -VirtualCenter 'vCenter1' + + .EXAMPLE + Get-HVvCenterServerHealth -VirtualCenter $vCenter1 + + .EXAMPLE + Get-HVvCenterServerHealth + + .OUTPUTS + Returns array of object type VMware.Hv.VirtualCenterInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $false)] + $VirtualCenter = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + } + + process { + + if ($null -eq $PSBoundParameters.VirtualCenter) { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_List() + } else { + $objType = $VirtualCenter.getType() | Select-Object -ExpandProperty Name + Switch ($objType) { + 'String' { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_Get($(Get-HVvCenterServer -Name $VirtualCenter | Select-Object -ExpandProperty Id)) + } + 'VirtualCenterInfo' { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_Get($($VirtualCenter | Select-Object -ExpandProperty Id)) + } + 'VirtualCenterId' { + $VirtualCenterHealth = $services.VirtualCenterHealth.VirtualCenterHealth_Get($VirtualCenter) + } + } + } + + } + + end { + + return $VirtualCenterHealth + + } +} + function Get-JsonObject { param( [Parameter(Mandatory = $true)] @@ -462,8 +615,6 @@ function Add-HVRDSServer { } } - - function Connect-HVEvent { <# .SYNOPSIS @@ -2790,7 +2941,6 @@ function Test-HVFarmSpec { } } - function Get-HVFarmProvisioningData { param( [Parameter(Mandatory = $false)] @@ -2865,7 +3015,6 @@ function Get-HVFarmProvisioningData { return $vmObject } - function Get-HVFarmStorageObject { param( @@ -2933,7 +3082,6 @@ function Get-HVFarmStorageObject { return $storageObject } - function Get-HVFarmNetworkSetting { param( [Parameter(Mandatory = $false)] @@ -2945,7 +3093,6 @@ function Get-HVFarmNetworkSetting { return $networkObject } - function Get-HVFarmCustomizationSetting { param( [Parameter(Mandatory = $false)] @@ -3078,7 +3225,6 @@ function Get-FarmSpec { return $farm_spec_helper.getDataObject() } - function New-HVPool { <# .Synopsis @@ -4922,7 +5068,6 @@ function Get-HVPoolProvisioningData { return $vmObject } - function Get-HVHostOrClusterID { <# .Synopsis @@ -6902,6 +7047,239 @@ function Get-Machine ($Pool,$MachineList) { return $machines } +function Get-HVBaseImageVM { + <# + .Synopsis + Gets a list of compatible base image virtual machines. + + .DESCRIPTION + Queries and returns BaseImageVmInfo for the specified vCenter Server. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered in place of hvServer. + + .PARAMETER VirtualCenter + A parameter to specify which vCenter Server to check base image VMs for. It can be specified as a String, + containing the name of the vCenter, or as a vCenter object as returned by Get-HVvCenterServer. If the value is + not passed or null then first element returned from Get-HVvCenterServer would be considered in place of VirtualCenter. + + .PARAMETER ImageType + A parameter to define the type of compatability to check the base image VM list against. Valid options are 'VDI', 'RDS', or 'ALL' + 'VDI' will return all desktop compatible Base Image VMs. + 'RDS' will return all RDSH compatible Base Image VMs. + 'ALL' will return all Base Image VMs, regardless of compatibility. + The default value is 'ALL'. + + .PARAMETER Name + The name of a virtual machine (if known), to filter Base Image VMs on. Wildcards are accepted. If Name is specified, then ImageType + is not considered for filtering. + + .EXAMPLE + Get-HVBaseImageVM -VirtualCenter 'vCenter1' -ImageType VDI + + .EXAMPLE + Get-HVBaseImageVM -VirtualCenter $vCenter1 -ImageType ALL + + .EXAMPLE + Get-HVBaseImageVM -Name '*WIN10*' + + .OUTPUTS + Returns array of object type VMware.Hv.BaseImageVmInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + [cmdletbinding( + DefaultParameterSetName='ImageType' + )] + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $false)] + $VirtualCenter = $null, + + [Parameter(Mandatory = $false,ParameterSetName = 'ImageType')] + [ValidateSet('VDI','RDS','ALL')] + $ImageType = 'VDI', + + [Parameter(Mandatory = $false,ParameterSetName = 'Name')] + [string]$Name = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + + if ($null -eq $PSBoundParameters.VirtualCenter) { + $VirtualCenterId = Get-HVvCenterServer | Select-Object -First 1 -ExpandProperty Id + } else { + $objType = $VirtualCenter.getType() | Select-Object -ExpandProperty Name + Switch ($objType) { + 'String' { + $VirtualCenterId = Get-HVvCenterServer -Name $VirtualCenter | Select-Object -ExpandProperty Id + } + 'VirtualCenterInfo' { + $VirtualCenterId = $VirtualCenter | Select-Object -ExpandProperty Id + } + 'VirtualCenterId' { + $VirtualCenterId = $VirtualCenter + } + } + } + + } + + process { + + $BaseImageVMList = $services.BaseImageVM.BaseImageVM_List($VirtualCenterId) + + #For all conditions, see https://vdc-download.vmware.com/vmwb-repository/dcr-public/3721109b-48a5-4ffb-a0ad-6d6a44f2f288/ff45dfca-1050-4265-93ef-4e7d702322e4/vdi.utils.virtualcenter.BaseImageVm.BaseImageVmIncompatibleReasons.html + + If ($null -ne $PSBoundParameters.Name) { + $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object {$_.Name -like $Name} + } Else { + Switch ($ImageType) { + + 'VDI' { + $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object { + ($_.IncompatibleReasons.InUseByDesktop -eq $false) -and + ($_.IncompatibleReasons.InUseByLinkedCloneDesktop -eq $false) -and + ($_.IncompatibleReasons.ViewComposerReplica -eq $false) -and + ($_.IncompatibleReasons.UnsupportedOS -eq $false) -and + ($_.IncompatibleReasons.NoSnapshots -eq $false) -and + (($null -eq $_.IncompatibleReasons.InstantInternal) -or ($_.IncompatibleReasons.InstantInternal -eq $false)) + } + } + 'RDS' { + $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object { + ($_.IncompatibleReasons.InUseByDesktop -eq $false) -and + ($_.IncompatibleReasons.InUseByLinkedCloneDesktop -eq $false) -and + ($_.IncompatibleReasons.ViewComposerReplica -eq $false) -and + ($_.IncompatibleReasons.UnsupportedOSForLinkedCloneFarm -eq $false) -and + ($_.IncompatibleReasons.NoSnapshots -eq $false) -and + (($null -eq $_.IncompatibleReasons.InstantInternal) -or ($_.IncompatibleReasons.InstantInternal -eq $false)) + } + } + 'ALL' { + $CompatibleBaseImageVMs = $BaseImageVMList + } + + } + } + + } + + end { + + return $CompatibleBaseImageVMs + + } +} + +function Get-HVBaseImageSnapshot { + <# + .Synopsis + Gets a list of compatible base image virtual machines. + + .DESCRIPTION + Queries and returns BaseImageVmInfo for the specified vCenter Server. + + .PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered in place of hvServer. + + .PARAMETER BaseImageVM + The BaseImageVM to query snapshots for. This parameter is required. Wildcards are accepted. This parameter also supports + pipeline operations with Get-HVBaseImageVM + + .EXAMPLE + Get-HVBaseImageSnapshots -BaseImageVM 'WIN10-BaseImage' + + .EXAMPLE + Get-HVBaseImageSnapshots -BaseImageVM '*WIN10*' + + .EXAMPLE + Get-HVBaseImageVM -Name 'WIN10-BaseImage' | Get-HVBaseImageSnapshots + + .OUTPUTS + Array of object type VMware.Hv.BaseImageSnapshotInfo + + .NOTES + Author : Matt Frey. + Author email : mfrey@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.7 + PowerCLI Version : PowerCLI 11.2.0 + PowerShell Version : 5.1 + #> + + [cmdletbinding( + DefaultParameterSetName='ImageType' + )] + + param( + [Parameter(Mandatory = $false)] + $HvServer = $null, + + [Parameter(Mandatory = $true,ValueFromPipeLine=$true)] + $BaseImageVM = $null + ) + + begin { + $services = Get-ViewAPIService -hvServer $hvServer + + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + + } + + process { + + if ($null -ne $PSBoundParameters.BaseImageVM) { + $objType = $BaseImageVM.getType() | Select-Object -ExpandProperty Name + Switch ($objType) { + 'String' { + $BaseImageVMObj = Get-HVBaseImageVM -Name $BaseImageVM + } + 'BaseImageVMInfo' { + $BaseImageVMObj = $BaseImageVM + } + 'Object[]' { + Write-Error 'This function cannot accept an array of Base Image VMs. You must specify only a single Base Image VM.' + Break + } + } + $BaseImageSnapshotList = $services.BaseImageSnapshot.BaseImageSnapshot_List($BaseImageVMObj.Id) + } + + } + + end { + + return $BaseImageSnapshotList + + } +} + function Set-HVPoolSpec { param( [Parameter(Mandatory = $true)] @@ -11579,5 +11957,7 @@ Export-ModuleMember -Function Get-HVGlobalSettings, Set-HVApplicationIcon, Remov Export-ModuleMember -Function Get-HVResourceStructure, Get-HVLocalSession, Get-HVGlobalSession # Event Database related Export-ModuleMember -Function Get-HVEventDatabase, Set-HVEventDatabase, Clear-HVEventDatabase, Get-HVEvent, Connect-HVEvent, Disconnect-HVEvent +# vCenter Server related +Export-ModuleMember -Function Get-HVvCenterServer, Get-HVvCenterServerHealth # Misc/other related -Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance \ No newline at end of file +Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance, Get-HVBaseImageVM, Get-HVBaseImageVMSnapshot \ No newline at end of file From 29fbb5bc59d447981b71b9e5a116fdf0bd8ae10c Mon Sep 17 00:00:00 2001 From: William Lam Date: Fri, 15 Mar 2019 05:13:37 -0700 Subject: [PATCH 05/28] Fixing optional for Source/Destination Groups + typo --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 70e8ba1..de52816 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -464,8 +464,8 @@ Function New-NSXTFirewall { [Parameter(Mandatory=$True)]$Name, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$True)]$SequenceNumber, - [Parameter(Mandatory=$True)]$SourceGroup, - [Parameter(Mandatory=$True)]$DestinationGroup, + [Parameter(Mandatory=$False)]$SourceGroup, + [Parameter(Mandatory=$False)]$DestinationGroup, [Parameter(Mandatory=$True)]$Service, [Parameter(Mandatory=$True)][ValidateSet("ALLOW","DENY")]$Action, [Parameter(Mandatory=$false)]$InfraScope, @@ -490,7 +490,7 @@ Function New-NSXTFirewall { } if(! $DestinationInfraGroup) { - foreach ($group in $SourceInfraGroup) { + foreach ($group in $DestinationInfraGroup) { $tmp = (Get-NSXTInfraGroup -Name $group).Path $destinationGroups+= $tmp } From 72a55558609fb85f23befafc87d7a9648504af5d Mon Sep 17 00:00:00 2001 From: William Lam Date: Fri, 15 Mar 2019 10:46:43 -0700 Subject: [PATCH 06/28] Fixing logic for SRC/DST Infra Group --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index de52816..eb54158 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -489,7 +489,7 @@ Function New-NSXTFirewall { } } - if(! $DestinationInfraGroup) { + if($DestinationInfraGroup) { foreach ($group in $DestinationInfraGroup) { $tmp = (Get-NSXTInfraGroup -Name $group).Path $destinationGroups+= $tmp @@ -506,7 +506,7 @@ Function New-NSXTFirewall { } } - if(! $SourceInfraGroup) { + if($SourceInfraGroup) { foreach ($group in $SourceInfraGroup) { $tmp = (Get-NSXTInfraGroup -Name $group).Path $sourceGroups+= $tmp From bda5a5a276ca016a4861ca53489203f5b14722f5 Mon Sep 17 00:00:00 2001 From: William Lam Date: Mon, 18 Mar 2019 13:39:52 -0700 Subject: [PATCH 07/28] Fixing the default Scope label for CGW FW Rules --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index eb54158..fcfbe3c 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -524,8 +524,8 @@ Function New-NSXTFirewall { } $scopeLabels = @() - if(! $InfraScope ) { - $scopeLabels = @("/infra/labels/$($GatewayType.toLower())") + if(!$InfraScope) { + $scopeLabels = @("/infra/labels/$($GatewayType.toLower())-all") } else { foreach ($infraScopeName in $InfraScope) { $scope = Get-NSXTInfraScope -Name $infraScopeName From d95806ea2f2f91546c815ffaeb8ae3171a9d7fe4 Mon Sep 17 00:00:00 2001 From: William Lam Date: Tue, 19 Mar 2019 10:31:20 -0700 Subject: [PATCH 08/28] Fix CGW/MGW scope --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index fcfbe3c..d29abbc 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -525,7 +525,11 @@ Function New-NSXTFirewall { $scopeLabels = @() if(!$InfraScope) { - $scopeLabels = @("/infra/labels/$($GatewayType.toLower())-all") + if($GatewayType.toLower() -eq "cgw") { + $scopeLabels = @("/infra/labels/$($GatewayType.toLower())-all") + } else { + $scopeLabels = @("/infra/labels/$($GatewayType.toLower())") + } } else { foreach ($infraScopeName in $InfraScope) { $scope = Get-NSXTInfraScope -Name $infraScopeName From 1c54a37fbdeb56ac33146d1ff27f084448f9b8bd Mon Sep 17 00:00:00 2001 From: Matt Frey Date: Tue, 19 Mar 2019 15:06:54 -0700 Subject: [PATCH 09/28] Shortened ImageType to Type --- Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 17508d7..d47d6b5 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -7064,7 +7064,7 @@ function Get-HVBaseImageVM { containing the name of the vCenter, or as a vCenter object as returned by Get-HVvCenterServer. If the value is not passed or null then first element returned from Get-HVvCenterServer would be considered in place of VirtualCenter. - .PARAMETER ImageType + .PARAMETER Type A parameter to define the type of compatability to check the base image VM list against. Valid options are 'VDI', 'RDS', or 'ALL' 'VDI' will return all desktop compatible Base Image VMs. 'RDS' will return all RDSH compatible Base Image VMs. @@ -7072,14 +7072,14 @@ function Get-HVBaseImageVM { The default value is 'ALL'. .PARAMETER Name - The name of a virtual machine (if known), to filter Base Image VMs on. Wildcards are accepted. If Name is specified, then ImageType + The name of a virtual machine (if known), to filter Base Image VMs on. Wildcards are accepted. If Name is specified, then Type is not considered for filtering. .EXAMPLE - Get-HVBaseImageVM -VirtualCenter 'vCenter1' -ImageType VDI + Get-HVBaseImageVM -VirtualCenter 'vCenter1' -Type VDI .EXAMPLE - Get-HVBaseImageVM -VirtualCenter $vCenter1 -ImageType ALL + Get-HVBaseImageVM -VirtualCenter $vCenter1 -Type ALL .EXAMPLE Get-HVBaseImageVM -Name '*WIN10*' @@ -7099,7 +7099,7 @@ function Get-HVBaseImageVM { #> [cmdletbinding( - DefaultParameterSetName='ImageType' + DefaultParameterSetName='Type' )] param( @@ -7109,9 +7109,9 @@ function Get-HVBaseImageVM { [Parameter(Mandatory = $false)] $VirtualCenter = $null, - [Parameter(Mandatory = $false,ParameterSetName = 'ImageType')] + [Parameter(Mandatory = $false,ParameterSetName = 'Type')] [ValidateSet('VDI','RDS','ALL')] - $ImageType = 'VDI', + $Type = 'VDI', [Parameter(Mandatory = $false,ParameterSetName = 'Name')] [string]$Name = $null @@ -7153,7 +7153,7 @@ function Get-HVBaseImageVM { If ($null -ne $PSBoundParameters.Name) { $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object {$_.Name -like $Name} } Else { - Switch ($ImageType) { + Switch ($Type) { 'VDI' { $CompatibleBaseImageVMs = $BaseImageVMList | Where-Object { @@ -7231,7 +7231,7 @@ function Get-HVBaseImageSnapshot { #> [cmdletbinding( - DefaultParameterSetName='ImageType' + DefaultParameterSetName='Type' )] param( From db8f4407a04b4e0717673cff133665e7c499b3c3 Mon Sep 17 00:00:00 2001 From: Matt Frey Date: Fri, 5 Apr 2019 11:19:38 -0500 Subject: [PATCH 10/28] Address Issue #273 --- Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index f176258..5d4e80f 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -2057,7 +2057,7 @@ function New-HVFarm { Set to true to enable provision of RDSServers immediately in farm. Applicable to Linked Clone and Instant Clone farms. -.PARAMETER StopOnProvisioningError +.PARAMETER StopProvisioningOnError Set to true to stop provisioning of all RDSServers on error. Applicable to Linked Clone and Instant Clone farms. @@ -2130,11 +2130,11 @@ function New-HVFarm { Reference to Horizon View Server to query the farms from. If the value is not passed or null then first element from global:DefaultHVServers would be considered in-place of hvServer. .EXAMPLE - New-HVFarm -LinkedClone -FarmName 'LCFarmTest' -ParentVM 'Win_Server_2012_R2' -SnapshotVM 'Snap_RDS' -VmFolder 'PoolVM' -HostOrCluster 'cls' -ResourcePool 'cls' -Datastores 'datastore1 (5)' -FarmDisplayName 'LC Farm Test' -Description 'created LC Farm from PS' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern "LCFarmVM_PS" -MinReady 1 -MaximumCount 1 -SysPrepName "RDSH_Cust2" -NetBiosName "adviewdev" + New-HVFarm -LinkedClone -FarmName 'LCFarmTest' -ParentVM 'Win_Server_2012_R2' -SnapshotVM 'Snap_RDS' -VmFolder 'PoolVM' -HostOrCluster 'cls' -ResourcePool 'cls' -Datastores 'datastore1 (5)' -FarmDisplayName 'LC Farm Test' -Description 'created LC Farm from PS' -EnableProvisioning $true -StopProvisioningOnError $false -NamingPattern "LCFarmVM_PS" -MinReady 1 -MaximumCount 1 -SysPrepName "RDSH_Cust2" -NetBiosName "adviewdev" Creates new linkedClone farm by using naming pattern .EXAMPLE - New-HVFarm -InstantClone -FarmName 'ICFarmCL' -ParentVM 'vm-rdsh-ic' -SnapshotVM 'Snap_5' -VmFolder 'Instant_Clone_VMs' -HostOrCluster 'vimal-cluster' -ResourcePool 'vimal-cluster' -Datastores 'datastore1' -FarmDisplayName 'IC Farm using CL' -Description 'created IC Farm from PS command-line' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern "ICFarmCL-" -NetBiosName "ad-vimalg" + New-HVFarm -InstantClone -FarmName 'ICFarmCL' -ParentVM 'vm-rdsh-ic' -SnapshotVM 'Snap_5' -VmFolder 'Instant_Clone_VMs' -HostOrCluster 'vimal-cluster' -ResourcePool 'vimal-cluster' -Datastores 'datastore1' -FarmDisplayName 'IC Farm using CL' -Description 'created IC Farm from PS command-line' -EnableProvisioning $true -StopProvisioningOnError $false -NamingPattern "ICFarmCL-" -NetBiosName "ad-vimalg" Creates new linkedClone farm by using naming pattern .EXAMPLE @@ -2344,11 +2344,11 @@ function New-HVFarm { [boolean] $EnableProvisioning = $true, - #farmSpec.automatedfarmSpec.virtualCenterProvisioningSettings.stopOnProvisioningError if LINKED_CLONE, INSTANT_CLONE + #farmSpec.automatedfarmSpec.virtualCenterProvisioningSettings.stopProvisioningOnError if LINKED_CLONE, INSTANT_CLONE [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] [boolean] - $StopOnProvisioningError = $true, + $StopProvisioningOnError = $true, [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] @@ -3448,7 +3448,7 @@ function New-HVPool { .PARAMETER BlackoutTimes A list of blackout times. -.PARAMETER StopOnProvisioningError +.PARAMETER StopProvisioningOnError Set to true to stop provisioning of all VMs on error. Applicable to Full, Linked, Instant Clone Pools. @@ -3575,7 +3575,7 @@ function New-HVPool { first element from global:DefaultHVServers would be considered in-place of hvServer. .EXAMPLE - C:\PS>New-HVPool -LinkedClone -PoolName 'vmwarepool' -UserAssignment FLOATING -ParentVM 'Agent_vmware' -SnapshotVM 'kb-hotfix' -VmFolder 'vmware' -HostOrCluster 'CS-1' -ResourcePool 'CS-1' -Datastores 'datastore1' -NamingMethod PATTERN -PoolDisplayName 'vmware linkedclone pool' -Description 'created linkedclone pool from ps' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern "vmware2" -MinReady 0 -MaximumCount 1 -SpareCount 1 -ProvisioningTime UP_FRONT -SysPrepName vmwarecust -CustType SYS_PREP -NetBiosName adviewdev -DomainAdmin root + C:\PS>New-HVPool -LinkedClone -PoolName 'vmwarepool' -UserAssignment FLOATING -ParentVM 'Agent_vmware' -SnapshotVM 'kb-hotfix' -VmFolder 'vmware' -HostOrCluster 'CS-1' -ResourcePool 'CS-1' -Datastores 'datastore1' -NamingMethod PATTERN -PoolDisplayName 'vmware linkedclone pool' -Description 'created linkedclone pool from ps' -EnableProvisioning $true -StopProvisioningOnError $false -NamingPattern "vmware2" -MinReady 0 -MaximumCount 1 -SpareCount 1 -ProvisioningTime UP_FRONT -SysPrepName vmwarecust -CustType SYS_PREP -NetBiosName adviewdev -DomainAdmin root Create new automated linked clone pool with naming method pattern .EXAMPLE @@ -4030,12 +4030,12 @@ function New-HVPool { [boolean] $EnableProvisioning = $true, - #desktopSpec.automatedDesktopSpec.virtualCenterProvisioningSettings.stopOnProvisioningError if LINKED_CLONE, INSTANT_CLONE, FULL_CLONE + #desktopSpec.automatedDesktopSpec.virtualCenterProvisioningSettings.stopProvisioningOnError if LINKED_CLONE, INSTANT_CLONE, FULL_CLONE [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] [Parameter(Mandatory = $false,ParameterSetName = 'FULL_CLONE')] [boolean] - $StopOnProvisioningError = $true, + $StopProvisioningOnError = $true, [Parameter(Mandatory = $false,ParameterSetName = "LINKED_CLONE")] [Parameter(Mandatory = $false,ParameterSetName = 'INSTANT_CLONE')] From 3b5f501d724065c945c0a40d35b379da2d11dabe Mon Sep 17 00:00:00 2001 From: Matt Frey Date: Mon, 8 Apr 2019 00:56:49 -0500 Subject: [PATCH 11/28] Address Issue #180 --- Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 5d4e80f..bfbd71a 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -4310,6 +4310,7 @@ function New-HVPool { $adContainer = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.AdContainer } $custType = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.CustomizationType + $reusePreExistingAccounts = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.reusePreExistingAccounts if ($jsonObject.AutomatedDesktopSpec.ProvisioningType -eq "INSTANT_CLONE_ENGINE") { $InstantClone = $true if ($null -ne $jsonObject.AutomatedDesktopSpec.CustomizationSettings.CloneprepCustomizationSettings) { @@ -4330,7 +4331,6 @@ function New-HVPool { 'SYS_PREP' { $sysprepCustomizationSettings = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.SysprepCustomizationSettings $sysPrepName = $sysprepCustomizationSettings.customizationSpec - $reusePreExistingAccounts = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.reusePreExistingAccounts } 'QUICK_PREP' { $powerOffScriptName = $jsonObject.AutomatedDesktopSpec.CustomizationSettings.QuickprepCustomizationSettings.PowerOffScriptName @@ -5401,7 +5401,7 @@ function Get-HVPoolCustomizationSetting { } if ($null -eq $ViewComposerDomainAdministratorID) { throw "No Composer Domain Administrator found with netBiosName: [$netBiosName]" - } + } if ($custType -eq 'SYS_PREP') { $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.CustomizationType = 'SYS_PREP' $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.SysprepCustomizationSettings = Get-CustomizationObject @@ -5425,6 +5425,7 @@ function Get-HVPoolCustomizationSetting { throw "The customization type: [$custType] is not supported for LinkedClone Pool" } $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.DomainAdministrator = $ViewComposerDomainAdministratorID + $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.ReusePreExistingAccounts = $reusePreExistingAccounts } elseIf ($FullClone) { if ($custType -eq 'SYS_PREP') { $desktopSpecObj.AutomatedDesktopSpec.CustomizationSettings.CustomizationType = 'SYS_PREP' From b95886558fefd7eefb929aa866eb198037b9cba3 Mon Sep 17 00:00:00 2001 From: Mark McGilly Date: Tue, 9 Apr 2019 10:55:34 -0400 Subject: [PATCH 12/28] Get-HcxMigration: Allow array of MigrationIds --- Modules/VMware.HCX/VMware.HCX.psm1 | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index cfbe95b..5582681 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -453,12 +453,23 @@ Function Get-HcxMigration { Get-HcxMigration -MigrationId #> Param ( - [Parameter(Mandatory=$false)][String]$MigrationId, + [Parameter(Mandatory=$false)][String[]]$MigrationId, [Switch]$RunningMigrations ) If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { - $spec = @{} + If($PSBoundParameters.ContainsKey("MigrationId")){ + $spec = @{ + filter = @{ + migrationId = $MigrationId + } + paging =@{ + pageSize = $MigrationId.Count + } + } + } Else { + $spec = @{} + } $body = $spec | ConvertTo-Json $hcxQueryUrl = $global:hcxConnection.Server + "/migrations?action=query" @@ -468,10 +479,10 @@ Function Get-HcxMigration { $requests = Invoke-WebRequest -Uri $hcxQueryUrl -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing } - $migrations = ($requests.content | ConvertFrom-Json).rows - if($PSBoundParameters.ContainsKey("MigrationId")){ - $migrations = $migrations | where { $_.migrationId -eq $MigrationId } + $migrations = ($requests.content | ConvertFrom-Json).items + } else { + $migrations = ($requests.content | ConvertFrom-Json).rows } if($RunningMigrations){ From 423e752404c1d933bceda6b49df8f038b129f161 Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 13 Apr 2019 13:41:51 -0700 Subject: [PATCH 13/28] Adding Route Based VPN functions --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 2 +- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 393 +++++++++++++++++-- 2 files changed, 371 insertions(+), 24 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index 45e549d..4b50bf0 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup' +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', 'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index d29abbc..e5c7c06 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -1641,53 +1641,400 @@ Function Get-NSXTInfraGroup { .EXAMPLE Get-NSXTInfraGroup -Name "S3 Prefixes" #> - param( - [Parameter(Mandatory=$false)][String]$Name, - [Switch]$Troubleshoot - ) + param( + [Parameter(Mandatory=$false)][String]$Name, + [Switch]$Troubleshoot + ) - If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { - $method = "GET" - $infraGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/groups" + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $infraGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/groups" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$infraGroupsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $infraGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $infraGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T Infrastructure Groups" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $groups = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $groups = $groups | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($group in $groups) { + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Path = $group.path; + } + $results+=$tmp + } + $results + } + } +} + +Function New-NSXTRouteBasedVPN { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 04/13/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Infrastructure Scopes + .DESCRIPTION + This cmdlet retrieves all NSX-T Infrastructure Scopes + .EXAMPLE + New-NSXTRouteBasedVPN -Name VPN3 ` + -PublicIP 18.184.241.223 ` + -RemotePublicIP 18.194.148.62 ` + -BGPLocalIP 169.254.51.2 ` + -BGPRemoteIP 169.254.51.1 ` + -BGPLocalASN 65056 ` + -BGPremoteASN 64512 ` + -BGPNeighborID 60 ` + -TunnelEncryption AES_256 ` + -TunnelDigestEncryption SHA2_256 ` + -IKEEncryption AES_256 ` + -IKEDigestEncryption SHA2_256 ` + -DHGroup GROUP14 ` + -IKEVersion IKE_V1 ` + -PresharedPassword VMware123. ` + -Troubleshoot + #> + param( + [Parameter(Mandatory=$true)][String]$Name, + [Parameter(Mandatory=$true)][String]$PublicIP, + [Parameter(Mandatory=$true)][String]$RemotePublicIP, + [Parameter(Mandatory=$true)][String]$BGPLocalIP, + [Parameter(Mandatory=$true)][String]$BGPRemoteIP, + [Parameter(Mandatory=$false)][int]$BGPLocalPrefix=30, + [Parameter(Mandatory=$true)][ValidateRange(64512,65534)][int]$BGPLocalASN, + [Parameter(Mandatory=$true)][ValidateRange(64512,65534)][int]$RemoteBGPASN, + [Parameter(Mandatory=$true)][String]$BGPNeighborID, + [Parameter(Mandatory=$true)][String][ValidateSet("AES_128","AES_256","AES_GCM_128","AES_GCM_192","AES_GCM_256")]$TunnelEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("SHA1","SHA2_256")]$TunnelDigestEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("AES_128","AES_256","AES_GCM_128","AES_GCM_192","AES_GCM_256")]$IKEEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("SHA1","SHA2_256")]$IKEDigestEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("GROUP2","GROUP5","GROUP14","GROUP15","GROUP16")]$DHGroup, + [Parameter(Mandatory=$true)][String][ValidateSet("IKE_V1","IKE_V2","IKE_FLEX")]$IKEVersion, + [Parameter(Mandatory=$true)][String]$PresharedPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + + ## Configure BGP ASN + + $payload = @{ + local_as_num = $BGPLocalASN; + } + $body = $payload | ConvertTo-Json -Depth 5 + + $ASNmethod = "patch" + $bgpAsnURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/bgp" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $ASNmethod`n$bgpAsnURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $bgpAsnURL -Body $body -Method $ASNmethod -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $bgpAsnURL -Body $body -Method $ASNmethod -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in updating BGP ASN" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + ## Configure BGP Neighbor + + $payload = @{ + resource_type = "BgpNeighborConfig"; + id = $BGPNeighborID; + remote_as_num = $RemoteBGPASN; + neighbor_address = $BGPRemoteIP; + } + $body = $payload | ConvertTo-Json -Depth 5 + + $method = "put" + $bgpNeighborURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/bgp/neighbors/$BGPNeighborID" if($Troubleshoot) { - Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$infraGroupsURL`n" + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$bgpNeighborURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" } try { if($PSVersionTable.PSEdition -eq "Core") { - $requests = Invoke-WebRequest -Uri $infraGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + $requests = Invoke-WebRequest -Uri $bgpNeighborURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck } else { - $requests = Invoke-WebRequest -Uri $infraGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers + $requests = Invoke-WebRequest -Uri $bgpNeighborURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers } } catch { if($_.Exception.Response.StatusCode -eq "Unauthorized") { Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" break } else { - Write-Error "Error in retrieving NSX-T Infrastructure Groups" + Write-Error "Error in configuring BGP Neighbor" Write-Error "`n($_.Exception.Message)`n" break } } if($requests.StatusCode -eq 200) { - $groups = ($requests.Content | ConvertFrom-Json).results + ## Configure Route Based Policy VPN - if ($PSBoundParameters.ContainsKey("Name")){ - $groups = $groups | where {$_.display_name -eq $Name} + $TunnelSubnets = @{ + ip_addresses = @("$BGPLocalIP"); + prefix_length = $BGPLocalPrefix; } - $results = @() - foreach ($group in $groups) { - $tmp = [pscustomobject] @{ - Name = $group.display_name; - ID = $group.id; - Path = $group.path; + $payload = @{ + display_name = $Name; + enabled = $true; + local_address = $PublicIP; + remote_private_address = $RemotePublicIP; + remote_public_address = $RemotePublicIP; + passphrases = @("$PresharedPassword"); + tunnel_digest_algorithms = @("$TunnelDigestEncryption"); + ike_digest_algorithms = @("$IKEDigestEncryption"); + ike_encryption_algorithms = @("$IKEEncryption"); + enable_perfect_forward_secrecy = $true; + dh_groups = @("$DHGroup"); + ike_version = $IKEVersion; + l3vpn_session = @{ + resource_type = "RouteBasedL3VpnSession"; + tunnel_subnets = @($TunnelSubnets); + default_rule_logging = $false; + force_whitelisting = $false; + routing_config_path = "/infra/tier-0s/vmc/locale-services/default/bgp/neighbors/$BGPNeighborID"; + }; + tunnel_encryption_algorithms = @("$TunnelEncryption"); + } + $body = $payload | ConvertTo-Json -Depth 5 + + $routeBasedVPNURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/l3vpns/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$bgpNeighborURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $routeBasedVPNURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $routeBasedVPNURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in configuring Route Based VPN" + Write-Error "`n($_.Exception.Message)`n" + break } - $results+=$tmp } - $results + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created Route Based VPN" + ($requests.Content | ConvertFrom-Json) + } } } - } \ No newline at end of file + } +} + +Function Get-NSXTRouteBasedVPN { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 04/13/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Route Based VPN Tunnels + .DESCRIPTION + This cmdlet retrieves all NSX-T Route Based VPN Tunnels description + .EXAMPLE + Get-NSXTRouteBasedVPN + .EXAMPLE + Get-NSXTRouteBasedVPN -Name "VPN-T1" + #> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $routeBaseVPNURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/l3vpns" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$routeBaseVPNURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $routeBaseVPNURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $routeBaseVPNURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T Route Based VPN Tunnels" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $groups = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $groups = $groups | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($group in $groups) { + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Path = $group.path; + RoutingConfigPath = $group.l3vpn_session.routing_config_path; + } + $results+=$tmp + } + $results + } + } +} + +Function Remove-NSXTRouteBasedVPN { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 04/13/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes a route based VPN Tunnel and it's associated BGP neighbor + .DESCRIPTION + This cmdlet removes a route based VPN Tunnel and it's associated BGP neighbor + .EXAMPLE + Remove-NSXTRouteBasedVPN -Name VPN1 -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $TunnelId = (Get-NSXTRouteBasedVPN -Name $Name).ID + $path = (Get-NSXTRouteBasedVPN -Name $Name).RoutingConfigPath + + # Delete IPSEC tunnel + $method = "DELETE" + $deleteVPNtunnelURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/l3vpns/$TunnelId" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteVPNtunnelURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteVPNtunnelURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteVPNtunnelURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in removing NSX-T IPSEC Tunnel: $Name" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T IPSEC Tunnel: $Name" + } + + # Delete BGP Neighbor + $method = "DELETE" + $deleteBGPnbURL = $global:nsxtProxyConnection.Server + "/policy/api/v1$path" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteBGPnbURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteBGPnbURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteBGPnbURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in removing NSX-T BGP Neighbor" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T BGP Neighbor" + } + } +} \ No newline at end of file From 0cfb39779ba66690bfd22e3dd0969f8a3a41595e Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 13 Apr 2019 14:11:49 -0700 Subject: [PATCH 14/28] Fix "Successfully" typo --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index e5c7c06..3e73913 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -205,7 +205,7 @@ Function New-NSXTSegment { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully created new NSX-T Segment $Name" + Write-Host "Successfully created new NSX-T Segment $Name" ($requests.Content | ConvertFrom-Json) | select display_name, id } } @@ -260,7 +260,7 @@ Function Remove-NSXTSegment { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully removed NSX-T Segment $Name" + Write-Host "Successfully removed NSX-T Segment $Name" } } } @@ -577,7 +577,7 @@ Function New-NSXTFirewall { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully created new NSX-T Firewall Rule $Name" + Write-Host "Successfully created new NSX-T Firewall Rule $Name" ($requests.Content | ConvertFrom-Json) | select display_name, id } } @@ -633,7 +633,7 @@ Function Remove-NSXTFirewall { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully removed NSX-T Firewall Rule" + Write-Host "Successfully removed NSX-T Firewall Rule" } } } @@ -791,7 +791,7 @@ Function New-NSXTGroup { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully created new NSX-T Group $Name" + Write-Host "Successfully created new NSX-T Group $Name" ($requests.Content | ConvertFrom-Json) | select display_name, id } } @@ -847,7 +847,7 @@ Function Remove-NSXTGroup { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully removed NSX-T Group $Name" + Write-Host "Successfully removed NSX-T Group $Name" } } } @@ -997,7 +997,7 @@ Function New-NSXTService { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully created new NSX-T Service $Name" + Write-Host "Successfully created new NSX-T Service $Name" ($requests.Content | ConvertFrom-Json) | select display_name, id } } @@ -1352,7 +1352,7 @@ Function New-NSXTDistFirewall { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully created new NSX-T Distributed Firewall Rule $Name" + Write-Host "Successfully created new NSX-T Distributed Firewall Rule $Name" ($requests.Content | ConvertFrom-Json) | select display_name, id } } @@ -1411,7 +1411,7 @@ Function Remove-NSXTDistFirewall { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully removed NSX-T Distributed Firewall Rule" + Write-Host "Successfully removed NSX-T Distributed Firewall Rule" } } } @@ -1477,7 +1477,7 @@ Function Get-NSXTRouteTable { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully retrieved NSX-T Routing Table`n" + Write-Host "Successfully retrieved NSX-T Routing Table`n" $routeTables = ($requests.Content | ConvertFrom-Json).results foreach ($routeTable in $routeTables) { @@ -1544,7 +1544,7 @@ If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection f } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully retrieved NSX-T Overview Information" + Write-Host "Successfully retrieved NSX-T Overview Information" ($requests.Content | ConvertFrom-Json) } } @@ -1872,7 +1872,7 @@ Function New-NSXTRouteBasedVPN { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully created Route Based VPN" + Write-Host "Successfully created Route Based VPN" ($requests.Content | ConvertFrom-Json) } } @@ -2005,7 +2005,7 @@ Function Remove-NSXTRouteBasedVPN { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully removed NSX-T IPSEC Tunnel: $Name" + Write-Host "Successfully removed NSX-T IPSEC Tunnel: $Name" } # Delete BGP Neighbor @@ -2034,7 +2034,7 @@ Function Remove-NSXTRouteBasedVPN { } if($requests.StatusCode -eq 200) { - Write-Host "Succesfully removed NSX-T BGP Neighbor" + Write-Host "Successfully removed NSX-T BGP Neighbor" } } } \ No newline at end of file From 25450e9003f90dbb3dbfb7fb5b33ea556a00ccd9 Mon Sep 17 00:00:00 2001 From: William Lam Date: Mon, 15 Apr 2019 09:15:40 -0700 Subject: [PATCH 15/28] Fix No DHCP NSX-T Segment creation --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 3e73913..1f34f3d 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -152,6 +152,8 @@ Function New-NSXTSegment { This cmdlet creates a new NSX-T Segment (Logical Networks) .EXAMPLE New-NSXTSegment -Name "sddc-cgw-network-4" -Gateway "192.168.4.1/24" -DHCP -DHCPRange "192.168.4.2-192.168.4.254" + .EXAMPLE + New-NSXTSegment -Name "sddc-cgw-network-5" -Gateway "192.168.5.1/24" #> Param ( [Parameter(Mandatory=$True)]$Name, @@ -163,14 +165,14 @@ Function New-NSXTSegment { If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { if($DHCP) { - $dhcpConf = @($DHCPRange) + $subnets = @{ + gateway_address = $gateway; + dhcp_ranges = @($DHCPRange) + } } else { - $dhcpConf = @($null) - } - - $subnets = @{ - gateway_address = $gateway; - dhcp_ranges = $dhcpConf; + $subnets = @{ + gateway_address = $gateway; + } } $payload = @{ From 2cebd97c014c3fe736ef9f783db7699864fa16a6 Mon Sep 17 00:00:00 2001 From: William Lam Date: Fri, 19 Apr 2019 16:24:19 -0700 Subject: [PATCH 16/28] Fixed Distributed Firewall Rule Section + Remove NSX-T Service --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 2 +- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 169 +++++++++++++++---- 2 files changed, 136 insertions(+), 35 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index 4b50bf0..c18be71 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', 'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN' +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', 'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN', 'Remove-NSXTService', 'New-NSXTDistFirewallSection', 'Get-NSXTDistFirewallSection' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 1f34f3d..59606b5 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -520,7 +520,7 @@ Function New-NSXTFirewall { if($serviceName -eq "ANY") { $services = @("ANY") } else { - $tmp = "/infra/services/$serviceName" + $tmp = (Get-NSXTService -Name "$serviceName").Path $services+=$tmp } } @@ -924,6 +924,7 @@ Function Get-NSXTService { Protocol = $serviceProtocol; Source = $serviceSourcePorts; Destination = $serviceDestinationPorts; + Path = $service.path; } $results += $tmp } @@ -932,6 +933,60 @@ Function Get-NSXTService { } } +Function Remove-NSXTService { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 04/10/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Service + .DESCRIPTION + This cmdlet removes an NSX-T Service + .EXAMPLE + Remove-NSXTService -Id VMware-Blast -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "DELETE" + $deleteServiceURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/services/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteServiceURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteServiceURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteServiceURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in removing NSX-T Service" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Successfully removed NSX-T Service $Id" + } + } +} + Function New-NSXTService { <# .NOTES @@ -1005,27 +1060,23 @@ Function New-NSXTService { } } -Function Get-NSXTDistFirewallSection { +Function New-NSXTDistFirewallSection { <# .NOTES =========================================================================== Created by: William Lam - Date: 01/01/2019 + Date: 04/19/2019 Organization: VMware Blog: http://www.virtuallyghetto.com Twitter: @lamw =========================================================================== .SYNOPSIS - Returns all NSX-T Distributed Firewall Groups + Creates new NSX-T Distributed Firewall Section .DESCRIPTION - This cmdlet retrieves all NSX-T Distributed Firewall Sections + This cmdlet to create new NSX-T Distributed Firewall Section .EXAMPLE - Get-NSXTDistFirewallSection - .EXAMPLE - Get-NSXTDistFirewallSection -Name "App Section 1" - .EXAMPLE - et-NSXTDistFirewallSection -Category Emergency + Get-NSXTDistFirewallSection -Name "App Section 1" -Category Application #> param( [Parameter(Mandatory=$false)][String]$Name, @@ -1034,52 +1085,102 @@ Function Get-NSXTDistFirewallSection { ) If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { - $method = "GET" - $distFirewallGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/cgw/communication-maps" + $payload = @{ + display_name = $Name; + category = $Category; + resource_type = "CommunicationMap"; + } + + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $generatedId = (New-Guid).Guid + $distFirewallSectionURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/cgw/communication-maps/$generatedId" if($Troubleshoot) { - Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$distFirewallGroupURL`n" + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$distFirewallSectionURL`n" } try { if($PSVersionTable.PSEdition -eq "Core") { - $requests = Invoke-WebRequest -Uri $distFirewallGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + $requests = Invoke-WebRequest -Uri $distFirewallSectionURL -Method $method -Body $body -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck } else { - $requests = Invoke-WebRequest -Uri $distFirewallGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers + $requests = Invoke-WebRequest -Uri $distFirewallSectionURL -Method $method -Body $body -Headers $global:nsxtProxyConnection.headers } } catch { if($_.Exception.Response.StatusCode -eq "Unauthorized") { Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" break } else { - Write-Error "Error in retrieving NSX-T Distributed Firewall Sections" + Write-Error "Error in creating NSX-T Distributed Firewall Section" Write-Error "`n($_.Exception.Message)`n" break } } if($requests.StatusCode -eq 200) { - $groups = ($requests.Content | ConvertFrom-Json).results + Write-Host "Successfully created new NSX-T Distributed Firewall Section $Section" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } + } +} + +Function Get-NSXTDistFirewallSection { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 04/19/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Distributed Firewall Sections + .DESCRIPTION + This cmdlet retrieves all NSX-T Distributed Firewall Sections + .EXAMPLE + Get-NSXTDistFirewallSection +#> + param( + [Parameter(Mandatory=$true)][String]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $distFirewallSectionURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/cgw/communication-maps" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$distFirewallSectionURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $distFirewallSectionURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $distFirdistFirewallSectionURLwallURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T Distributed Firewall Section" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $sections = ($requests.Content | ConvertFrom-Json).results if ($PSBoundParameters.ContainsKey("Name")){ - $groups = $groups | where {$_.display_name -eq $Name} + $sections = $sections | where {$_.display_name -eq $Name} } - if ($PSBoundParameters.ContainsKey("Category")){ - $groups = $groups | where {$_.category -eq $Category} - } - - $results = @() - foreach ($group in $groups | Sort-Object -Property category) { - $tmp = [pscustomobject] @{ - Id = $group.id; - Section = $group.display_name; - Category = $group.category; - Precedence = $group.precedence; - } - $results+=$tmp - } - $results + $sections | Sort-Object -Propert display_name | select display_name, id } } } @@ -1329,7 +1430,7 @@ Function New-NSXTDistFirewall { $method = "PUT" $generatedId = (New-Guid).Guid - $newDistFirewallURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/cgw/communication-maps/$sectionId/communication-entries/$generatedId" + $newDistFirewallURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/cgw/communication-maps/$($sectionId)/communication-entries/$generatedId" if($Troubleshoot) { Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newDistFirewallURL`n" From 3134d1acd934ac43da93b9649ef344b82bac3c63 Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 20 Apr 2019 12:29:24 -0700 Subject: [PATCH 17/28] Removing -Name as required param + DROP keyword for action --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 59606b5..15e969e 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -1144,7 +1144,7 @@ Function Get-NSXTDistFirewallSection { Get-NSXTDistFirewallSection #> param( - [Parameter(Mandatory=$true)][String]$Name, + [Parameter(Mandatory=$false)][String]$Name, [Switch]$Troubleshoot ) @@ -1376,7 +1376,7 @@ Function New-NSXTDistFirewall { [Parameter(Mandatory=$True)]$SourceGroup, [Parameter(Mandatory=$True)]$DestinationGroup, [Parameter(Mandatory=$True)]$Service, - [Parameter(Mandatory=$True)][ValidateSet("ALLOW","DENY")]$Action, + [Parameter(Mandatory=$True)][ValidateSet("ALLOW","DROP")]$Action, [Parameter(Mandatory=$false)][Boolean]$Logged=$false, [Switch]$Troubleshoot ) From fd7429055ddba34648bebde67f9a805a0a223cba Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 20 Apr 2019 12:42:15 -0700 Subject: [PATCH 18/28] Add Remove-NSXTDistFirewallSection --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 54 ++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 15e969e..f3ea7e6 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -1185,6 +1185,60 @@ Function Get-NSXTDistFirewallSection { } } +Function Remove-NSXTDistFirewallSection { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 04/20/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Distributed Firewall Section + .DESCRIPTION + This cmdlet removes an NSX-T Distributed Firewall Section + .EXAMPLE + Remove-NSXTDistFirewallSection -Id -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "DELETE" + $deleteDistFirewallSectioneURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/cgw/communication-maps/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteDistFirewallSectioneURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteDistFirewallSectioneURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteDistFirewallSectioneURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in removing NSX-T Distributed Firewall Section" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Successfully removed NSX-T Distributed Firewall Section $Id" + } + } +} + Function Get-NSXTDistFirewall { <# .NOTES From 4c9fab7b6ca14d1e240ef8047a8d73fccb5bf932 Mon Sep 17 00:00:00 2001 From: Thibaut Noben Date: Mon, 22 Apr 2019 21:01:59 +0200 Subject: [PATCH 19/28] removed return farm summary --- Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index c58e1c0..c3e4e3e 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -1004,8 +1004,7 @@ function Get-HVFarm { if (! $farmList) { if (! $SuppressInfo) { Write-Host "Get-HVFarm: No Farm Found with given search parameters" - } - return $farmList + } } $farm_service_helper = New-Object VMware.Hv.FarmService $queryResults = @() From 11181a95ecde249a9689b99e2f8563e26d8c5df3 Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 4 May 2019 12:48:19 -0700 Subject: [PATCH 20/28] Added New-SubscribedContentLibrary function --- Modules/ContentLibrary/ContentLibrary.psm1 | 74 +++++++++++++++++++++- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/Modules/ContentLibrary/ContentLibrary.psm1 b/Modules/ContentLibrary/ContentLibrary.psm1 index 9a8574b..5729445 100644 --- a/Modules/ContentLibrary/ContentLibrary.psm1 +++ b/Modules/ContentLibrary/ContentLibrary.psm1 @@ -190,7 +190,7 @@ Function Get-ContentLibraryItemFiles { $itemIds = $contentLibraryItemService.list($libraryID) $DatastoreID = $library.storage_backings.datastore_id.Value $Datastore = get-datastore -id "Datastore-$DatastoreID" - + foreach($itemId in $itemIds) { $itemName = ($contentLibraryItemService.get($itemId)).name $contentLibraryItemFileSerice = Get-CisService com.vmware.content.library.item.file @@ -205,7 +205,7 @@ Function Get-ContentLibraryItemFiles { else{ $fullfilepath = "UNKNOWN" } - + if(!$LibraryItemName) { $fileResult = [pscustomobject] @{ Name = $file.name; @@ -709,4 +709,72 @@ Function New-VMFromVMTX { Write-Host "`nDeploying new VM $NewVMName from VMTX Template $VMTXName ..." $results = $vmtxService.deploy($vmtxId,$vmtxDeploySpec) -} +} + +Function New-SubscribedContentLibrary { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function creates a new Subscriber Content Library from Subscription URL + .PARAMETER LibraryName + The name of the new vSphere Content Library + .PARAMETER DatastoreName + The name of the vSphere Datastore to store the Content Library + .PARAMETER SubscriptionURL + The URL of the published Content Library + .PARAMETER SubscriptionThumbprint + The SSL Thumbprint for the published Content Library + .PARAMETER OnDemand + Specifies whether content is downloaded on-demand (e.g. no immediately) + .PARAMETER AutomaticSync + Specifies whether automatic synchronization with the external content library is enabled + .EXAMPLE + New-SubscribedContentLibrary -LibraryName NestedESXi -DatastoreName vsanDatastore -SubscriptionURL https://download3.vmware.com/software/vmw-tools/lib.json -SubscriptionThumbprint "7a:c4:08:2d:d3:55:56:af:9f:26:43:65:d0:31:99:0b:d2:f3:d8:69" -AutomaticSync + .EXAMPLE + New-SubscribedContentLibrary -LibraryName NestedESXi -DatastoreName vsanDatastore -SubscriptionURL https://download3.vmware.com/software/vmw-tools/lib.json -SubscriptionThumbprint "7a:c4:08:2d:d3:55:56:af:9f:26:43:65:d0:31:99:0b:d2:f3:d8:69" -OnDemand +#> + param( + [Parameter(Mandatory=$true)][String]$LibraryName, + [Parameter(Mandatory=$true)][String]$DatastoreName, + [Parameter(Mandatory=$true)][String]$SubscriptionURL, + [Parameter(Mandatory=$true)][String]$SubscriptionThumbprint, + [Parameter(Mandatory=$false)][Switch]$OnDemand, + [Parameter(Mandatory=$false)][Switch]$AutomaticSync + ) + + $datastore = Get-Datastore -Name $DatastoreName + + if($datastore) { + $datastoreId = $datastore.ExtensionData.MoRef.Value + $subscribeLibraryService = Get-CisService -Name "com.vmware.content.subscribed_library" + + $StorageSpec = [pscustomobject] @{ + datastore_id = $datastoreId; + type = "DATASTORE"; + } + + $UniqueChangeId = [guid]::NewGuid().tostring() + + $createSpec = $subscribeLibraryService.help.create.create_spec.create() + $createSpec.name = $LibraryName + $createSpec.type = "SUBSCRIBED" + $addResults = $createSpec.storage_backings.Add($StorageSpec) + + if($OnDemand) { $OnDemandFlag = $true } else { $OnDemandFlag = $false } + if($AutomaticSync) { $AutomaticSyncFlag = $true } else { $AutomaticSyncFlag = $false } + $createSpec.subscription_info.on_demand = $OnDemandFlag + $createSpec.subscription_info.automatic_sync_enabled = $AutomaticSyncFlag + $createSpec.subscription_info.subscription_url = $SubscriptionURL + $createSpec.subscription_info.authentication_method = "NONE" + $createSpec.subscription_info.ssl_thumbprint = $SubscriptionThumbprint + + Write-Host "Creating new Subscribed Content Library called $LibraryName ..." + $library = $subscribeLibraryService.create($UniqueChangeId, $createSpec) + } +} \ No newline at end of file From f4fc007bd5d0eca17a3fef0575fb2ac1c86ac18b Mon Sep 17 00:00:00 2001 From: William Lam Date: Mon, 6 May 2019 12:14:41 -0700 Subject: [PATCH 21/28] Added Destination Resource Pool / VM Folder --- Modules/CrossvCentervmotion/XVM.psm1 | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Modules/CrossvCentervmotion/XVM.psm1 b/Modules/CrossvCentervmotion/XVM.psm1 index cb9d225..555ec5d 100644 --- a/Modules/CrossvCentervmotion/XVM.psm1 +++ b/Modules/CrossvCentervmotion/XVM.psm1 @@ -152,10 +152,12 @@ Function New-XVCMRequest { The name of the source vSphere Datacenter .PARAMETER DstDatacenter The name of the destination vSphere Datacenter - .PARAMETER SrcCluster - .PARAMETER DstCluster The name of the destination vSphere Cluster, set to null if DstHost is defined + .PARAMETER DstPool + The name of the destination vSphere Resource Pool + .PARAMETER DstFolder + The name of the destination vSphere Folder .PARAMETER DstDatastore The name of the destination Datastore .PARAMETER DstHost @@ -171,6 +173,15 @@ Function New-XVCMRequest { -DstDatastore vsanDatastore ` -srcVMs @("PhotonOS-01","PhotonOS-02","PhotonOS-03","PhotonOS-04") ` -NetworkMapping @{"DVPG-VM Network 1"="DVPG-Internal Network";"DVPG-VM Network 2"="DVPG-External Network"} + .EXAMPLE + New-XVCMRequest -opType Clone -SrcSite OREGON -DstSite CALIF ` + -SrcDatacenter SDDC-Datacenter -srcVMs @(“DUDE-ubuntu”) ` + -DstDatacenter SDDC-Datacenter ` + -DstCluster "Cluster-1" -DstHost $null ` + -DstPool Compute-ResourcePool ` + -DstFolder Workloads ` + -DstDatastore WorkloadDatastore ` + -NetworkMapping @{"OREGON-VMs-sddc"="CALIF-sddc-VMs"} #> param( [Parameter(Mandatory=$true)][String]$opType, #Added by CPM for 2.0 @@ -178,8 +189,9 @@ Function New-XVCMRequest { [Parameter(Mandatory=$true)][String]$DstSite, [Parameter(Mandatory=$true)][String]$SrcDatacenter, [Parameter(Mandatory=$true)][String]$DstDatacenter, - #[Parameter(Mandatory=$true)][String]$SrcCluster, #Removed by CPM for 2.0 [Parameter(Mandatory=$true)][AllowNull()] $DstCluster, #Added [AllowNull()], removed [String] by CPM for 2.0 + [Parameter(Mandatory=$true)][String]$DstPool, + [Parameter(Mandatory=$true)][String]$DstFolder, [Parameter(Mandatory=$true)][String]$DstDatastore, [Parameter(Mandatory=$true)][AllowNull()] $DstHost, #Added by CPM for 2.0 [Parameter(Mandatory=$true)][String[]]$srcVMs, @@ -193,7 +205,8 @@ Function New-XVCMRequest { "targetSite"=$DstSite; "sourceDatacenter"=$SrcDatacenter; "targetDatacenter"=$dstDatacenter; - #"sourceCluster"=$SrcCluster; #Removed by CPM for 2.0 + "targetPool"=$DstPool; + "targetFolder"=$DstFolder; "targetCluster"=$DstCluster; "targetDatastore"=$DstDatastore; "targetHost"=$DstHost; #Added by CPM for 2.0 From 6f22da7f67924e405f3e9a4d86a273a68c57311b Mon Sep 17 00:00:00 2001 From: LucD Date: Wed, 8 May 2019 10:07:26 +0200 Subject: [PATCH 22/28] Save-PowerCLI v2.1 - fixed incorrect module version download - added a working cleanup in End Signed-off-by: Luc Dekens --- Scripts/Save-PowerCLI.ps1 | 281 ++++++++++++++++++++------------------ 1 file changed, 146 insertions(+), 135 deletions(-) diff --git a/Scripts/Save-PowerCLI.ps1 b/Scripts/Save-PowerCLI.ps1 index e9127bc..495c153 100644 --- a/Scripts/Save-PowerCLI.ps1 +++ b/Scripts/Save-PowerCLI.ps1 @@ -1,147 +1,158 @@ -function Save-PowerCLI { - <# - .SYNOPSIS - Advanced function which can be used to easily download specific versions of PowerCLI from an online gallery - .DESCRIPTION - Downloads a specific version of PowerCLI and all the dependencies at the appropriate version - .NOTES - Author: 1.0 - Dimitar Milov - Author: 2.0 - Kyle Ruddy, @kmruddy - .PARAMETER RequiredVersion - Dynamic parameter used to specify the PowerCLI version - .PARAMETER Path - Directory path where the modules should be downloaded - .PARAMETER Repository - Repository to access the PowerCLI modules - .PARAMETER Simple - Switch used to specify the nested version folders should be removed (therefore adding PowerShell 3/4 compatibility) - .EXAMPLE - Save-PowerCLI -RequiredVersion '10.0.0.7895300' -Path .\Downloads\ - Downloads PowerCLI 10.0.0 to the Downloads folder - .EXAMPLE - Save-PowerCLI -RequiredVersion '6.5.2.6268016' -Path .\Downloads\ -Simple - Downloads PowerCLI 6.5.2 to the Downloads folder and removes the nested version folders - #> - [CmdletBinding(SupportsShouldProcess = $True)] - param( - [Parameter(Mandatory = $true, Position = 1)] - [ValidateScript( { Test-Path $_} )] - $Path, - [Parameter(Mandatory = $false, Position = 2)] - [string]$Repository = 'PSGallery', - [Parameter(Mandatory = $false, Position = 3)] - [Switch]$Simple - ) - DynamicParam - { - # Set the dynamic parameters name - $ParameterName = 'RequiredVersion' - - # Create the dictionary - $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary - - # Create the collection of attributes - $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] - - # Create and set the parameters' attributes - $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute - $ParameterAttribute.ValueFromPipeline = $true - $ParameterAttribute.ValueFromPipelineByPropertyName = $true - $ParameterAttribute.Mandatory = $true - $ParameterAttribute.Position = 0 - - # Add the attributes to the attributes collection - $AttributeCollection.Add($ParameterAttribute) - - # Generate and set the ValidateSet - $pcliVersions = Find-Module -Name 'VMware.PowerCLI' -AllVersions - $arrSet = $pcliVersions | select-Object -ExpandProperty Version - $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) - - # Add the ValidateSet to the attributes collection - $AttributeCollection.Add($ValidateSetAttribute) - - # Create and return the dynamic parameter - $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection) - $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter) - return $RuntimeParameterDictionary +function Save-PowerCLI { +<# +.SYNOPSIS + Advanced function which can be used to easily download specific versions of PowerCLI from an online gallery +.DESCRIPTION + Downloads a specific version of PowerCLI and all the dependencies at the appropriate version +.NOTES + Author: 1.0 - Dimitar Milov + Author: 2.0 - Kyle Ruddy, @kmruddy + Author: 2.1 - Luc Dekens, @LucD22 + - fixed issue with downloading the correct versions + - added a working cleanup of unwanted versions +.PARAMETER RequiredVersion + Dynamic parameter used to specify the PowerCLI version +.PARAMETER Path + Directory path where the modules should be downloaded +.PARAMETER Repository + Repository to access the PowerCLI modules +.PARAMETER Simple + Switch used to specify the nested version folders should be removed (therefore adding PowerShell 3/4 compatibility) +.EXAMPLE + Save-PowerCLI -RequiredVersion '10.0.0.7895300' -Path .\Downloads\ + Downloads PowerCLI 10.0.0 to the Downloads folder +.EXAMPLE + Save-PowerCLI -RequiredVersion '6.5.2.6268016' -Path .\Downloads\ -Simple + Downloads PowerCLI 6.5.2 to the Downloads folder and removes the nested version folders +#> + [CmdletBinding(SupportsShouldProcess = $True)] + param( + [Parameter(Mandatory = $true, Position = 1)] + [ValidateScript( { Test-Path $_} )] + $Path, + [Parameter(Mandatory = $false, Position = 2)] + [string]$Repository = 'PSGallery', + [Parameter(Mandatory = $false, Position = 3)] + [Switch]$Simple + ) + DynamicParam + { + # Set the dynamic parameters name + $ParameterName = 'RequiredVersion' + + # Create the dictionary + $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary + + # Create the collection of attributes + $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] + + # Create and set the parameters' attributes + $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute + $ParameterAttribute.ValueFromPipeline = $true + $ParameterAttribute.ValueFromPipelineByPropertyName = $true + $ParameterAttribute.Mandatory = $true + $ParameterAttribute.Position = 0 + + # Add the attributes to the attributes collection + $AttributeCollection.Add($ParameterAttribute) + + # Generate and set the ValidateSet + $pcliVersions = Find-Module -Name 'VMware.PowerCLI' -AllVersions + $arrSet = $pcliVersions | select-Object -ExpandProperty Version + $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet) + + # Add the ValidateSet to the attributes collection + $AttributeCollection.Add($ValidateSetAttribute) + + # Create and return the dynamic parameter + $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [String], $AttributeCollection) + $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter) + return $RuntimeParameterDictionary + } + + begin { + $powercliModuleName = 'VMware.PowerCLI' + $desiredPowerCLIModule = Find-Module -Name $powercliModuleName -RequiredVersion $PSBoundParameters.RequiredVersion -Repository $Repository + + $depsOrder = 'VMware.VimAutomation.Sdk', 'VMware.VimAutomation.Common', 'VMware.Vim', 'VMware.VimAutomation.Cis.Core', 'VMware.VimAutomation.Core', 'VMware.VimAutomation.Nsxt', 'VMware.VimAutomation.Vmc', 'VMware.VimAutomation.Vds', 'VMware.VimAutomation.Srm', 'VMware.ImageBuilder', 'VMware.VimAutomation.Storage', 'VMware.VimAutomation.StorageUtility', 'VMware.VimAutomation.License', 'VMware.VumAutomation', 'VMware.VimAutomation.HorizonView', 'VMware.DeployAutomation', 'VMware.VimAutomation.vROps', 'VMware.VimAutomation.PCloud' + $orderedDependencies = @() + foreach ($depModuleName in $depsOrder) { + $orderedDependencies += $desiredPowerCLIModule.Dependencies | Where-Object {$_.Name -eq $depModuleName} } - - begin { - $powercliModuleName = 'VMware.PowerCLI' - $desiredPowerCLIModule = Find-Module -Name $powercliModuleName -RequiredVersion $RequiredVersion -Repository $Repository - - $depsOrder = 'VMware.VimAutomation.Sdk', 'VMware.VimAutomation.Common', 'VMware.Vim', 'VMware.VimAutomation.Cis.Core', 'VMware.VimAutomation.Core', 'VMware.VimAutomation.Nsxt', 'VMware.VimAutomation.Vmc', 'VMware.VimAutomation.Vds', 'VMware.VimAutomation.Srm', 'VMware.ImageBuilder', 'VMware.VimAutomation.Storage', 'VMware.VimAutomation.StorageUtility', 'VMware.VimAutomation.License', 'VMware.VumAutomation', 'VMware.VimAutomation.HorizonView', 'VMware.DeployAutomation', 'VMware.VimAutomation.vROps', 'VMware.VimAutomation.PCloud' - $orderedDependencies = @() - foreach ($depModuleName in $depsOrder) { - $orderedDependencies += $desiredPowerCLIModule.Dependencies | Where-Object {$_.Name -eq $depModuleName} + + foreach ($remainingDep in $desiredPowerCLIModule.Dependencies) { + if ($orderedDependencies.Name -notcontains $remainingDep.Name) { + $orderedDependencies += $remainingDep } - foreach ($remainingDep in $desiredPowerCLIModule.Dependencies) { - if ($orderedDependencies.Name -notcontains $remainingDep.Name) { - $orderedDependencies += $remainingDep - } - + } + } + + process { + # Save PowerCLI Module Version + $desiredPowerCLIModule | Save-Module -Path $Path + + # Working with the depenent modules + foreach ($dependency in $orderedDependencies) { + if (Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion}) { + # Save dependencies with minimum version + Find-Module $dependency.Name -RequiredVersion $dependency.MinimumVersion | Save-Module -Path $Path } } - - process { - # Save PowerCLI Module Version - $desiredPowerCLIModule | Save-Module -Path $Path - - # Working with the depenent modules - foreach ($dependency in $orderedDependencies) { - if (Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion}) { - # Save dependencies with minimum version - Find-Module $dependency.Name -RequiredVersion $dependency.MinimumVersion | Save-Module -Path $Path - - # Remove newer dependencies version - Get-ChildItem -Path (Join-Path $path $dependency.Name) | Where-Object {$_.Name -ne $dependency.MinimumVersion} | Remove-Item -Confirm:$false -Force -Recurse + } + + end { + Get-Item -Path "$($Path)\*" -PipelineVariable dir | + ForEach-Object -Process { + $children = Get-ChildItem -Path $dir.FullName -Directory + if($children.Count -gt 1){ + $tgtVersion = $orderedDependencies.GetEnumerator() | where {$_.Name -eq $dir.Name} + $children | where{$_.Name -ne $tgtVersion.MinimumVersion} | + ForEach-Object -Process { + Remove-Item -Path $_.FullName -Recurse -Force -Confirm:$false } } } - - end { - if ($Simple) { - - function FolderCleanup { - param( - [Parameter(Mandatory = $true, Position = 0)] - [ValidateScript( { Test-Path $_} )] - $ParentFolder, - [Parameter(Mandatory = $true, Position = 1)] - [String]$ModuleName, - [Parameter(Mandatory = $true, Position = 2)] - $Version - ) - - - $topFolder = Get-Item -Path (Join-Path $ParentFolder $ModuleName) - $versionFolder = $topFolder | Get-ChildItem -Directory | Where-Object {$_.Name -eq $Version} - $versionFolder | Get-ChildItem | Copy-Item -Destination $topFolder - - # Checking for any nested folders within the PowerCLI module version folder - if ($versionFolder| Get-ChildItem -Directory) { - - # Obtaining and storing the child items to a variable, then copying the items to the parent folder's nested folder - $nestFolder = $versionFolder| Get-ChildItem -Directory - foreach ($nestDir in $nestFolder) { - $nestDir | Get-ChildItem | Copy-Item -Destination (Join-Path $topFolder $nestDir.Name) - } - + + if ($Simple) { + + function FolderCleanup { + param( + [Parameter(Mandatory = $true, Position = 0)] + [ValidateScript( { Test-Path $_} )] + $ParentFolder, + [Parameter(Mandatory = $true, Position = 1)] + [String]$ModuleName, + [Parameter(Mandatory = $true, Position = 2)] + $Version + ) + + + $topFolder = Get-Item -Path (Join-Path $ParentFolder $ModuleName) + $versionFolder = $topFolder | Get-ChildItem -Directory | Where-Object {$_.Name -eq $Version} + $versionFolder | Get-ChildItem | Copy-Item -Destination $topFolder + + # Checking for any nested folders within the PowerCLI module version folder + if ($versionFolder| Get-ChildItem -Directory) { + + # Obtaining and storing the child items to a variable, then copying the items to the parent folder's nested folder + $nestFolder = $versionFolder| Get-ChildItem -Directory + foreach ($nestDir in $nestFolder) { + $nestDir | Get-ChildItem | Copy-Item -Destination (Join-Path $topFolder $nestDir.Name) } - - # Removing any of the former, no longer needed, directory structure - $versionFolder| Remove-Item -Recurse -Force + } - - FolderCleanup -ParentFolder $Path -ModuleName $desiredPowerCLIModule.Name -Version $desiredPowerCLIModule.Version - foreach ($cleanUp in $orderedDependencies) { - - FolderCleanup -ParentFolder $Path -ModuleName $cleanUp.Name -Version $cleanUp.MinimumVersion - } - + + # Removing any of the former, no longer needed, directory structure + $versionFolder| Remove-Item -Recurse -Force } - + + FolderCleanup -ParentFolder $Path -ModuleName $desiredPowerCLIModule.Name -Version $desiredPowerCLIModule.Version + foreach ($cleanUp in $orderedDependencies) { + + FolderCleanup -ParentFolder $Path -ModuleName $cleanUp.Name -Version $cleanUp.MinimumVersion + } + } - } \ No newline at end of file + } +} From 50559d9c6d96756d05d2c8cbd2815959d76de1bc Mon Sep 17 00:00:00 2001 From: samiullasha <46373019+samiullasha@users.noreply.github.com> Date: Wed, 8 May 2019 18:26:00 +0530 Subject: [PATCH 23/28] Adding new functions to Application Pool Adding the below new functions to Application Pool. Get-HVApplication, Remove-HVApplication, New-HVManualApplication, Get-HVPreInstalledApplication, New-HVPreInstalledApplication --- .../VMware.Hv.Helper/VMware.HV.Helper.psm1 | 532 +++++++++++++++++- 1 file changed, 531 insertions(+), 1 deletion(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 608180d..a73fc56 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -11946,12 +11946,542 @@ function Set-HVInstantCloneMaintenance { [System.gc]::collect() } } + +Function Get-HVApplication { +<# +.Synopsis + Gets the application information. + +.DESCRIPTION + Gets the application information. This will be useful to find out whether the specified application exists or not. If the application name is not specified, this will lists all the applications in the Pod. + +.PARAMETER ApplicationName + Name of the application. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.PARAMETER FormatList + Displays the list of the available applications in Table Format if this parameter is set to True. + +.EXAMPLE + Get-HVApplication -ApplicationName 'App1' -HvServer $HvServer + Queries and returns 'App1' information. + +.EXAMPLE + Get-HVApplication -HvServer $HvServer -FormatList:$True + Lists all the applications in the Pod. + +.OUTPUTS + Returns the information of the specified application if it specified, else displays all the available applications. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.2 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [string]$ApplicationName = $Null, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + $HvServer = $Null, + + [Parameter(Mandatory = $False)] + [string]$FormatList = $False + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve View API services from connection object." + break + } + } + process { + if ($ApplicationName) { + $eqFilter = Get-HVQueryFilter 'data.name' -Eq $ApplicationName + $ResourceObjs = Get-HVQueryResult -EntityType ApplicationInfo -Filter $eqFilter -HvServer $HvServer + if(!$ResourceObjs){Write-host "No application found with specified name: $ApplicationName"; return} + Write-host "Application found with specified name: $ApplicationName" + return $ResourceObjs + } + $ResourceObjs = Get-HVQueryResult -EntityType ApplicationInfo -HvServer $HvServer + if ($FormatList -eq $True){ return $ResourceObjs.data | Format-Table -AutoSize} + return $ResourceObjs.data + } + end { + [System.GC]::Collect() + } +} + +Function Remove-HVApplication { +<# +.Synopsis + Removes the specified application if exists. + +.DESCRIPTION + Removes the specified application if exists. + +.PARAMETER ApplicationName + Application to be deleted. + The name of the application must be given that is to be searched for and remove if exists. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.EXAMPLE + Remove-HVApplication -ApplicationName 'App1' -HvServer $HvServer + Removes 'App1', if exists. + +.OUTPUTS + Removes the specified application if exists. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.2 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [string]$ApplicationName, + + [Parameter(Mandatory = $False)] + $HvServer = $null + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve View API services from connection object" + break + } + } + process { + $App= Get-HVApplication -ApplicationName $ApplicationName -HvServer $HvServer + if (!$App) { + Write-Host "Application '$ApplicationName' not found. $_" + return + } + $AppService= New-Object VMware.Hv.ApplicationService + $AppService.Application_Delete($services,$App.Id) + if ($?) { + Write-Host "'$ApplicationName' has been successfully removed." + } + } + end { + [System.GC]::Collect() + } +} + +Function New-HVManualApplication { +<# +.Synopsis + Creates a Manual Application. + +.DESCRIPTION + Creates Application manually with given parameters. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.PARAMETER Name + The Application name is the unique identifier used to identify this Application. + +.PARAMETER DisplayName + The display name is the name that users will see when they connect to view client. If the display name is left blank, it defaults to Name. + +.PARAMETER Description + The description is a set of notes about the Application. + +.PARAMETER ExecutablePath + Path to Application executable. + +.PARAMETER Version + Application version. + +.PARAMETER Publisher + Application publisher. + +.PARAMETER Enabled + Indicates if Application is enabled. + +.PARAMETER EnablePreLaunch + Application can be pre-launched if value is true. + +.PARAMETER ConnectionServerRestrictions + Connection server restrictions. This is a list of tags that access to the application is restricted to. Empty/Null list means that the application can be accessed from any connection server. + +.PARAMETER CategoryFolderName + Name of the category folder in the user's OS containing a shortcut to the application. Unset if the application does not belong to a category. + +.PARAMETER ClientRestrictions + Client restrictions to be applied to Application. Currently it is valid for RDSH pools. + +.PARAMETER ShortcutLocations + Locations of the category folder in the user's OS containing a shortcut to the desktop. The value must be set if categoryFolderName is provided. + +.PARAMETER MultiSessionMode + Multi-session mode for the application. An application launched in multi-session mode does not support reconnect behavior when user logs in from a different client instance. + +.PARAMETER MaxMultiSessions + Maximum number of multi-sessions a user can have in this application pool. + +.PARAMETER StartFolder + Starting folder for Application. + +.PARAMETER Args + Parameters to pass to application when launching. + +.PARAMETER Farm + Farm name. + +.PARAMETER AutoUpdateFileTypes + Whether or not the file types supported by this application should be allowed to automatically update to reflect changes reported by the agent. + +.PARAMETER AutoUpdateOtherFileTypes + Whether or not the other file types supported by this application should be allowed to automatically update to reflect changes reported by the agent. + +.EXAMPLE + New-HVManualApplication -Name 'App1' -DisplayName 'DisplayName' -Description 'ApplicationDescription' -ExecutablePath "PathOfTheExecutable" -Version 'AppVersion' -Publisher 'PublisherName' -Farm 'FarmName' + Creates a manual application App1 in the farm specified. + +.OUTPUTS + A success message is displayed when done. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [VMware.VimAutomation.HorizonView.Impl.V1.ViewServerImpl]$HvServer, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [string][ValidateLength(1,64)]$Name, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String][ValidateLength(1,256)]$DisplayName = $Name, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String][ValidateLength(1,1024)]$Description, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String]$ExecutablePath, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$Version, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$Publisher, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$Enabled = $True, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$EnablePreLaunch=$False, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [string[]]$ConnectionServerRestrictions, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True, ParameterSetName = 'categoryFolderName')] + [String][ValidateRange(1,64)]$CategoryFolderName, + + #Below Parameter is for Client restrictions to be applied to Application. Currently it is valid for RDSH pools. + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$clientRestrictions = $False, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True, ParameterSetName = 'categoryFolderName')] + [String[]]$ShortcutLocations, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [ValidateSet('DISABLED','ENABLED_DEFAULT_OFF','ENABLED_DEFAULT_ON','ENABLED_ENFORCED')] + [String]$MultiSessionMode = 'DISABLED', + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [ValidateScript({if(($MultiSessionMode -eq 'ENABLED_DEFAULT_OFF') -or ($MultiSessionMode -eq 'ENABLED_DEFAULT_ON') -or ($MultiSessionMode -eq 'ENABLED_ENFORCED')){$_ -eq 1}})] + [Int]$MaxMultiSessions, + + #Below parameters are for ExecutionData, moved ExecutablePath, Version and Publisher to above from this. + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$StartFolder, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String]$Args, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String]$Farm, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$AutoUpdateFileTypes = $True, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$AutoUpdateOtherFileTypes = $True + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve View API services from connection object" + break + } + $FarmInfo = Get-HVFarm -FarmName $Farm + if ($null -eq $FarmInfo) { + Write-Error "Could not find the specified Farm." + break + } + } + process { + $App = Get-HVApplication -ApplicationName $Name -HvServer $HvServer + if ($App) { + Write-Host "Application already exists with the name : $Name" + return + } + $AppData = New-Object VMware.Hv.ApplicationData -Property @{ 'Name' = $Name; 'DisplayName' = $DisplayName; 'Description' = $Description; 'Enabled' = $Enabled; 'EnableAntiAffinityRules' = $EnableAntiAffinityRules; 'AntiAffinityPatterns' = $AntiAffinityPatterns; 'AntiAffinityCount' = $AntiAffinityCount; 'EnablePreLaunch' = $EnablePreLaunch; 'multiSessionMode' = $MultiSessionMode; 'maxMultiSessions' = $MaxMultiSessions; 'ConnectionServerRestrictions' = $ConnectionServerRestrictions; 'CategoryFolderName' = $CategoryFolderName; 'ClientRestrictions' = $ClientRestrictions; 'ShortcutLocations' = $ShortcutLocations} + $ExecutionData = New-object VMware.Hv.ApplicationExecutionData -Property @{ 'ExecutablePath' = $ExecutablePath; 'Version' = $Version; 'Publisher' = $Publisher; 'StartFolder' = $StartFolder; 'Args' = $Args; 'Farm' = $FarmInfo.id; 'AutoUpdateFileTypes' = $AutoUpdateFileTypes; 'AutoUpdateOtherFileTypes' = $AutoUpdateOtherFileTypes} + $AppSpec = New-Object VMware.Hv.ApplicationSpec -Property @{ 'Data' = $AppData; 'ExecutionData' = $ExecutionData} + $AppService = New-Object VMware.Hv.ApplicationService + $AppService.Application_Create($services,$AppSpec) + if ($?) { + Write-Host "Application '$Name' created successfully" + return + } + Write-Host "Application creation of '$Name' has failed. $_" + } + end { + [System.GC]::Collect() + } +} + +Function Get-HVPreInstalledApplication { +<# +.Synopsis + Gets the list of Pre-installed Applications from the RDS Server(s). + +.DESCRIPTION + Gets the list of Pre-installed Applications from the RDS Server(s). + +.PARAMETER FarmName + Name of the Farm on which to discover installed applications. + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.EXAMPLE + Get-HVPreInstalledApplication -FarmName 'Farm1' -HvServer $HvServer + Gets the list of Applications present in 'Farm1', if exists. + +.OUTPUTS + Gets the list of Applications from the specified Farm if exists. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String][ValidateLength(1,64)]$FarmName, + + [Parameter(Mandatory = $False)] + $HvServer = $null + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + $Farm = Get-HVFarm -FarmName $FarmName + if($null -eq $Farm) { + Write-Error "Could not find the specified Farm." + break + } + } + process { + $FarmService = New-Object VMware.Hv.FarmService + $Data = $FarmService.Farm_DiscoverInstalledApplications($services,$Farm.Id) + return $Data + } + end { + [System.GC]::Collect() + } +} + +Function New-HVPreInstalledApplication { +<# +.Synopsis + Creates a application pool from Pre-installed applications on RDS Server(s). + +.DESCRIPTION + Creates a application pool from Pre-installed applications on RDS Server(s). + +.PARAMETER HvServer + View API service object of Connect-HVServer cmdlet. + +.PARAMETER ApplicationName + The Application name is the unique identifier used to identify this Application. + +.PARAMETER DisplayName + The display name is the name that users will see when they connect to view client. If the display name is left blank, it defaults to Name. + +.PARAMETER FarmName + Farm name. + +.PARAMETER EnablePreLaunch + Application can be pre-launched if value is true. + +.PARAMETER ConnectionServerRestrictions + Connection server restrictions. This is a list of tags that access to the application is restricted to. Empty/Null list means that the application can be accessed from any connection server. + +.PARAMETER CategoryFolderName + Name of the category folder in the user's OS containing a shortcut to the application. Unset if the application does not belong to a category. + +.PARAMETER ClientRestrictions + Client restrictions to be applied to Application. Currently it is valid for RDSH pools. + +.EXAMPLE + New-HVPreInstalledApplication -ApplicationName 'App1' -DisplayName 'DisplayName' -FarmName 'FarmName' + Creates a application App1 from the farm specified. + +.EXAMPLE + New-HVPreInstalledApplication -ApplicationName 'App2' -FarmName FarmManual -EnablePreLaunch $True + Creates a application App2 from the farm specified and the PreLaunch option will be enabled. + +.OUTPUTS + A success message is displayed when done. + +.NOTES + Author : Samiullasha S + Author email : ssami@vmware.com + Version : 1.0 + + ===Tested Against Environment==== + Horizon View Server Version : 7.8.0 + PowerCLI Version : PowerCLI 11.1 + PowerShell Version : 5.0 +#> + param ( + [Parameter(Mandatory = $False)] + $HvServer = $null, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [string][ValidateLength(1,64)]$ApplicationName, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [String][ValidateLength(1,256)]$DisplayName = $ApplicationName, + + [Parameter(Mandatory = $True, ValueFromPipeline = $True)] + [String][ValidateLength(1,64)]$FarmName, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$EnablePreLaunch=$False, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [string[]]$ConnectionServerRestrictions, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True,ParameterSetName = 'categoryFolderName')] + [String][ValidateRange(1,64)]$CategoryFolderName, + + [Parameter(Mandatory = $False, ValueFromPipeline = $True)] + [Boolean]$clientRestrictions = $False + ) + begin { + $services = Get-ViewAPIService -HvServer $HvServer + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + $FarmInfo = Get-HVFarm -FarmName $FarmName + if($null -eq $FarmInfo) { + Write-Error "Could not find the specified Farm $FarmName." + break + } + } + process { + #Validate the Application name uniqueness with existing applications. + $ResourceObjs = Get-HVApplication -HvServer $HvServer + foreach($App in ($ResourceObjs.name)) { + if($App -eq $ApplicationName) { + Write-Host "$ApplicationName already exists in the Application Pool." + return + } + } + #Validate the application name uniqueness with Desktops. + $DesktopSummary = Get-HVQueryResult -EntityType DesktopSummaryView -HvServer $hvserver + foreach($App in $DesktopSummary) { + if($App.DesktopSummaryData.Name -eq $ApplicationName) { + Write-Host "$ApplicationName already exists in the Desktop Pool." + return + } + } + #get all the applications installed in RDS Server(s). + $AppsInRDS = Get-HVPreinstalledApplication -FarmName $FarmName + $AppFoundInRDS = $False + foreach($App in ($AppsInRDS)) { + if($($App.name) -eq ($ApplicationName)) { + $AppFoundInRDS = $True + $ApplicationID = $ApplicationName -replace " ","_" + $ApplicationData = New-Object VMware.Hv.ApplicationData -Property @{ 'Name' = $ApplicationID; + 'DisplayName' = $DisplayName; + 'EnablePreLaunch' = $EnablePreLaunch; + 'ConnectionServerRestrictions' = $ConnectionServerRestrictions; + 'CategoryFolderName' = $CategoryFolderName; + 'ClientRestrictions' = $ClientRestrictions } + $ExecutionData = New-object VMware.Hv.ApplicationExecutionData -Property @{ 'ExecutablePath' = $App.ExecutionData.ExecutablePath; + 'Version' = $App.ExecutionData.Version; + 'Publisher' = $App.ExecutionData.Publisher; + 'Args' = $App.ExecutionData.Args; + 'StartFolder' = $App.ExecutionData.StartFolder; + 'Farm' = $FarmInfo.Id; + 'AutoUpdateFileTypes' = $App.ExecutionData.AutoUpdateFileTypes; + 'AutoUpdateOtherFileTypes' = $App.executionData.AutoUpdateOtherFileTypes } + $ApplicationSpec = New-Object VMware.Hv.ApplicationSpec -Property @{ 'Data' = $ApplicationData; 'ExecutionData' = $ExecutionData} + $AppService = New-Object VMware.Hv.ApplicationService + $AppService.Application_Create($services,$ApplicationSpec) + if($?) { + Write-Host "Application '$ApplicationName' created successfully" + return + } + Write-Host "Failed to create Application '$ApplicationName'. $_ " + return + } + } + if ($AppFoundInRDS -eq $False) { + Write-Host ""$ApplicationName" does not exist in any of the RDS Server(s) belongs to the Farm $FarmName." + } + } + end { + [System.GC]::Collect() + } +} + # Object related Export-ModuleMember -Function Get-HVMachine, Get-HVMachineSummary, Get-HVQueryResult, Get-HVQueryFilter, Get-HVInternalName # RDS Farm related Export-ModuleMember -Function Get-HVFarmSummary, Start-HVFarm, Start-HVPool, New-HVFarm, Remove-HVFarm, Get-HVFarm, Set-HVFarm, Add-HVRDSServer # Desktop Pool related Export-ModuleMember -Function Get-HVPoolSummary, New-HVPool, Remove-HVPool, Get-HVPool, Set-HVPool, Get-HVPoolSpec, Add-HVDesktop +# Application Pool related +Export-ModuleMember -Function Get-HVApplication, Remove-HVApplication, New-HVManualApplication, Get-HVPreInstalledApplication, New-HVPreInstalledApplication # Entitlement related Export-ModuleMember -Function New-HVEntitlement,Get-HVEntitlement,Remove-HVEntitlement Export-ModuleMember -Function Set-HVMachine, Reset-HVMachine, Remove-HVMachine @@ -11966,4 +12496,4 @@ Export-ModuleMember -Function Get-HVEventDatabase, Set-HVEventDatabase, Clear-HV # vCenter Server related Export-ModuleMember -Function Get-HVvCenterServer, Get-HVvCenterServerHealth # Misc/other related -Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance, Get-HVBaseImageVM, Get-HVBaseImageVMSnapshot \ No newline at end of file +Export-ModuleMember -Function Get-HVlicense, Set-HVlicense, Get-HVHealth, Set-HVInstantCloneMaintenance, Get-HVBaseImageVM, Get-HVBaseImageVMSnapshot From e8fdf541d4049497bc1c2eca1403981c2c653fbe Mon Sep 17 00:00:00 2001 From: Mark McGilly Date: Thu, 9 May 2019 04:49:39 -0400 Subject: [PATCH 24/28] Added Get-HcxLicense function Added parameter to set Proxy Exclusions in Set-HcxProxy Added ability to return UserName from Get-HcxNSXConfig Added ability to return UserName, LookupServiceURL from Get-HcxVCConfig --- Modules/VMware.HCX/VMware.HCX.psd1 | 2 +- Modules/VMware.HCX/VMware.HCX.psm1 | 42 +++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 index a5e74f0..3b3f3b0 100644 --- a/Modules/VMware.HCX/VMware.HCX.psd1 +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VM PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy' +FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy', 'Get-HcxLicense' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index 5582681..6ba3e8a 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -570,16 +570,22 @@ Function Get-HcxVCConfig { #> If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { $vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter" + $pscConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/lookupservice" if($PSVersionTable.PSEdition -eq "Core") { $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + $ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck } else { $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + $ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing } $vcData = ($vcRequests.content | ConvertFrom-Json).data.items + $ssoData = ($ssoRequests.content | ConvertFrom-Json).data.items $tmp = [pscustomobject] @{ Name = $vcData.config.name; + UserName = $vcData.Config.userName + LookupServiceUrl = $ssoData.config.lookupServiceUrl Version = $vcData.config.version; Build = $vcData.config.buildNumber; UUID = $vcData.config.vcuuid; @@ -589,6 +595,38 @@ Function Get-HcxVCConfig { } } +Function Get-HcxLicense { + <# + .NOTES + =========================================================================== + Created by: Mark McGilly + Date: 4/29/2019 + Organization: Liberty Mutual Insurance + =========================================================================== + + .SYNOPSIS + Returns the license key that is registered with HCX Manager + .DESCRIPTION + This cmdlet returns the license key registered with HCX Manager + .EXAMPLE + Get-HcxLicense + #> + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $hcxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/hcx" + + if($PSVersionTable.PSEdition -eq "Core") { + $licenseRequests = Invoke-WebRequest -Uri $hcxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $licenseRequests = Invoke-WebRequest -Uri $hcxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $license = ($licenseRequests.content | ConvertFrom-Json).data.items + if($licenseRequests) { + $license.config.activationKey + } + } +} + Function Set-HcxLicense { <# .NOTES @@ -800,6 +838,7 @@ Function Get-HcxNSXConfig { $tmp = [pscustomobject] @{ Name = $nsxData.config.url; + UserName = $nsxData.config.userName Version = $nsxData.config.version; HCXUUID = $nsxData.config.uuid; } @@ -1211,6 +1250,7 @@ Function Set-HcxProxy { [Parameter(Mandatory=$True)]$ProxyPort, [Parameter(Mandatory=$False)]$ProxyUser, [Parameter(Mandatory=$False)]$ProxyPassword, + [Parameter(Mandatory=$False)]$ProxyExclusions, [Switch]$Troubleshoot ) @@ -1225,7 +1265,7 @@ Function Set-HcxProxy { config = @{ proxyHost = "$ProxyServer"; proxyPort = "$ProxyPort"; - nonProxyHosts = ""; + nonProxyHosts = "$ProxyExclusions"; userName = "$ProxyUser"; password = "$ProxyPassword"; } From 0576034d74146d3e2f4547b6d4b1b7372894986e Mon Sep 17 00:00:00 2001 From: Mark McGilly Date: Thu, 9 May 2019 04:57:23 -0400 Subject: [PATCH 25/28] Fix tabs instead of spaces --- Modules/VMware.HCX/VMware.HCX.psm1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index 6ba3e8a..b8f8866 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -570,7 +570,7 @@ Function Get-HcxVCConfig { #> If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { $vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter" - $pscConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/lookupservice" + $pscConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/lookupservice" if($PSVersionTable.PSEdition -eq "Core") { $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck @@ -580,12 +580,12 @@ Function Get-HcxVCConfig { $ssoRequests = Invoke-WebRequest -Uri $pscConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing } $vcData = ($vcRequests.content | ConvertFrom-Json).data.items - $ssoData = ($ssoRequests.content | ConvertFrom-Json).data.items + $ssoData = ($ssoRequests.content | ConvertFrom-Json).data.items $tmp = [pscustomobject] @{ Name = $vcData.config.name; - UserName = $vcData.Config.userName - LookupServiceUrl = $ssoData.config.lookupServiceUrl + UserName = $vcData.Config.userName + LookupServiceUrl = $ssoData.config.lookupServiceUrl Version = $vcData.config.version; Build = $vcData.config.buildNumber; UUID = $vcData.config.vcuuid; @@ -838,7 +838,7 @@ Function Get-HcxNSXConfig { $tmp = [pscustomobject] @{ Name = $nsxData.config.url; - UserName = $nsxData.config.userName + UserName = $nsxData.config.userName Version = $nsxData.config.version; HCXUUID = $nsxData.config.uuid; } @@ -1250,7 +1250,7 @@ Function Set-HcxProxy { [Parameter(Mandatory=$True)]$ProxyPort, [Parameter(Mandatory=$False)]$ProxyUser, [Parameter(Mandatory=$False)]$ProxyPassword, - [Parameter(Mandatory=$False)]$ProxyExclusions, + [Parameter(Mandatory=$False)]$ProxyExclusions, [Switch]$Troubleshoot ) From 5f1a86e78ba5351d3b3128dcd2ca0ed81503549a Mon Sep 17 00:00:00 2001 From: William Lam Date: Thu, 9 May 2019 06:50:22 -0700 Subject: [PATCH 26/28] Added Get/New/Remove functions for Policy Based VPN --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 8 +- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 297 ++++++++++++++++++- 2 files changed, 296 insertions(+), 9 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index c18be71..3f6f507 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -36,7 +36,13 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', 'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN', 'Remove-NSXTService', 'New-NSXTDistFirewallSection', 'Get-NSXTDistFirewallSection' +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', ` +'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', ` +'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall', 'Get-NSXTDistFirewallSection', ` +'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', ` +'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', ` +'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN', 'Remove-NSXTService', 'New-NSXTDistFirewallSection', 'Get-NSXTDistFirewallSection', ` +'New-NSXTPolicyBasedVPN', 'Get-NSXTPolicyBasedVPN', 'Remove-NSXTPolicyBasedVPN' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index f3ea7e6..0a7b5bd 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -2089,20 +2089,32 @@ Function Get-NSXTRouteBasedVPN { if($requests.StatusCode -eq 200) { $groups = ($requests.Content | ConvertFrom-Json).results - if ($PSBoundParameters.ContainsKey("Name")){ $groups = $groups | where {$_.display_name -eq $Name} } $results = @() foreach ($group in $groups) { - $tmp = [pscustomobject] @{ - Name = $group.display_name; - ID = $group.id; - Path = $group.path; - RoutingConfigPath = $group.l3vpn_session.routing_config_path; + if($group.l3vpn_session.resource_type -eq "RouteBasedL3VpnSession") { + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Path = $group.path; + Routing_Config_Path = $group.l3vpn_session.routing_config_path; + Local_IP = $group.local_address; + Remote_Public_IP = $group.remote_public_address; + Tunnel_IP_Address = $group.l3vpn_session.tunnel_subnets.ip_addresses + IKE_Version = $group.ike_version; + IKE_Encryption = $group.ike_encryption_algorithms; + IKE_Digest = $group.ike_digest_algorithms; + Tunnel_Encryption = $group.tunnel_encryption_algorithms; + Tunnel_Digest = $group.tunnel_digest_algorithms; + DH_Group = $group.dh_groups; + Created_by = $group._create_user; + Last_Modified_by = $group._last_modified_user; + } + $results+=$tmp } - $results+=$tmp } $results } @@ -2194,4 +2206,273 @@ Function Remove-NSXTRouteBasedVPN { Write-Host "Successfully removed NSX-T BGP Neighbor" } } -} \ No newline at end of file +} + +Function New-NSXTPolicyBasedVPN { +<# +.NOTES +=========================================================================== +Created by: William Lam +Date: 05/09/2019 +Organization: VMware +Blog: http://www.virtuallyghetto.com +Twitter: @lamw +=========================================================================== + +.SYNOPSIS + Creates a new NSX-T Policy Based VPN +.DESCRIPTION + This cmdlet creates a new NSX-T Policy Based VPN +.EXAMPLE + New-NSXTPolicyBasedVPN -Name Policy1 ` + -LocalIP 18.194.102.229 ` + -RemotePublicIP 3.122.124.16 ` + -RemotePrivateIP 169.254.90.1 ` + -SequenceNumber 0 ` + -SourceIPs @("192.168.4.0/24", "192.168.5.0/24") ` + -DestinationIPs @("172.204.10.0/24", "172.204.20.0/24") ` + -TunnelEncryption AES_256 ` + -TunnelDigestEncryption SHA2_256 ` + -IKEEncryption AES_256 ` + -IKEDigestEncryption SHA2_256 ` + -DHGroup GROUP14 ` + -IKEVersion IKE_V1 ` + -PresharedPassword VMware123. ` + -Troubleshoot +#> + param( + [Parameter(Mandatory=$true)][String]$Name, + [Parameter(Mandatory=$true)][String]$LocalIP, + [Parameter(Mandatory=$true)][String]$RemotePublicIP, + [Parameter(Mandatory=$true)][String]$RemotePrivateIP, + [Parameter(Mandatory=$True)]$SequenceNumber, + [Parameter(Mandatory=$true)][String[]]$SourceIPs, + [Parameter(Mandatory=$true)][String[]]$DestinationIPs, + [Parameter(Mandatory=$true)][String][ValidateSet("AES_128","AES_256","AES_GCM_128","AES_GCM_192","AES_GCM_256")]$TunnelEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("SHA1","SHA2_256")]$TunnelDigestEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("AES_128","AES_256","AES_GCM_128","AES_GCM_192","AES_GCM_256")]$IKEEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("SHA1","SHA2_256")]$IKEDigestEncryption, + [Parameter(Mandatory=$true)][String][ValidateSet("GROUP2","GROUP5","GROUP14","GROUP15","GROUP16")]$DHGroup, + [Parameter(Mandatory=$true)][String][ValidateSet("IKE_V1","IKE_V2","IKE_FLEX")]$IKEVersion, + [Parameter(Mandatory=$true)][String]$PresharedPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + + $generatedId = (New-Guid).Guid + + $sources = @() + foreach ($source in $SourceIPs) { + $tmp = @{ subnet = $source} + $sources+=$tmp + } + + $destinations = @() + foreach ($destination in $DestinationIPs) { + $tmp = @{ subnet = $destination} + $destinations+=$tmp + } + + $payload = @{ + display_name = $Name; + enabled = $true; + local_address = $LocalIP; + remote_private_address = $RemotePrivateIP; + remote_public_address = $RemotePublicIP; + passphrases = @("$PresharedPassword"); + tunnel_digest_algorithms = @("$TunnelDigestEncryption"); + tunnel_encryption_algorithms = @("$TunnelEncryption"); + ike_digest_algorithms = @("$IKEDigestEncryption"); + ike_encryption_algorithms = @("$IKEEncryption"); + enable_perfect_forward_secrecy = $true; + dh_groups = @("$DHGroup"); + ike_version = $IKEVersion; + + l3vpn_session = @{ + resource_type = "PolicyBasedL3VpnSession"; + rules = @( + @{ + id = $generatedId; + display_name = $generatedId; + sequence_number = $SequenceNumber; + sources = @($sources) + destinations = @($destinations) + } + ) + } + } + $body = $payload | ConvertTo-Json -Depth 5 + + $method = "put" + $policyBasedVPNURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/l3vpns/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$policyBasedVPNURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $policyBasedVPNURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $policyBasedVPNURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in configuring Policy Based VPN" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Successfully created Policy Based VPN" + ($requests.Content | ConvertFrom-Json) + } + } +} + +Function Get-NSXTPolicyBasedVPN { +<# +.NOTES +=========================================================================== +Created by: William Lam +Date: 05/09/2019 +Organization: VMware +Blog: http://www.virtuallyghetto.com +Twitter: @lamw +=========================================================================== + +.SYNOPSIS + Returns all NSX-T Policy Based VPN Tunnels +.DESCRIPTION + This cmdlet retrieves all NSX-T Policy Based VPN Tunnels description +.EXAMPLE + Get-NSXTPolicyBasedVPN +.EXAMPLE + Get-NSXTPolicyBasedVPN -Name "VPN-T1" +#> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $policyBaseVPNURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/l3vpns" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$routeBaseVPNURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $policyBaseVPNURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $policyBaseVPNURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T Policy Based VPN Tunnels" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $groups = ($requests.Content | ConvertFrom-Json).results + if ($PSBoundParameters.ContainsKey("Name")){ + $groups = $groups | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($group in $groups) { + if($group.l3vpn_session.resource_type -eq "PolicyBasedL3VpnSession") { + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Path = $group.path; + Local_IP = $group.local_address; + Remote_Public_IP = $group.remote_public_address; + Tunnel_IP_Address = $group.remote_private_address; + IKE_Version = $group.ike_version; + IKE_Encryption = $group.ike_encryption_algorithms; + IKE_Digest = $group.ike_digest_algorithms; + Tunnel_Encryption = $group.tunnel_encryption_algorithms; + Tunnel_Digest = $group.tunnel_digest_algorithms; + DH_Group = $group.dh_groups; + IP_Sources = $group.l3vpn_session.rules.sources.subnet; + IP_Destinations = $group.l3vpn_session.rules.destinations.subnet + Created_by = $group._create_user; + Last_Modified_by = $group._last_modified_user; + } + $results+=$tmp + } + } + $results + } + } +} + +Function Remove-NSXTPolicyBasedVPN { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 05/09/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes a policy based VPN Tunnel + .DESCRIPTION + This cmdlet removes a policy based VPN Tunnel + .EXAMPLE + Remove-NSXTPolicyBasedVPN -Name "Policy1" -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $TunnelId = (Get-NSXTPolicyBasedVPN -Name $Name).ID + + # Delete IPSEC tunnel + $method = "DELETE" + $deleteVPNtunnelURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-0s/vmc/locale-services/default/l3vpns/$TunnelId" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteVPNtunnelURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteVPNtunnelURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteVPNtunnelURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in removing NSX-T VPN Tunnel: $Name" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Successfully removed NSX-T VPN Tunnel: $Name" + } + } +} From 2a5eff4fd1195164fef8c1fd461afc808946d910 Mon Sep 17 00:00:00 2001 From: William Lam Date: Tue, 28 May 2019 06:20:26 -0700 Subject: [PATCH 27/28] Adding DRaaS Module + VMC module typo fix --- Modules/VMware.DRaaS/VMware.DRaaS.psd1 | Bin 0 -> 7718 bytes Modules/VMware.DRaaS/VMware.DRaaS.psm1 | 256 +++++++++++++++++++++++++ Modules/VMware.VMC/VMware.VMC.psm1 | 7 +- 3 files changed, 260 insertions(+), 3 deletions(-) create mode 100755 Modules/VMware.DRaaS/VMware.DRaaS.psd1 create mode 100644 Modules/VMware.DRaaS/VMware.DRaaS.psm1 diff --git a/Modules/VMware.DRaaS/VMware.DRaaS.psd1 b/Modules/VMware.DRaaS/VMware.DRaaS.psd1 new file mode 100755 index 0000000000000000000000000000000000000000..fd5ab0692124655225f62337b7c4fa3c07651ab6 GIT binary patch literal 7718 zcmeI1Yfl?T6o%(BzhWgm098XmN|L5hr63y;Btj98v|oLtZt$hHfkajQdfWGz<6&mJ zYiv-WR#j!;_3qA`%X{v_Uw^K**%jkRW~Yg;s$?vwjL*Bfzbh}SE3t?x*sC0_j{ zG=`!IjVJDzd+eV2?;ZDYwrfo^|Ilxf;mozfzvo6?lYXYDY1P!*f!E?wNyo0<87d87 zG12apo zSthg9HLdGwH5m0I8R%85E*uqB z&W(Q>!#UTH_z^i5(vB=ZE-=sU&(M#VVG;iDo~L7cH-+q$s6G{@#BMQ{O$wm}E=3{( z(M7JoKgP-%c*%BRi@JXo<2^)4vR*dE znvN%;b>n3{6NY#%`lL}95qv8-kmW+W2l~$OC=_qR8uFj&yXB<>1>#{-aTBt}R)WV{ zPpc=tB1;q=v9Zvr#syCt2vKAP>1yeTJChMvum+LY^S_qkRYkKp6Yb7rq3E}{HCL0G z__SJfUy0WjAn|5KG0J5&k1_N$(EoaRR9oS`+MqM>2in+)ys_<$RV&W*>p*YFavgaX zdF;czJ!o4y&TlI%(Mk*iAH=gQMywKFiyN60zYIMLnF`OX^29=MM0WWgD&(y~cWI5I z!VX07lXSA$Sl5%O^y}!mtlgKvG)PR$_w}*LPxnM5Ug>(_H5&W8Mok1^vO-POR=kvAU3hu{|}Hu9CipUvzu)Ky+DX8G16Zw{=XxV=m;YL#-zY z@a2K8Y@jsoKEnD!RH*WXm+en!hiU}P(BDQGP2*G1POCs#;m`st^GiL04wJ`{gCBmZvOtK23z_0NFQ{6X@4>yx&B-*>psuq>sgJds01MkO7uz2=AA#p0fs#4F#OF0V3WZ=#;O%|{?pcaI=ows>sl)j~V$BIm^pkn*Y z7f-csel~rab*W`fvAC!11!?AWD96r$kAT>BBe7}PaUUg}Ptvbe=N$5NsOET^ zWks|b&z{=}29c-YKp z6o_HG+$IXB)AiWg8s>BBTC6@1TS$jiRvC)2pqtzBBuz@~S{T|&;3KQiU zB;U}CjBZtL&MMxRp&wGrBruzHSRHR`$5>ze&*ic~sx`dT_z>vA8KKP`gm zqSf+e2|3MGBs!88Sk|?QgXWi#Fs(TF2d987O;a|ZkXgyPWY9&q-DFE^N#s?oDDhn` zM_TtED#L*!CF@5XW&U(eJ@wRfDn{MlSHo*ZK8H86NU&3=9Vt#)=L6jlbB@l2QV|LW@t$np$nRNT&jDGfF_YgowidvP6nbU=hg%p zB8yW*s=U>GdS7sdE48?gEEYAavH1u6gT&#QOP+gRSQDtLE~6f4E|Y z#kBCOjaj7+J3i|fyY__yx!d^VQCH3t{MTsF&NN%b*si7l=Qm#Wk^X}-@SVN+_TjB8 z)yP{7ncquPurt*Z9-R1fT|-s%QpnnA2v2(IrQ@7|7jX7w69VX`GmA}A%jOnx$xpMa z020g + Param ( + [Parameter(Mandatory=$true)][String]$RefreshToken, + [Parameter(Mandatory=$true)][String]$OrgName, + [Parameter(Mandatory=$true)][String]$SDDCName + ) + + If (-Not $global:DefaultVMCServers.IsConnected) { Write-error "No valid VMC Connection found, please use the Connect-VMC to connect"; break } Else { + $sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs" + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $sddc = $sddcService.get($orgId,$sddcId) + + } + + $results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$RefreshToken" -Method POST -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$RefreshToken"} + if($results.StatusCode -ne 200) { + Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again" + break + } + $accessToken = ($results | ConvertFrom-Json).access_token + + $headers = @{ + "csp-auth-token"="$accessToken" + "Content-Type"="application/json" + "Accept"="application/json" + } + $global:draasConnection = new-object PSObject -Property @{ + 'Server' = "https://vmc.vmware.com/vmc/draas/api/orgs/$orgId/sddcs/$sddcId/site-recovery" + 'headers' = $headers + } + $global:draasConnection +} + +Function Get-DRaas { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 05/23/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns information about DRaaS configuration for a given SDDC + .DESCRIPTION + This cmdlet returns information about DRaaS configuration for a given SDDC. Can be used to monitor both activate and deactivate operations. + .EXAMPLE + Get-DRaas +#> + Param ( + [Switch]$Troubleshoot + ) + + If (-Not $global:draasConnection) { Write-error "No DRaaS Connection found, please use Connect-DRaaS" } Else { + $method = "GET" + $draasUrl = $global:draasConnection.Server + $draasVersionUrl = $global:draasConnection.Server + "/versions" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving DRaaS Information" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $json = ($requests.Content | ConvertFrom-Json) + + $draasId = $json.id; + $draasState = $json.site_recovery_state; + $srmNode = $json.srm_node.ip_address; + $srmNodeState = $json.site_recovery_state; + $vrNode = $json.vr_node.ip_address; + $vrNodeState = $json.vr_node.state; + $draasUrl = $json.draas_h5_url; + + if($srmNodeState -eq "ACTIVATED") { + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasVersionUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $draasVersionUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $draasVersionUrl -Method $method -Headers $global:draasConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving DRaaS Information" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $json = ($requests.Content | ConvertFrom-Json).node_versions + + $srmVersion,$srmDescription = ($json | where {$_.node_ip -eq $srmNode}).full_version.split("`n") + $vrVersion,$vrDescription = ($json | where {$_.node_ip -eq $vrNode}).full_version.split("`n") + + $results = [pscustomobject] @{ + ID = $draasId; + DRaaSState = $draasState; + SRMNode = $srmNode; + SRMVersion = $srmVersion; + SRMNodeState = $srmNodeState; + VRNode = $vrNode; + VRVersion = $vrVersion; + VRNodeState = $vrNodeState; + DRaaSURL = $draasUrl; + } + + $results + } + } elseif ($srmNodeState -eq "ACTIVATING" -or $srmNodeState -eq "DEACTIVATING") { + $results = [pscustomobject] @{ + ID = $draasId; + DRaaSState = $draasState; + SRMNode = $srmNode; + SRMNodeState = $srmNodeState; + VRNode = $vrNode; + VRNodeState = $vrNodeState; + DRaaSURL = $draasUrl; + } + + $results + } else { + Write-Host "`nDRaaS is currently deactivated, please run Set-DRaas -Activate`n" + } + } else { + Write-Host "`nDRaaS has not been activated before, please run Set-DRaas -Activate`n" + } + } +} + + +Function Set-DRaas { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 05/23/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Activate or deactivate DRaaS for a given SDDC + .DESCRIPTION + This cmdlet activates or deactivates DRaaS for a given SDDC + .EXAMPLE + Get-DRaas +#> + Param ( + [Switch]$Activate, + [Switch]$Deactivate, + [Switch]$Troubleshoot + ) + + If (-Not $global:draasConnection) { Write-error "No DRaaS Connection found, please use Connect-DRaaS" } Else { + $draasUrl = $global:draasConnection.server + + if($Activate) { + $method = "POST" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in activating DRaaS" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + Write-Host "`nActivating DRaaS, this will take some time and you can monitor the progress using Get-DRaaS or using the VMC Console UI`n" + } elseif ($Deactivate) { + $method = "DELETE" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$draasUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $draasUrl -Method $method -Headers $global:draasConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe CSP session is no longer valid, please re-run the Connect-DRaaS cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in deactivating DRaaS" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + Write-Host "`nDeactivating DRaaS, this will take some time and you can monitor the progress using Get-DRaaS or the VMC Console UI`n" + } else { + Write-Error "Invalid Operation" + } + } +} \ No newline at end of file diff --git a/Modules/VMware.VMC/VMware.VMC.psm1 b/Modules/VMware.VMC/VMware.VMC.psm1 index 33f78a7..63ad087 100644 --- a/Modules/VMware.VMC/VMware.VMC.psm1 +++ b/Modules/VMware.VMC/VMware.VMC.psm1 @@ -874,8 +874,8 @@ Function Get-VMCSDDCSummary { Get-VMCSDDCSummary -Name -Org #> Param ( - [Parameter(Mandatory=$True)]$OrgName, - [Parameter(Mandatory=$True)]$SDDCName + [Parameter(Mandatory=$True)]$Org, + [Parameter(Mandatory=$True)]$Name ) If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { @@ -895,6 +895,7 @@ Function Get-VMCSDDCSummary { InstanceType = $sddc.resource_config.sddc_manifest.esx_ami.instance_type; VpcCIDR = $sddc.resource_config.vpc_info.vpc_cidr; NSXT = $sddc.resource_config.nsxt; + VPC_VGW = $sddc.resource_config.vpc_info.vgw_id; } $results } @@ -903,7 +904,7 @@ Function Get-VMCPublicIP { <# .NOTES =========================================================================== - Created by: William Lam + Created by: William LamVPC_VGW Date: 09/12/2018 Organization: VMware Blog: http://www.virtuallyghetto.com From 5f3f41ff449c9f7d5e3e5dcb7235887640dd9231 Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 8 Jun 2019 13:13:19 -0700 Subject: [PATCH 28/28] Added Get/Set NSX-T DNS Zone Configuration --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 2 +- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 129 ++++++++++++++++++- 2 files changed, 129 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index 3f6f507..1b97cd3 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -42,7 +42,7 @@ FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', ' 'Get-NSXTDistFirewall', 'New-NSXTDistFirewall', 'Remove-NSXTDistFirewall', 'Get-NSXTRouteTable', ` 'Get-NSXTOverviewInfo', 'Get-NSXTInfraScope', 'Get-NSXTInfraGroup', 'New-NSXTRouteBasedVPN', ` 'Get-NSXTRouteBasedVPN', 'Remove-NSXTRouteBasedVPN', 'Remove-NSXTService', 'New-NSXTDistFirewallSection', 'Get-NSXTDistFirewallSection', ` -'New-NSXTPolicyBasedVPN', 'Get-NSXTPolicyBasedVPN', 'Remove-NSXTPolicyBasedVPN' +'New-NSXTPolicyBasedVPN', 'Get-NSXTPolicyBasedVPN', 'Remove-NSXTPolicyBasedVPN', 'Get-NSXTDNS', 'Set-NSXTDNS' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 0a7b5bd..5004034 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -2334,7 +2334,7 @@ Twitter: @lamw } } } - + Function Get-NSXTPolicyBasedVPN { <# .NOTES @@ -2476,3 +2476,130 @@ Function Remove-NSXTPolicyBasedVPN { } } } + +Function Get-NSXTDNS { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 06/08/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns DNS Zone configuration for MGW or CGW + .DESCRIPTION + This cmdlet retrieves DNS Zone configuration for MGW or CGW + .EXAMPLE + Get-NSXTDNS -GatewayType MGW + .EXAMPLE + Get-NSXTDNS -GatewayType CGW +#> + param( + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $dnsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/dns-forwarder-zones/$($GatewayType.toLower())-dns-zone" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$dnsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $dnsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $dnsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in retrieving NSX-T DNS Zones" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + $dnsZone = ($requests.Content | ConvertFrom-Json) + + $results = [pscustomobject] @{ + Name = $dnsZone.display_name; + DNS1 = $dnsZone.upstream_servers[0]; + DNS2 = $dnsZone.upstream_servers[1]; + Domain = $dnsZone.dns_domain_names; + } + $results + } + } +} + +Function Set-NSXTDNS { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 06/08/2019 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns DNS Zone configuration for MGW or CGW + .DESCRIPTION + This cmdlet retrieves DNS Zone configuration for MGW or CGW + .EXAMPLE + Set-NSXTDNS -GatewayType MGW -DNS @("192.168.1.14","192.168.1.15") + .EXAMPLE + Set-NSXTDNS -GatewayType CGW -DNS @("8.8.8.8") +#> + param( + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Parameter(Mandatory=$true)][String[]]$DNS, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "PATCH" + $dnsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/dns-forwarder-zones/$($GatewayType.toLower())-dns-zone" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$dnsURL`n" + } + + $payload = @{ + upstream_servers = @($DNS) + } + + $body = $payload | ConvertTo-Json -Depth 5 + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $dnsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $dnsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in updating NSX-T DNS Zones" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Successfully updated NSX-T DNS for $GatewayType" + } + } +} \ No newline at end of file