diff --git a/Modules/ContentLibrary/ContentLibrary.psm1 b/Modules/ContentLibrary/ContentLibrary.psm1 index e2fef41..318b999 100644 --- a/Modules/ContentLibrary/ContentLibrary.psm1 +++ b/Modules/ContentLibrary/ContentLibrary.psm1 @@ -2,10 +2,10 @@ <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function lists all available vSphere Content Libaries @@ -87,10 +87,10 @@ Function Get-ContentLibraryItems { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function lists all items within a given vSphere Content Library @@ -158,10 +158,10 @@ Function Get-ContentLibraryItemFiles { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function lists all item files within a given vSphere Content Library @@ -225,10 +225,10 @@ Function Set-ContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function updates the JSON Persistence property for a given Content Library @@ -281,10 +281,10 @@ Function New-ExtReplicatedContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function creates a new Subscriber Content Library from a JSON Persisted @@ -345,10 +345,10 @@ Function Remove-SubscribedContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function deletes a Subscriber Content Library @@ -387,10 +387,10 @@ Function New-LocalContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function creates a new Subscriber Content Library from a JSON Persisted @@ -444,10 +444,10 @@ Function Remove-LocalContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function deletes a Local Content Library @@ -486,10 +486,10 @@ Function Copy-ContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function copies all library items from one Content Library to another @@ -578,4 +578,122 @@ Function Copy-ContentLibrary { } } } +} + +Function New-VMTX { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function clones a VM to VM Template in Content Library (currently only supported on VMC) + .PARAMETER SourceVMName + The name of the source VM to clone + .PARAMETER VMTXName + The name of the VM Template in Content Library + .PARAMETER Description + Description of the VM template + .PARAMETER LibaryName + The name of the Content Library to clone to + .PARAMETER FolderName + The name of vSphere Folder (Defaults to Workloads for VMC) + .PARAMETER ResourcePoolName + The name of the vSphere Resource Pool (Defaults to Compute-ResourcePools for VMC) + .EXAMPLE + New-VMTX -SourceVMName "Windows10-BaseInstall" -VMTXName "Windows10-VMTX-Template" -LibraryName "VMC-CL-01" +#> + param( + [Parameter(Mandatory=$true)][String]$SourceVMName, + [Parameter(Mandatory=$true)][String]$VMTXName, + [Parameter(Mandatory=$false)][String]$Description, + [Parameter(Mandatory=$true)][String]$LibraryName, + [Parameter(Mandatory=$false)][String]$FolderName="Workloads", + [Parameter(Mandatory=$false)][String]$ResourcePoolName="Compute-ResourcePool" + ) + + $vmtxService = Get-CisService -Name "com.vmware.vcenter.vm_template.library_items" + + $sourceVMId = ((Get-VM -Name $SourceVMName).ExtensionData.MoRef).Value + $libraryId = ((Get-ContentLibrary -LibraryName $LibraryName).Id).Value + $folderId = ((Get-Folder -Name $FolderName).ExtensionData.MoRef).Value + $rpId = ((Get-ResourcePool -Name $ResourcePoolName).ExtensionData.MoRef).Value + + $vmtxCreateSpec = $vmtxService.Help.create.spec.Create() + $vmtxCreateSpec.source_vm = $sourceVMId + $vmtxCreateSpec.name = $VMTXName + $vmtxCreateSpec.description = $Description + $vmtxCreateSpec.library = $libraryId + $vmtxCreateSpec.placement.folder = $folderId + $vmtxCreateSpec.placement.resource_pool = $rpId + + Write-Host "`nCreating new VMTX Template from $SourceVMName in Content Library $LibraryName ..." + $result = $vmtxService.create($vmtxCreateSpec) +} + +Function New-VMFromVMTX { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function deploys a new VM from Template in Content Library (currently only supported in VMC) + .PARAMETER VMTXName + The name of the VM Template in Content Library to deploy from + .PARAMETER NewVMName + The name of the new VM to deploy + .PARAMETER FolderName + The name of vSphere Folder (Defaults to Workloads for VMC) + .PARAMETER ResourcePoolName + The name of the vSphere Resource Pool (Defaults to Compute-ResourcePools for VMC) + .PARAMETER NumCpu + The number of vCPU to configure for the new VM + .PARAMETER MemoryMb + The amount of memory (MB) to configure for the new VM + .PARAMETER PowerOn + To power on the VM after deploy + .EXAMPLE + New-VMFromVMTX -NewVMName "FooFoo" -VMTXName "FooBar" -PowerOn $true -NumCpu 4 -MemoryMB 2048 +#> + param( + [Parameter(Mandatory=$true)][String]$VMTXName, + [Parameter(Mandatory=$true)][String]$NewVMName, + [Parameter(Mandatory=$false)][String]$FolderName="Workloads", + [Parameter(Mandatory=$false)][String]$ResourcePoolName="Compute-ResourcePool", + [Parameter(Mandatory=$false)][String]$DatastoreName="WorkloadDatastore", + [Parameter(Mandatory=$false)][Int]$NumCpu, + [Parameter(Mandatory=$false)][Int]$MemoryMB, + [Parameter(Mandatory=$false)][Boolean]$PowerOn=$false + ) + + $vmtxService = Get-CisService -Name "com.vmware.vcenter.vm_template.library_items" + $vmtxId = (Get-ContentLibraryItem -Name $VMTXName).Id + $folderId = ((Get-Folder -Name $FolderName).ExtensionData.MoRef).Value + $rpId = ((Get-ResourcePool -Name $ResourcePoolName).ExtensionData.MoRef).Value + $datastoreId = ((Get-Datastore -Name $DatastoreName).ExtensionData.MoRef).Value + + $vmtxDeploySpec = $vmtxService.Help.deploy.spec.Create() + $vmtxDeploySpec.name = $NewVMName + $vmtxDeploySpec.powered_on = $PowerOn + $vmtxDeploySpec.placement.folder = $folderId + $vmtxDeploySpec.placement.resource_pool = $rpId + $vmtxDeploySpec.vm_home_storage.datastore = $datastoreId + $vmtxDeploySpec.disk_storage.datastore = $datastoreId + + if($NumCpu) { + $vmtxDeploySpec.hardware_customization.cpu_update.num_cpus = $NumCpu + } + if($MemoryMB) { + $vmtxDeploySpec.hardware_customization.memory_update.memory = $MemoryMB + } + + Write-Host "`nDeploying new VM $NewVMName from VMTX Template $VMTXName ..." + $results = $vmtxService.deploy($vmtxId,$vmtxDeploySpec) } \ No newline at end of file diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index c3371b3..3cee460 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -7,7 +7,35 @@ Copyright = '(c) 2017. All rights reserved.' Description = 'Powershell Module for NSX-T REST API Functions' PowerShellVersion = '5.0' - FunctionsToExport = 'Get-NSXTComputeManager','Get-NSXTFabricNode','Get-NSXTFirewallRule','Get-NSXTIPPool','Get-NSXTLogicalSwitch','Get-NSXTManager','Get-NSXTTransportZone','Get-NSXTController' + FunctionsToExport = 'Get-NSXTBGPNeighbors', + 'Get-NSXTComputeManager', + 'Get-NSXTController', + 'Get-NSXTEdgeCluster', + 'Get-NSXTFabricNode', + 'Get-NSXTFabricVM', + 'Get-NSXTFirewallRule', + 'Get-NSXTForwardingTable', + 'Get-NSXTIPPool', + 'Get-NSXTLogicalRouter', + 'Get-NSXTLogicalRouterPorts', + 'Get-NSXTLogicalSwitch', + 'Get-NSXTManager', + 'Get-NSXTNetworkRoutes', + 'Get-NSXTRoutingTable', + 'Get-NSXTTraceFlow', + 'Get-NSXTTraceFlowObservations', + 'Get-NSXTTransportNode', + 'Get-NSXTTransportZone', + 'Get-NSXTClusterNode', + 'Set-NSXTIPPool', + 'Set-NSXTLogicalRouter', + 'Set-NSXTLogicalSwitch', + 'Set-NSXTTraceFlow', + 'Get-NSXTIPAMIPBlock', + 'Set-NSXTIPAMIPBlock', + 'Remove-NSXTIPAMIPBlock' + + PrivateData = @{ PSData = @{ Tags = @('NSX-T','REST') diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index f8dcb49..4e135e8 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -71,63 +71,6 @@ Function Get-NSXTFabricNode { $results } -Function Get-NSXTIPPool { - Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id - ) - - $ipPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" - - if($Id) { - $ipPools = $ipPoolService.get($Id) - } else { - $ipPools = $ipPoolService.list().results - } - - $results = @() - foreach ($ipPool in $ipPools) { - $tmp = [pscustomobject] @{ - Id = $ipPool.Id; - Name = $ipPool.Display_Name; - Total = $ipPool.pool_usage.total_ids; - Free = $ipPool.pool_usage.free_ids; - Network = $ipPool.subnets.cidr; - Gateway = $ipPool.subnets.gateway_ip; - DNS = $ipPool.subnets.dns_nameservers; - RangeStart = $ipPool.subnets.allocation_ranges.start; - RangeEnd = $ipPool.subnets.allocation_ranges.end - } - $results+=$tmp - } - $results -} - -Function Get-NSXTTransportZone { - Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id - ) - - $transportZoneService = Get-NsxtService -Name "com.vmware.nsx.transport_zones" - - if($Id) { - $transportZones = $transportZoneService.get($Id) - } else { - $transportZones = $transportZoneService.list().results - } - - $results = @() - foreach ($transportZone in $transportZones) { - $tmp = [pscustomobject] @{ - Id = $transportZone.Id; - Name = $transportZone.display_name; - Type = $transportZone.transport_type; - HostSwitchName = $transportZone.host_switch_name; - } - $results+=$tmp - } - $results -} - Function Get-NSXTComputeManager { Param ( [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id @@ -160,38 +103,6 @@ Function Get-NSXTComputeManager { $results } -Function Get-NSXTLogicalSwitch { - Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id - ) - - $logicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches" - $logicalSwitchSummaryService = Get-NsxtService -Name "com.vmware.nsx.logical_switches.summary" - - if($Id) { - $logicalSwitches = $logicalSwitchService.get($Id) - } else { - $logicalSwitches = $logicalSwitchService.list().results - } - - $results = @() - foreach ($logicalSwitch in $logicalSwitches) { - $transportZone = (Get-NSXTTransportZone -Id $logicalSwitch.transport_zone_id | Select Name | ft -HideTableHeaders | Out-String).trim() - $ports = $logicalSwitchSummaryService.get($logicalSwitch.id).num_logical_ports - - $tmp = [pscustomobject] @{ - Id = $logicalSwitch.Id; - Name = $logicalSwitch.display_name; - VLAN = $logicalSwitch.vlan; - AdminStatus = $logicalSwitch.admin_state; - Ports = $ports; - TransportZone = $transportZone; - } - $results+=$tmp - } - $results -} - Function Get-NSXTFirewallRule { Param ( [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id @@ -257,4 +168,1937 @@ Function Get-NSXTManager { } } $results -} \ No newline at end of file +} + +# Updated Function style below + +Function Get-NSXTTransportNode { + <# + .Synopsis + Retrieves the transport_node information + .DESCRIPTION + Retrieves transport_node information for a single or multiple IDs. Execute with no parameters to get all ports, specify a transport_node if known. + .EXAMPLE + Get-NSXTTransportNode + .EXAMPLE + Get-NSXTThingTemplate -Tranport_node_id "TN ID" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id","Tranportnode_id")] + [string]$transport_node_id + ) + + begin + { + $NSXTransportNodesService = Get-NsxtService -Name "com.vmware.nsx.transport_nodes" + + class NSXTransportNode { + [string]$Name + [string]$Transport_node_id + [string]$maintenance_mode + hidden $tags = [System.Collections.Generic.List[string]]::new() + hidden $host_switches = [System.Collections.Generic.List[string]]::new() + hidden [string]$host_switch_spec + hidden $transport_zone_endpoints = [System.Collections.Generic.List[string]]::new() + } + } + + Process + { + if($transport_node_id) { + $NSXTransportNodes = $NSXTransportNodesService.get($transport_node_id) + } else { + $NSXTransportNodes = $NSXTransportNodesService.list().results + } + + foreach ($NSXTransportNode in $NSXTransportNodes) { + + $results = [NSXTransportNode]::new() + $results.Name = $NSXTransportNode.display_name; + $results.Transport_node_id = $NSXTransportNode.Id; + $results.maintenance_mode = $NSXTransportNode.maintenance_mode; + $results.Tags = $NSXTransportNode.tags; + $results.host_switches = $NSXTransportNode.host_switches; + $results.host_switch_spec = $NSXTransportNode.host_switch_spec; + $results.transport_zone_endpoints = $NSXTransportNode.transport_zone_endpoints; + $results.host_switches = $NSXTransportNode.host_switches + $results + } + } +} + +Function Get-NSXTTraceFlow { + <# + .Synopsis + Retrieves traceflow information + .DESCRIPTION + Retrieves traceflow information for a single or multiple traceflows. Execute with no parameters to get all traceflows, specify a traceflow_id if known. + .EXAMPLE + Get-NSXTTraceFlow + .EXAMPLE + Get-NSXTTraceFlow -traceflow_id "TF ID +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true)] + [Alias("Id")] + [string]$traceflow_id + ) + + $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" + + if($traceflow_id) { + $NSXTraceFlows = $NSXTraceFlowsService.get($traceflow_id) + } else { + $NSXTraceFlows = $NSXTraceFlowsService.list().results + } + + class NSXTraceFlow { + [string]$traceflow_id + hidden [string]$lport_id + [string]$Operation_State + [int]$Forwarded + [int]$Delivered + [int]$Received + [int]$Dropped + [string]$Analysis + } + + foreach ($NSXTraceFlow in $NSXTraceFlows) { + + $results = [NSXTraceFlow]::new() + $results.traceflow_id = $NSXTraceFlow.Id; + $results.Operation_State = $NSXTraceFlow.operation_state; + $results.forwarded = $NSXTraceFlow.Counters.forwarded_count; + $results.delivered = $NSXTraceFlow.Counters.delivered_count; + $results.received = $NSXTraceFlow.Counters.received_count; + $results.dropped = $NSXTraceFlow.Counters.dropped_count; + $results.analysis = $NSXTraceFlow.analysis + $results + } +} + +Function Get-NSXTTraceFlowObservations { + <# + .Synopsis + Retrieves traceflow observations information + .DESCRIPTION + Retrieves traceflow observations information for a single traceflow. Must specify a current traceflow_id + .EXAMPLE + Get-NSXTTraceFlowObservations -traceflow_id "TF ID" + .EXAMPLE + Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations +#> + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$traceflow_id + ) + + begin + { + $NSXTraceFlowsObservService = Get-NsxtService -Name "com.vmware.nsx.traceflows.observations" + } + + Process + { + if($traceflow_id) { + $NSXTraceFlowsObserv = $NSXTraceFlowsObservService.list($traceflow_id) + } else { + throw "TraceFlow ID required" + } + + $NSXTraceFlowsObserv.results | select transport_node_name,component_name,@{N='PacketEvent';E={($_.resource_type).TrimStart("TraceflowObservation")}} + } +} + +Function Get-NSXTEdgeCluster { + <# + .Synopsis + Retrieves the Edge cluster information + .DESCRIPTION + Retrieves Edge cluster information for a single or multiple clusterss. Execute with no parameters to get all ports, specify a edge_cluster_id if known. + .EXAMPLE + Get-NSXTEdgeCluster + .EXAMPLE + Get-NSXTEdgeCluster -edge_cluster_id "Edge Cluster ID" + .EXAMPLE + Get-NSXTThingTemplate | where name -eq "My Edge Cluster Name" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$edge_cluster_id + ) + + Begin + { + $NSXTEdgeClustersService = Get-NsxtService -Name "com.vmware.nsx.edge_clusters" + + class NSXEdgeCluster { + [string]$Name + hidden [string]$Protection + hidden [string]$Tags + [string]$edge_cluster_id + [string]$resource_type + [string]$deployment_type + [string]$member_node_type + $members = [System.Collections.Generic.List[string]]::new() + $cluster_profile_bindings = [System.Collections.Generic.List[string]]::new() + } + } + + Process + { + if ($edge_cluster_id) { + $NSXEdgeClusters = $NSXTEdgeClustersService.get($edge_cluster_id) + } + else { + $NSXEdgeClusters = $NSXTEdgeClustersService.list().results + } + + foreach ($NSXEdgeCluster in $NSXEdgeClusters) { + + $results = [NSXEdgeCluster]::new() + $results.Name = $NSXEdgeCluster.display_name; + $results.Protection = $NSXEdgeCluster.Protection; + $results.edge_cluster_id = $NSXEdgeCluster.Id; + $results.resource_type = $NSXEdgeCluster.resource_type; + $results.Tags = $NSXEdgeCluster.tags; + $results.deployment_type = $NSXEdgeCluster.deployment_type; + $results.member_node_type = $NSXEdgeCluster.member_node_type; + $results.members = $NSXEdgeCluster.members; + $results.cluster_profile_bindings = $NSXEdgeCluster.cluster_profile_bindings + $results + } + } +} + +Function Get-NSXTLogicalRouter { + <# + .Synopsis + Retrieves the Logical Router information + .DESCRIPTION + Retrieves Logical Router information for a single or multiple LR's. This includes corresponding SR's and transport_node_id. Execute with no parameters to get all ports, specify a Logical_router_id if known. + .EXAMPLE + Get-NSXTLogicalRouter + .EXAMPLE + Get-NSXTLogicalRouter -Logical_router_id "LR ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" + .EXAMPLE + (Get-NSXTLogicalRouter -Logical_router_id "LR ID").per_node_status +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$Logical_router_id + ) + + begin + { + $NSXTLogicalRoutersService = Get-NsxtService -Name "com.vmware.nsx.logical_routers" + $NSXTLogicalRoutersStatusService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.status" + + class per_node_status { + $service_router_id + [ValidateSet("ACTIVE","STANDBY","DOWN","SYNC","UNKNOWN")] + $high_availability_status + $transport_node_id + + per_node_status(){} + + per_node_status( + $service_router_id, + $high_availability_status, + $transport_node_id + ) { + $this.service_router_id = $service_router_id + $this.high_availability_status = $high_availability_status + $this.transport_node_id = $transport_node_id + } + } + + class NSXTLogicalRouter { + [string]$Name + [string]$Logical_router_id + [string]$protection + hidden [string]$Tags + [string]$edge_cluster_id + [ValidateSet("TIER0","TIER1")] + [string]$router_type + [ValidateSet("ACTIVE_ACTIVE","ACTIVE_STANDBY","")] + [string]$high_availability_mode + [ValidateSet("PREEMPTIVE","NON_PREEMPTIVE","")] + [string]$failover_mode + [string]$external_transit + [string]$internal_transit + hidden [string]$advanced_config = [System.Collections.Generic.List[string]]::new() + hidden [string]$firewall_sections = [System.Collections.Generic.List[string]]::new() + $per_node_status = [System.Collections.Generic.List[string]]::new() + } + } + + Process + { + if($Logical_router_id) { + $NSXLogicalRouters = $NSXTLogicalRoutersService.get($Logical_router_id) + } else { + $NSXLogicalRouters = $NSXTLogicalRoutersService.list().results + } + + foreach ($NSXLogicalRouter in $NSXLogicalRouters) { + + $NSXTLogicalRoutersStatus = $NSXTLogicalRoutersStatusService.get($NSXLogicalRouter.id) + $results = [NSXTLogicalRouter]::new() + + foreach ($NSXTLogicalRouterStatus in $NSXTLogicalRoutersStatus.per_node_status) { + $results.per_node_status += [per_node_status]::new($NSXTLogicalRouterStatus.service_router_id,$NSXTLogicalRouterStatus.high_availability_status,$NSXTLogicalRouterStatus.transport_node_id) + } + + $results.Name = $NSXLogicalRouter.display_name; + $results.Logical_router_id = $NSXLogicalRouter.Id; + $results.protection = $NSXLogicalRouter.protection; + $results.Tags = $NSXLogicalRouter.tags; + $results.edge_cluster_id = $NSXLogicalRouter.edge_cluster_id; + $results.router_type = $NSXLogicalRouter.router_type; + $results.high_availability_mode = $NSXLogicalRouter.high_availability_mode; + $results.failover_mode =$NSXLogicalRouter.failover_mode; + $results.external_transit = $NSXLogicalRouter.advanced_config.external_transit_networks; + $results.internal_transit = $NSXLogicalRouter.advanced_config.internal_transit_network; + $results.advanced_config =$NSXLogicalRouter.advanced_config; + $results.firewall_sections =$NSXLogicalRouter.firewall_sections + $results + } + } +} + +Function Get-NSXTRoutingTable { + <# + .Synopsis + Retrieves the routing table information + .DESCRIPTION + Retrieves routing table for a single LR including LR type (SR/DR) and next_hop. Must specify Logical_router_id & transport_node_id. Pipeline input supported. + .EXAMPLE + Get-NSXTRoutingTable -Logical_router_id "LR ID" -transport_node_id "TN ID" | format-table -autosize + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTRoutingTable -transport_node_id "TN ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq INT-T1 | Get-NSXTRoutingTable -transport_node_id ((Get-NSXTTransportNode | where name -match "INT")[0].transport_node_id) + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq INT-T1 | Get-NSXTRoutingTable -transport_node_id (((Get-NSXTLogicalRouter | where name -eq INT-T1).per_node_status | where high_availability_status -eq ACTIVE).transport_node_id) +#> + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$Logical_router_id, + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$transport_node_id + ) + + Begin + { + $NSXTRoutingTableService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.route_table" + + class NSXTRoutingTable { + hidden [string]$Logical_router_id + [string]$lr_component_id + [string]$lr_component_type + [string]$network + [string]$next_hop + [string]$route_type + hidden [string]$logical_router_port_id + [long]$admin_distance + } + } + + Process + { + $NSXTRoutingTable = $NSXTRoutingTableService.list($Logical_router_id,$transport_node_id,$null,$null,$null,$null,$null,'realtime') + + foreach ($NSXTRoute in $NSXTRoutingTable.results) { + + $results = [NSXTRoutingTable]::new() + $results.Logical_router_id = $Logical_router_id; + $results.lr_component_type = $NSXTRoute.lr_component_type; + $results.lr_component_id = $NSXTRoute.lr_component_id; + $results.next_hop = $NSXTRoute.next_hop; + $results.route_type = $NSXTRoute.route_type; + $results.logical_router_port_id = $NSXTRoute.logical_router_port_id; + $results.admin_distance = $NSXTRoute.admin_distance; + $results.network = $NSXTRoute.network + $results + } + } +} + +Function Get-NSXTFabricVM { + <# + .Synopsis + Retrieves the VM's attached to the fabric. + .DESCRIPTION + Retrieves all VM's attached to the fabric. + .EXAMPLE + Get-NSXTFabricVM +#> + Begin + { + $NSXTVMService = Get-NsxtService -Name "com.vmware.nsx.fabric.virtual_machines" + + class NSXVM { + [string]$Name + $resource_type + hidden [string]$Tags + hidden $compute_ids + hidden [string]$external_id + [string]$host_id + [string]$power_state + [string]$type + hidden $source + } + } + + Process + { + + $NSXTVMs = $NSXTVMService.list().results + + foreach ($NSXTVM in $NSXTVMs) { + + $results = [NSXVM]::new() + $results.Name = $NSXTVM.display_name; + $results.resource_type = $NSXTVM.resource_type; + $results.compute_ids = $NSXTVM.compute_ids; + $results.resource_type = $NSXTVM.resource_type; + $results.Tags = $NSXTVM.tags; + $results.external_id = $NSXTVM.external_id; + $results.host_id = $NSXTVM.host_id; + $results.power_state = $NSXTVM.power_state; + $results.type = $NSXTVM.type; + $results.source = $NSXTVM.source + $results + } + } +} + +Function Get-NSXTBGPNeighbors { + <# + .Synopsis + Retrieves the BGP neighbor information + .DESCRIPTION + Retrieves BGP neighbor information for a single logical router. Must specify logical_router_id parameter. Pipeline input supported + .EXAMPLE + Get-NSXTBGPNeighbors -logical_router_id "LR ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTBGPNeighbors +#> + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$logical_router_id + ) + + begin + { + $NSXTThingsService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.bgp.neighbors" + + class NSXTBGPNeighbors { + [string]$Name + [string]$logical_router_id + hidden $tags = [System.Collections.Generic.List[string]]::new() + [string]$protection + [string]$resource_type + [string]$address_families = [System.Collections.Generic.List[string]]::new() + hidden $bfd_config + [bool]$enable_bfd + [bool]$enabled + hidden $filter_in_ipprefixlist_id + hidden $filter_in_routemap_id + hidden $filter_out_ipprefixlist_id + hidden $filter_out_routemap_id + hidden [long]$hold_down_timer + hidden [long]$keep_alive_timer + hidden [long]$maximum_hop_limit + [string]$neighbor_address + hidden [string]$password + [long]$remote_as + [string]$remote_as_num + [string]$source_address + [string]$source_addresses = [System.Collections.Generic.List[string]]::new() + } + } + + Process + { + $NSXTThings = $NSXTThingsService.list($logical_router_id).results + + foreach ($NSXTThing in $NSXTThings) { + + $results = [NSXTBGPNeighbors]::new() + $results.Name = $NSXTThing.display_name; + $results.logical_router_id = $NSXTThing.logical_router_id; + $results.tags = $NSXTThing.tags; + $results.protection = $NSXTThing.protection; + $results.resource_type = $NSXTThing.resource_type; + $results.address_families = $NSXTThing.address_families; + $results.bfd_config = $NSXTThing.bfd_config; + $results.enable_bfd = $NSXTThing.enable_bfd; + $results.enabled = $NSXTThing.enabled; + $results.filter_in_ipprefixlist_id = $NSXTThing.filter_in_ipprefixlist_id; + $results.filter_in_routemap_id = $NSXTThing.filter_in_routemap_id; + $results.filter_out_ipprefixlist_id = $NSXTThing.filter_out_ipprefixlist_id; + $results.filter_out_routemap_id = $NSXTThing.filter_out_routemap_id; + $results.hold_down_timer = $NSXTThing.hold_down_timer; + $results.keep_alive_timer = $NSXTThing.keep_alive_timer; + $results.maximum_hop_limit = $NSXTThing.maximum_hop_limit; + $results.neighbor_address = $NSXTThing.neighbor_address; + $results.password = $NSXTThing.password; + $results.remote_as = $NSXTThing.remote_as; + $results.remote_as_num = $NSXTThing.remote_as_num; + $results.source_address = $NSXTThing.source_address; + $results.source_addresses = $NSXTThing.source_addresses + $results + } + } +} + +Function Get-NSXTForwardingTable { + <# + .Synopsis + Retrieves the forwarding table information + .DESCRIPTION + Retrieves forwarding table for a single LR including LR type (SR/DR) and next_hop. Must specify Logical_router_id & transport_node_id. Pipeline input supported. + .EXAMPLE + Get-Get-NSXTForwardingTable -Logical_router_id "LR ID" -transport_node_id "TN ID" | format-table -autosize + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTForwardingTable -transport_node_id "TN ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTForwardingTable -transport_node_id ((Get-NSXTTransportNode | where name -match "Edge Name")[0].transport_node_id) + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTForwardingTable -transport_node_id (((Get-NSXTLogicalRouter | where name -eq "Edge Name").per_node_status | where high_availability_status -eq ACTIVE).transport_node_id) +#> + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$Logical_router_id, + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$transport_node_id + ) + + Begin + { + $NSXTForwardingTableService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.forwarding_table" + + class NSXTForwardingTable { + hidden [string]$Logical_router_id + [string]$lr_component_id + [string]$lr_component_type + [string]$network + [string]$next_hop + [string]$route_type + hidden [string]$logical_router_port_id + } + } + + Process + { + $NSXTForwardingTable = $NSXTForwardingTableService.list($Logical_router_id,$transport_node_id,$null,$null,$null,$null,$null,$null,'realtime') + + foreach ($NSXTForwarding in $NSXTForwardingTable.results) { + + $results = [NSXTForwardingTable]::new() + $results.Logical_router_id = $Logical_router_id; + $results.lr_component_type = $NSXTForwarding.lr_component_type; + $results.lr_component_id = $NSXTForwarding.lr_component_id; + $results.network = $NSXTForwarding.network; + $results.next_hop = $NSXTForwarding.next_hop; + $results.route_type = $NSXTForwarding.route_type; + $results.logical_router_port_id = $NSXTForwarding.logical_router_port_id + $results + } + } +} + +Function Get-NSXTNetworkRoutes { +<# + .Synopsis + Retrieves the network routes information + .DESCRIPTION + Retrieves the network routes information for a single or multiple routes. + .EXAMPLE + Get-NSXTNetworkRoutes + .EXAMPLE + Get-NSXTNetworkRoutes -route_id "Route ID" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [string]$route_id + ) + + Begin + { + $NSXTNetworkRoutesService = Get-NsxtService -Name "com.vmware.nsx.node.network.routes" + + class NSXTNetworkRoutes { + [string]$route_id + $route_type + $interface_id + $gateway + $from_address + $destination + $netmask + $metric + $proto + $scope + $src + } + } + + Process + { + if ($route_id) { + $NSXTNetworkRoutes = $NSXTNetworkRoutesService.get($route_id) + } + else { + $NSXTNetworkRoutes = $NSXTNetworkRoutesService.list().results + } + + foreach ($NSXTRoute in $NSXTNetworkRoutes) { + + $results = [NSXTNetworkRoutes]::new() + $results.route_id = $NSXTRoute.route_id; + $results.route_type = $NSXTRoute.route_type; + $results.interface_id = $NSXTRoute.interface_id; + $results.gateway = $NSXTRoute.gateway; + $results.from_address = $NSXTRoute.from_address; + $results.destination = $NSXTRoute.destination; + $results.netmask = $NSXTRoute.netmask; + $results.metric = $NSXTRoute.metric; + $results.proto = $NSXTRoute.proto; + $results.scope = $NSXTRoute.scope; + $results.src = $NSXTRoute.src + $results + } + } +} + +Function Get-NSXTLogicalRouterPorts { +<# + .Synopsis + Retrieves the logical router port information + .DESCRIPTION + Retrieves logical router port information for a single or multiple ports. Execute with no parameters to get all ports, specify a single port if known, or feed a logical switch for filtered output. + .EXAMPLE + Get-NSXTLogicalRouterPorts + .EXAMPLE + Get-NSXTLogicalRouterPorts -logical_router_port_id "LR Port Name" + .EXAMPLE + Get-NSXTLogicalRouterPorts -logical_router_id "LR Name" + .EXAMPLE + Get-NSXTLogicalRouterPorts -logical_router_id (Get-NSXTLogicalRouter | where name -eq "LR Name") +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$logical_router_port_id, + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [string]$logical_router_id + ) + + begin + { + $NSXTLogicalRouterPortsService = Get-NsxtService -Name "com.vmware.nsx.logical_router_ports" + + class subnets { + $ip_addresses + $prefix_length + + subnets(){} + + subnets( + $ip_addresses, + $prefix_length + ) { + $this.ip_addresses = $ip_addresses + $this.prefix_length = $prefix_length + } + } + + class NSXTLogicalRouterPorts { + [string]$Name + $Id + [string]$logical_router_id + $resource_type + [string]$protection + $mac_address + $subnets = [System.Collections.Generic.List[string]]::new() + hidden [string]$Tags + hidden $linked_logical_switch_port_id + } + } + + Process + { + if($logical_router_port_id) { + $NSXTLogicalRouterPorts = $NSXTLogicalRouterPortsService.get($logical_router_port_id) + } else { + if ($logical_router_id) { + $NSXTLogicalRouterPorts = $NSXTLogicalRouterPortsService.list().results | where {$_.logical_router_id -eq $Logical_router_id} + } + else { + $NSXTLogicalRouterPorts = $NSXTLogicalRouterPortsService.list().results + } + } + + foreach ($NSXTLogicalRouterPort in $NSXTLogicalRouterPorts) { + + $results = [NSXTLogicalRouterPorts]::new() + + foreach ($subnet in $NSXTLogicalRouterPort.subnets) { + $results.subnets += [subnets]::new($subnet.ip_addresses,$subnet.prefix_length) + } + + $results.Name = $NSXTLogicalRouterPort.display_name + $results.Id = $NSXTLogicalRouterPort.Id + $results.Logical_router_id = $NSXTLogicalRouterPort.Logical_router_id + $results.resource_type = $NSXTLogicalRouterPort.resource_type + $results.protection = $NSXTLogicalRouterPort.protection + $results.Tags = $NSXTLogicalRouterPort.tags + $results.mac_address = $NSXTLogicalRouterPort.mac_address + $results.linked_logical_switch_port_id = $NSXTLogicalRouterPort.linked_logical_switch_port_id + $results + } + } +} + +Function Get-NSXTTransportZone { + <# + .Synopsis + Retrieves the Transport Zone information + .DESCRIPTION + Retrieves THING information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTTransportZone + .EXAMPLE + Get-NSXTTransportZone -zone_id "Zone ID" + .EXAMPLE + Get-NSXTTransportZone -name "Zone1" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$zone_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTTransportZoneService = Get-NsxtService -Name "com.vmware.nsx.transport_zones" + + class NSXTTransportZone { + [string]$Name + [string]$ID + hidden [string]$description + hidden $tags + $resource_type + $host_switch_name + $transport_type + hidden $transport_zone_profile_ids + $host_switch_mode + $protection + hidden $uplink_teaming_policy_names + } + } + + Process + { + if($zone_id) { + $NSXTTransportZones = $NSXTTransportZoneService.get($zone_id) + } else { + if ($name) { + $NSXTTransportZones = $NSXTTransportZoneService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTTransportZones = $NSXTTransportZoneService.list().results + } + } + + foreach ($NSXTTransportZone in $NSXTTransportZones) { + + $results = [NSXTTransportZone]::new() + $results.Name = $NSXTTransportZone.display_name; + $results.ID = $NSXTTransportZone.Id; + $results.description = $NSXTTransportZone.description; + $results.tags = $NSXTTransportZone.tags; + $results.resource_type = $NSXTTransportZone.resource_type; + $results.host_switch_name = $NSXTTransportZone.host_switch_name; + $results.transport_type = $NSXTTransportZone.transport_type; + $results.transport_zone_profile_ids = $NSXTTransportZone.transport_zone_profile_ids; + $results.host_switch_mode = $NSXTTransportZone.host_switch_mode; + $results.protection = $NSXTTransportZone.protection; + $results.uplink_teaming_policy_names = $NSXTTransportZone.uplink_teaming_policy_names + $results + } + } +} + +Function Get-NSXTLogicalSwitch { + <# + .Synopsis + Retrieves the Logical Switch information + .DESCRIPTION + Retrieves Logical Switch information for a single or multiple switches. Execute with no parameters to get all ports, specify a name or lswitch_id if known. + .EXAMPLE + Get-NSXTLogicalSwitch + .EXAMPLE + Get-NSXTLogicalSwitch -lswitch_id "switch id" + .EXAMPLE + Get-NSXTLogicalSwitch -name "switch name" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$lswitch_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTLogicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches" + + class NSXTLogicalSwitch { + [string]$Name + [string]$ID + $tags + $resource_type + hidden $description + $vni + $transport_zone_id + $admin_state + $replication_mode + hidden $address_bindings + $protection + hidden $extra_configs + $ip_pool_id + hidden $mac_pool_id + hidden $uplink_teaming_policy_name + hidden $vlan + hidden $vlan_trunk_spec + } + } + + Process + { + if($lswitch_id) { + $NSXTLogicalSwitches = $NSXTLogicalSwitchService.get($lswitch_id) + } else { + if ($name) { + $NSXTLogicalSwitches = $NSXTLogicalSwitchService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTLogicalSwitches = $NSXTLogicalSwitchService.list().results + } + } + + foreach ($NSXTLogicalSwitch in $NSXTLogicalSwitches) { + + $results = [NSXTLogicalSwitch]::new() + $results.Name = $NSXTLogicalSwitch.display_name; + $results.Id = $NSXTLogicalSwitch.Id; + $results.Tags = $NSXTLogicalSwitch.tags; + $results.resource_type = $NSXTLogicalSwitch.resource_type; + $results.description = $NSXTLogicalSwitch.description; + $results.vni = $NSXTLogicalSwitch.vni; + $results.transport_zone_id = $NSXTLogicalSwitch.transport_zone_id; + $results.admin_state = $NSXTLogicalSwitch.admin_state; + $results.replication_mode = $NSXTLogicalSwitch.replication_mode; + $results.address_bindings = $NSXTLogicalSwitch.address_bindings; + $results.protection = $NSXTLogicalSwitch.protection; + $results.extra_configs = $NSXTLogicalSwitch.extra_configs; + $results.ip_pool_id = $NSXTLogicalSwitch.ip_pool_id; + $results.mac_pool_id = $NSXTLogicalSwitch.mac_pool_id; + $results.uplink_teaming_policy_name = $NSXTLogicalSwitch.uplink_teaming_policy_name; + $results.vlan = $NSXTLogicalSwitch.vlan; + $results.vlan_trunk_spec = $NSXTLogicalSwitch.vlan_trunk_spec + $results + } + } +} + +Function Get-NSXTIPPool { + <# + .Synopsis + Retrieves the THING information + .DESCRIPTION + Retrieves THING information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTIPPool + .EXAMPLE + Get-NSXTThingTemplate -pool_id "Pool ID" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$pool_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" + + class NSXTIPPool { + [string]$Name + [string]$id + $total_ids + $free_ids + $allocated_ids + $Network + $Gateway + $DNS + $RangeStart + $RangeEnd + } + } + + Process + { + if($pool_id) { + $NSXTIPPools = $NSXTIPPoolService.get($pool_id) + } else { + if ($name) { + $NSXTIPPools = $NSXTIPPoolService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTIPPools = $NSXTIPPoolService.list().results + } + } + + foreach ($NSXTIPPool in $NSXTIPPools) { + + $results = [NSXTIPPool]::new() + $results.Name = $NSXTIPPool.display_name; + $results.ID = $NSXTIPPool.id; + $results.total_ids = $NSXTIPPool.pool_usage.total_ids; + $results.free_ids = $NSXTIPPool.pool_usage.free_ids; + $results.allocated_ids = $NSXTIPPool.pool_usage.allocated_ids; + $results.Network = $NSXTIPPool.subnets.cidr; + $results.Gateway = $NSXTIPPool.subnets.gateway_ip; + $results.DNS = $NSXTIPPool.subnets.dns_nameservers; + $results.RangeStart = $NSXTIPPool.subnets.allocation_ranges.start; + $results.RangeEnd = $NSXTIPPool.subnets.allocation_ranges.end + $results + } + } +} + +Function Get-NSXTIPAMIPBlock { + <# + .Synopsis + Retrieves the IPAM IP Block information + .DESCRIPTION + Retrieves IPAM IP Block information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTIPAMIPBlock + .EXAMPLE + Get-NSXTIPAMIPBlock -block_id "Block Id" + .EXAMPLE + Get-NSXTIPAMIPBlock -name "Block Name" + +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$block_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTIPAMIPBlocksService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_blocks" + + class ip_block { + [string]$Name + [string]$block_id + hidden [string]$Tags = [System.Collections.Generic.List[string]]::new() + [string]$protection + #[ValidateSet("TIER0","TIER1")] + [string]$cidr + hidden [string]$resource_type + } + } + + Process + { + if($block_id) { + $NSXTIPAMIPBlocks = $NSXTIPAMIPBlocksService.get($block_id) + } else { + if ($name) { + $NSXTIPAMIPBlocks = $NSXTIPAMIPBlocksService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTIPAMIPBlocks = $NSXTIPAMIPBlocksService.list().results + } + } + + foreach ($NSXTIPAMIPBlock in $NSXTIPAMIPBlocks) { + + $results = [ip_block]::new() + $results.Name = $NSXTIPAMIPBlock.display_name; + $results.block_id = $NSXTIPAMIPBlock.id; + $results.Tags = $NSXTIPAMIPBlock.tags; + $results.protection = $NSXTIPAMIPBlock.protection; + $results.cidr = $NSXTIPAMIPBlock.cidr; + $results.resource_type = $NSXTIPAMIPBlock.resource_type + + $results + } + } +} + +Function Get-NSXTClusterNode { + <# + .Synopsis + Retrieves the cluster node information + .DESCRIPTION + Retrieves cluster node information including manager and controller nodes. + .EXAMPLE + Get-NSXTClusterNode + .EXAMPLE + Get-NSXTClusterNode -node_id "Node Id" + .EXAMPLE + Get-NSXTClusterNode -name "Name" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$node_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTClusterNodesService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes" + + class NSXTClusterNode { + [string]$Name + [string]$node_id + hidden [array]$Tags = [System.Collections.Generic.List[string]]::new() + hidden [string]$controller_role + hidden [array]$manager_role + [string]$protection + [string]$appliance_mgmt_listen_addr + hidden [string]$external_id + hidden [string]$description + [string]$role + } + } + + Process + { + if($node_id) { + $NSXTThings = $NSXTClusterNodesService.get($node_id) + } else { + if ($name) { + $NSXTClusterNodes = $NSXTClusterNodesService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTClusterNodes = $NSXTClusterNodesService.list().results + } + } + + foreach ($NSXTClusterNode in $NSXTClusterNodes) { + + $results = [NSXTClusterNode]::new() + $results.Name = $NSXTClusterNode.display_name; + $results.node_id = $NSXTClusterNode.Id; + $results.Tags = $NSXTClusterNode.tags; + $results.controller_role = $NSXTClusterNode.controller_role; + $results.manager_role = $NSXTClusterNode.manager_role; + $results.protection = $NSXTClusterNode.protection; + $results.appliance_mgmt_listen_addr = $NSXTClusterNode.appliance_mgmt_listen_addr; + $results.external_id = $NSXTClusterNode.external_id; + $results.description = $NSXTClusterNode.description + + if ($NSXTClusterNode.manager_role -ne $null) { + $results.role = "Manager" + } + elseif ($NSXTClusterNode.controller_role -ne $null) { + $results.role = "Controller" + } + + $results + } + } +} + +# Working Set Functions +Function Set-NSXTLogicalRouter { + <# + .Synopsis + Creates a Logical Router + .DESCRIPTION + Create a TIER0 or TIER1 logical router + .EXAMPLE + Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_STANDBY" -router_type "TIER1" + .EXAMPLE + Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_ACTIVE" -router_type "TIER0" -edge_cluster_id "Edge Cluster ID" + .EXAMPLE + Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_STANDBY" -router_type "TIER1" -description "this is my new tier1 lr" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false, + ParameterSetName='TIER0')] + [parameter(Mandatory=$false, + ParameterSetName='TIER1')] + [string]$description, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [parameter(Mandatory=$true, + ParameterSetName='TIER1')] + [string]$display_name, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [parameter(Mandatory=$true, + ParameterSetName='TIER1')] + [ValidateSet("ACTIVE_ACTIVE","ACTIVE_STANDBY")] + [string]$high_availability_mode, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [parameter(Mandatory=$true, + ParameterSetName='TIER1')] + [ValidateSet("TIER0","TIER1")] + [string]$router_type, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [string]$edge_cluster_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTLogicalRouterService = Get-NsxtService -Name "com.vmware.nsx.logical_routers" + } + + Process + { + $logical_router_request = $NSXTLogicalRouterService.help.create.logical_router.Create() + + $logical_router_request.display_name = $display_name + $logical_router_request.description = $description + $logical_router_request.router_type = $router_type + $logical_router_request.high_availability_mode = $high_availability_mode + $logical_router_request.resource_type = "LogicalRouter" + $logical_router_request.failover_mode = "NON_PREEMPTIVE" + + if ($edge_cluster_id) { + $logical_router_request.edge_cluster_id = $edge_cluster_id + } + + try + { + # Should process + if ($pscmdlet.ShouldProcess($logical_router_request.display_name, "Create logical router")) + { + $NSXTLogicalRouter = $NSXTLogicalRouterService.create($logical_router_request) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTLogicalRouter + } +} + +Function Set-NSXTLogicalSwitch { + <# + .Synopsis + Creates a Logical Switch + .DESCRIPTION + Creates a Logical Switch with a number of required parameters. IP Pool is necessary even for an overlay logical switch + .EXAMPLE + Set-NSXTLogicalSwitch -display_name "Name" -transport_zone_id "TP Zone ID" + .EXAMPLE + Set-NSXTLogicalSwitch -display_name "Name" -transport_zone_id "TP Zone ID" -admin_state "UP" -replication_mode "MTEP" -ip_pool_id "IP Pool Name" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$true)] + [string]$display_name, + + [parameter(Mandatory=$true)] + [string]$transport_zone_id, + + [parameter(Mandatory=$true)] + [ValidateSet("UP","DOWN")] + [string]$admin_state, + + [parameter(Mandatory=$false)] + [ValidateSet("MTEP","SOURCE")] + [string]$replication_mode, + + [parameter(Mandatory=$true)] + [string]$ip_pool_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTLogicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches" + } + + Process + { + $logical_switch_request = $NSXTLogicalSwitchService.help.create.logical_switch.Create() + + $logical_switch_request.display_name = $display_name + $logical_switch_request.description = $description + $logical_switch_request.admin_state = $admin_state + $logical_switch_request.transport_zone_id = $transport_zone_id + $logical_switch_request.resource_type = "LogicalSwitch" + $logical_switch_request.replication_mode = $replication_mode + $logical_switch_request.ip_pool_id = $ip_pool_id + + try + { + # Should process + if ($pscmdlet.ShouldProcess($logical_switch_request.display_name, "Create logical switch")) + { + $NSXTLogicalSwitch = $NSXTLogicalSwitchService.create($logical_switch_request) + } + + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTLogicalSwitch + } +} + +Function Set-NSXTIPAMIPBlock { + <# + .Synopsis + Creates an IPAM IP Block + .DESCRIPTION + Creates a IPAM IP Block with a cidr parameter. + .EXAMPLE + Set-NSXTIPAMIPBlock -name "IPAM Block Name" -cidr "192.168.0.0/24" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$display_name, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$cidr + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPAMIPBlockService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_blocks" + } + + Process + { + $IPAMIPBlock_request = $NSXTIPAMIPBlockService.help.create.ip_block.Create() + + $IPAMIPBlock_request.display_name = $display_name + $IPAMIPBlock_request.description = $description + $IPAMIPBlock_request.resource_type = "IpBlock" + $IPAMIPBlock_request.cidr = $cidr + + + try + { + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTIPAMIPBlock = $NSXTIPAMIPBlockService.create($IPAMIPBlock_request) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTIPAMIPBlock + } +} + +Function Set-NSXTIPPool { + <# + .Synopsis + Creates an IP Pool + .DESCRIPTION + Creates a IP Pool with a number of required parameters. Supported IP formats include 192.168.1.1, 192.168.1.1-192.168.1.100, 192.168.0.0/24 + .EXAMPLE + Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" + .EXAMPLE + Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" -dns_suffix "evil corp" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='High')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$display_name, + + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$false)] + [string]$dns_nameservers, + + [parameter(Mandatory=$false)] + [string]$dns_suffix, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$allocation_start, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$allocation_end, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$cidr, + + [parameter(Mandatory=$false)] + [string]$gateway_ip + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" + + # Classes unused - part of early testing + class allocation_ranges { + [string]$start + [string]$end + #$self + } + + class subnets { + [array]$allocation_ranges = [allocation_ranges]::new() + [array]$dns_nameservers + [string]$dns_suffix + [string]$cidr + [string]$gateway_ip + #hidden $self + } + + class ip_pool { + [string]$display_name + [string]$description + [string]$resource_type = 'IpPool' + [long]$revision = '0' + [array]$subnets = [subnets]::new() + hidden $pool_usage + hidden [array]$tags + # hidden $self + hidden $links + } + } + + Process + { + $sample_ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() + $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Create()) + $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create()) + $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create()) + $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create()) + + #Remove buggy self object + $ip_pool = $sample_ip_pool | select -Property * -ExcludeProperty self + $ip_pool.subnets[0] = $sample_ip_pool.subnets[0] | select -Property * -ExcludeProperty self + $ip_pool.subnets[0].allocation_ranges[0] = $sample_ip_pool.subnets[0].allocation_ranges[0] | select -Property * -ExcludeProperty self + + # Assign objects + $ip_pool.display_name = $display_name + $ip_pool.description = $description + $ip_pool.resource_type = "IpPool" + $ip_pool.subnets[0].dns_nameservers = @($dns_nameservers) + $ip_pool.subnets[0].dns_suffix = $dns_suffix + $ip_pool.subnets[0].allocation_ranges[0].start = $allocation_start + $ip_pool.subnets[0].allocation_ranges[0].end = $allocation_end + $ip_pool.subnets[0].cidr = $cidr + $ip_pool.subnets[0].gateway_ip = $gateway_ip + $ip_pool.revision = 0 + $ip_pool.tags = @() + + try + { + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTIPPoolService.create($ip_pool) + } + } + + catch + { + $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file; grep POOL-MGMT + throw + } + } +} + +# Remove functions +Function Remove-NSXTIPAMIPBlock { + <# + .Synopsis + Removes an IPAM IP Block + .DESCRIPTION + Removes a IPAM IP Block with a block_id parameter. + .EXAMPLE + Remove-NSXTIPAMIPBlock -block_id "id" + .EXAMPLE + Get-NSXTIPAMIPBlock | where name -eq "IPAM Test2" | Remove-NSXTIPAMIPBlock +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='High')] + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateNotNullOrEmpty()] + [Alias("Id")] + [string]$block_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPAMIPBlockService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_blocks" + } + + Process + { + try + { + # Should process + if ($pscmdlet.ShouldProcess($block_id, "Delete IP Pool")) + { + $NSXTIPAMIPBlockService.delete($block_id) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + } +} + +# Non-working Set Functions +Function Set-NSXTTraceFlow { + <# + .Synopsis + Creates a TraceFlow + .DESCRIPTION + Create a TraceFlow for later observation. + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateSet("UNICAST")] + [string] + $transport_type = "UNICAST", + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + #[ValidateScript({Get-NSXTLogicalPort -Id $_}] + [string] + $lport_id, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$_ -match [IPAddress]$_})] + [string] + $src_ip, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' + if ($_ -match ($pattern -join '|')) {$true} else { + throw "The argument '$_' does not match a valid MAC address format." + } + })] + [string] + $src_mac, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$_ -match [IPAddress]$_ })] + [string] + $dst_ip, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' + if ($_ -match ($pattern -join '|')) {$true} else { + throw "The argument '$_' does not match a valid MAC address format." + } + })] + [string] + $dst_mac) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" + + # Comment out custom classes + <# + class ip_header { + [string]$src_ip + [string]$dst_ip + } + + class eth_header { + [string]$src_mac + [string]$dst_mac + } + + class packet_data { + [boolean]$routed + [ValidateSet("UNICAST","BROADCAST","MULTICAST","UNKNOWN")] + [string]$transport_type + [ValidateSet("BINARYPACKETDATA","FIELDSPACKETDATA")] + [string]$resource_type + [long]$frame_size + [eth_header]$eth_header = [eth_header]::new() + [ip_header]$ip_header = [ip_header]::new() + + packet_data(){ + $this.routed = 'true' + $this.transport_type = 'UNICAST' + $this.resource_type = 'FieldsPacketData' + } + } + + class traceflow_request { + [string]$lport_id + [long]$timeout + [packet_data]$packet = [packet_data]::new() + + traceflow_request(){ + $this.timeout = '15000' + } + } +#> + } + + Process + { + $traceflow_request = $NSXTraceFlowsService.Help.create.traceflow_request.Create() + + $traceflow_request.lport_id = $lport_id + $traceflow_request.packet.transport_type = $transport_type + + $eth_header = [ordered]@{'src_mac' = $src_mac;'eth_type' = '2048';'dst_mac' = $dst_mac} + $ip_header = [ordered]@{src_ip = $src_ip;protocol = '1';ttl = '64';dst_ip = $dst_ip} + $traceflow_request.packet | Add-Member -NotePropertyMembers $eth_header -TypeName eth_header + $traceflow_request.packet | Add-Member -NotePropertyMembers $ip_header -TypeName ip_header + + try + { + # Should process + if ($pscmdlet.ShouldProcess($traceflow_request.lport_id, "Create traceflow")) + { + # This does not work, bug report submitted to PowerCLI team + $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. Filter by MONITORING. + } + + $NSXTraceFlow + } +} + + + +########################### +# # +# TEMPLATES!! # +# # +########################### + +# Get Template +Function Get-NSXTThingTemplate { + <# + .Synopsis + Retrieves the THING information + .DESCRIPTION + Retrieves THING information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTThingTemplate + .EXAMPLE + Get-NSXTThingTemplate -param1 "LR Port Name" + .EXAMPLE + Get-NSXTThingTemplate -param2 "LR Name" + .EXAMPLE + Get-NSXTThingTemplate -param2 (Get-NSXTLogicalRouter | where name -eq "LR Name") +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$Thing_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTThingsService = Get-NsxtService -Name "com.vmware.nsx.API.Thing" + + class NSXTThing { + [string]$Name + [string]$Thing1 + hidden [string]$Tags = [System.Collections.Generic.List[string]]::new() + [string]$Thing2 + #[ValidateSet("TIER0","TIER1")] + [string]$Thing3 + #[ValidateSet("ACTIVE_ACTIVE","ACTIVE_STANDBY","")] + [string]$Thing4 + #[ValidateSet("PREEMPTIVE","NON_PREEMPTIVE","")] + [string]$Thing5 + [string]$Thing6 + [string]$Thing7 + } + } + + Process + { + if($Thing_id) { + $NSXTThings = $NSXTThingsService.get($Thing_id) + } else { + if ($name) { + $NSXTThings = $NSXTThingsService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTThings = $NSXTThingsService.list().results + } + } + + foreach ($NSXTThing in $NSXTThings) { + + $results = [NSXTThing]::new() + $results.Name = $NSXTThing.display_name; + $results.Logical_router_id = $NSXTThing.Id; + $results.Tags = $NSXTThing.tags; + $results.thing1 = $NSXTThing.thing1; + $results.thing2 = $NSXTThing.thing2 + + $results + } + } +} + +# Set Template +Function Set-NSXTThingTemplate { + <# + .Synopsis + Creates a THING + .DESCRIPTION + Creates a THING with a number of required parameters. + .EXAMPLE + Set-NSXTThingTemplateh -param1 "Name" -param2 "TP Zone ID" + .EXAMPLE + Set-NSXTThingTemplateh -param1 "Name" -param2 "TP Zone ID" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$display_name, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$transport_zone_id, + + [parameter(Mandatory=$true)] + [ValidateSet("UP","DOWN")] + [string]$admin_state, + + [parameter(Mandatory=$false)] + [ValidateSet("MTEP","SOURCE")] + [string]$replication_mode, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$ip_pool_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTTHINGService = Get-NsxtService -Name "com.vmware.nsx.THING" + } + + Process + { + $logical_THING_request = $NSXTTHINGService.help.create.logical_switch.Create() + + $logical_THING_request.display_name = $display_name + $logical_THING_request.description = $description + $logical_THING_request.admin_state = $admin_state + $logical_THING_request.transport_zone_id = $transport_zone_id + $logical_THING_request.resource_type = "LogicalSwitch" + $logical_THING_request.replication_mode = $replication_mode + $logical_THING_request.ip_pool_id = $ip_pool_id + + try + { + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTTHING = $NSXTTHINGService.create($logical_THING_request) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTTHING + } +} + +# Remove Template +Function Remove-NSXTThingTemplate { + <# + .Synopsis + Removes an IPAM IP Block + .DESCRIPTION + Removes a IPAM IP Block with a block_id parameter. + .EXAMPLE + Remove-NSXTIPAMIPBlock -block_id "id" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='High')] + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateNotNullOrEmpty()] + [Alias("Id")] + [string]$thing_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTTHINGkService = Get-NsxtService -Name "com.vmware.nsx.THING" + } + + Process + { + try + { + # Should process + if ($pscmdlet.ShouldProcess($thing_id, "Delete IP Pool")) + { + $NSXTTHINGkService.delete($thing_id) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + } +} + + + diff --git a/Modules/VMFSIncrease/VMFSIncrease.psm1 b/Modules/VMFSIncrease/VMFSIncrease.psm1 index ec0fa2b..90a8ccc 100644 --- a/Modules/VMFSIncrease/VMFSIncrease.psm1 +++ b/Modules/VMFSIncrease/VMFSIncrease.psm1 @@ -112,7 +112,7 @@ function Get-VmfsDatastoreIncrease Datastore = $Datastore.Name CanonicalName = $disk.CanonicalName Model = "$($disk.Vendor.TrimEnd(' ')).$($disk.Model.TrimEnd(' ')).$($disk.Revision.TrimEnd(' '))" - DiskSizeGB = $partInfo[0].Layout.Total.BlockSize * $hdPartInfo[0].Layout.Total.Block / 1GB + DiskSizeGB = $partInfo[0].Layout.Total.BlockSize * $partInfo[0].Layout.Total.Block / 1GB DiskBlocks = $partInfo[0].Layout.Total.Block DiskBlockMB = $partInfo[0].Layout.Total.BlockSize/1MB AvailableGB = [math]::Round($partMax - $partUsed, 2) @@ -181,7 +181,7 @@ function New-VmfsDatastoreIncrease { $lun = $hScsiDisk | where{ $_.CanonicalName -eq $dsOpt.Spec.Extent.DiskName } $partInfo = $hsSys.RetrieveDiskPartitionInfo($lun.DeviceName) - $partMax = ($vmfsExpOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } | + $partMax = ($expOpt[0].Info.Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } | Measure-Object -Sum | select -ExpandProperty Sum)/1GB $partUsed = ($partInfo[0].Layout.Partition | where{ $_.Type -eq 'VMFS' } | %{ ($_.End.Block - $_.Start.Block + 1) * $_.Start.BlockSize } | Measure-Object -Sum | select -ExpandProperty Sum)/1GB diff --git a/Modules/VMware.CSP/VMware.CSP.psm1 b/Modules/VMware.CSP/VMware.CSP.psm1 new file mode 100644 index 0000000..b4b4515 --- /dev/null +++ b/Modules/VMware.CSP/VMware.CSP.psm1 @@ -0,0 +1,54 @@ +Function Get-CSPAccessToken { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 07/23/2018 + Organization: VMware + Blog: https://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .DESCRIPTION + Converts a Refresh Token from the VMware Console Services Portal + to CSP Access Token to access CSP API + .PARAMETER RefreshToken + The Refresh Token from the VMware Console Services Portal + .EXAMPLE + Get-CSPAccessToken -RefreshToken $RefreshToken + #> + Param ( + [Parameter(Mandatory=$true)][String]$RefreshToken + ) + + $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 + Write-Host "CSP Auth Token has been successfully retrieved and saved to `$env:cspAuthToken" + $env:cspAuthToken = $accessToken +} + +Function Get-CSPServices { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 07/23/2018 + Organization: VMware + Blog: https://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .DESCRIPTION + Returns the list of CSP Services avialable for given user + .EXAMPLE + Get-CSPServices + #> + If (-Not $env:cspAuthToken) { Write-error "CSP Auth Token not found, please run Get-CSPAccessToken" } Else { + $results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/slc/api/definitions?expand=1" -Method GET -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$env:cspAuthToken"} + ((($results.Content) | ConvertFrom-Json).results | where {$_.visible -eq $true}).displayName + } +} \ No newline at end of file diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 new file mode 100644 index 0000000..a5e74f0 --- /dev/null +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -0,0 +1,88 @@ +# +# Module manifest for module 'VMware.HCX' +# +# Generated by: wlam@vmware.com +# +# Generated on: 09/11/18 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'VMware.HCX.psm1' + +# Version number of this module. +ModuleVersion = '1.0.2' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = '88898ed6-26e8-4dfa-a9de-10d3a12571de' + +# Author of this module +Author = 'William Lam' + +# Company or vendor of this module +CompanyName = 'VMware' + +# Copyright statement for this module +Copyright = '(c) 2018 VMware. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VMware Cloud on AWS' + +# Minimum version of the Windows PowerShell engine required by this module +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' +# 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 = @() + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases 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 aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} \ No newline at end of file diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 new file mode 100644 index 0000000..cfbe95b --- /dev/null +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -0,0 +1,1309 @@ +Function Connect-HcxServer { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Connect to the HCX Enterprise Manager + .DESCRIPTION + This cmdlet connects to the HCX Enterprise Manager + .EXAMPLE + Connect-HcxServer -Server $HCXServer -Username $Username -Password $Password +#> + Param ( + [Parameter(Mandatory=$true)][String]$Server, + [Parameter(Mandatory=$true)][String]$Username, + [Parameter(Mandatory=$true)][String]$Password + ) + + $payload = @{ + "username" = $Username + "password" = $Password + } + $body = $payload | ConvertTo-Json + + $hcxLoginUrl = "https://$Server/hybridity/api/sessions" + + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $hcxLoginUrl -Body $body -Method POST -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $hcxLoginUrl -Body $body -Method POST -UseBasicParsing -ContentType "application/json" + } + + if($results.StatusCode -eq 200) { + $hcxAuthToken = $results.Headers.'x-hm-authorization' + + $headers = @{ + "x-hm-authorization"="$hcxAuthToken" + "Content-Type"="application/json" + "Accept"="application/json" + } + + $global:hcxConnection = new-object PSObject -Property @{ + 'Server' = "https://$server/hybridity/api"; + 'headers' = $headers + } + $global:hcxConnection + } else { + Write-Error "Failed to connect to HCX Manager, please verify your vSphere SSO credentials" + } +} + +Function Get-HcxCloudConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the Cloud HCX information that is registerd with HCX Manager + .DESCRIPTION + This cmdlet returns the Cloud HCX information that is registerd with HCX Manager + .EXAMPLE + Get-HcxCloudConfig +#> + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxServer " } Else { + $cloudConfigUrl = $global:hcxConnection.Server + "/cloudConfigs" + + if($PSVersionTable.PSEdition -eq "Core") { + $cloudvcRequests = Invoke-WebRequest -Uri $cloudConfigUrl -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $cloudvcRequests = Invoke-WebRequest -Uri $cloudConfigUrl -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing + } + + $cloudvcData = ($cloudvcRequests.content | ConvertFrom-Json).data.items + + $tmp = [pscustomobject] @{ + Name = $cloudvcData.cloudName; + Version = $cloudvcData.version; + Build = $cloudvcData.buildNumber; + HCXUUID = $cloudvcData.endpointId; + } + $tmp + } +} + +Function Get-HcxEndpoint { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/24/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + List all HCX endpoints (onPrem and Cloud) + .DESCRIPTION + This cmdlet lists all HCX endpoints (onPrem and Cloud) + .EXAMPLE + Get-HcxEndpoint -cloudVCConnection $cloudVCConnection +#> + Param ( + [Parameter(Mandatory=$true)]$cloudVCConnection + ) + + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { + #Cloud HCX Manager + $cloudHCXConnectionURL = $global:hcxConnection.Server + "/cloudConfigs" + + if($PSVersionTable.PSEdition -eq "Core") { + $cloudRequests = Invoke-WebRequest -Uri $cloudHCXConnectionURL -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $cloudRequests = Invoke-WebRequest -Uri $cloudHCXConnectionURL -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing + } + $cloudData = ($cloudRequests.Content | ConvertFrom-Json).data.items[0] + + $hcxInventoryUrl = $global:hcxConnection.Server + "/service/inventory/resourcecontainer/list" + + $payload = @{ + "cloud" = @{ + "local"="true"; + "remote"="true"; + } + } + $body = $payload | ConvertTo-Json + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxInventoryUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxInventoryUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing + } + if($requests.StatusCode -eq 200) { + $items = ($requests.Content | ConvertFrom-Json).data.items + + $results = @() + foreach ($item in $items) { + $tmp = [pscustomobject] @{ + SourceResourceName = $item.resourceName; + SourceResourceType = $item.resourceType; + SourceResourceId = $item.resourceId; + SourceEndpointName = $item.endpoint.name; + SourceEndpointType = "VC" + SourceEndpointId = $item.endpoint.endpointId; + RemoteResourceName = $cloudVCConnection.name; + RemoteResourceType = "VC" + RemoteResourceId = $cloudVCConnection.InstanceUuid + RemoteEndpointName = $cloudData.cloudName; + RemoteEndpointType = $cloudData.cloudType; + RemoteEndpointId = $cloudData.endpointId; + } + $results+=$tmp + } + return $results + } else { + Write-Error "Failed to list HCX Connection Resources" + } + } +} + +Function New-HcxMigration { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/24/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Initiate a "Bulk" migrations supporting Cold, vMotion, VR or new Cloud Motion + .DESCRIPTION + This cmdlet initiates a "Bulk" migrations supporting Cold, vMotion, VR or new Cloud Motionn + .EXAMPLE + Validate Migration request only + + New-HcxMigration -onPremVCConnection $onPremVC -cloudVCConnection $cloudVC ` + -MigrationType bulkVMotion ` + -VMs @("SJC-CNA-34","SJC-CNA-35","SJC-CNA-36") ` + -NetworkMappings @{"SJC-CORP-WORKLOADS"="sddc-cgw-network-1";"SJC-CORP-INTERNAL-1"="sddc-cgw-network-2";"SJC-CORP-INTERNAL-2"="sddc-cgw-network-3"} ` + -StartTime "Sep 24 2018 1:30 PM" ` + -EndTime "Sep 24 2018 2:30 PM" + .EXAMPLE + Start Migration request + + New-HcxMigration -onPremVCConnection $onPremVC -cloudVCConnection $cloudVC ` + -MigrationType bulkVMotion ` + -VMs @("SJC-CNA-34","SJC-CNA-35","SJC-CNA-36") ` + -NetworkMappings @{"SJC-CORP-WORKLOADS"="sddc-cgw-network-1";"SJC-CORP-INTERNAL-1"="sddc-cgw-network-2";"SJC-CORP-INTERNAL-2"="sddc-cgw-network-3"} ` + -StartTime "Sep 24 2018 1:30 PM" ` + -EndTime "Sep 24 2018 2:30 PM" ` + -MigrationType bulkVMotion +#> + Param ( + [Parameter(Mandatory=$true)][String[]]$VMs, + [Parameter(Mandatory=$true)][Hashtable]$NetworkMappings, + [Parameter(Mandatory=$true)]$onPremVCConnection, + [Parameter(Mandatory=$true)]$cloudVCConnection, + [Parameter(Mandatory=$true)][String]$StartTime, + [Parameter(Mandatory=$true)][String]$EndTime, + [Parameter(Mandatory=$true)][ValidateSet("Cold","vMotion","VR","bulkVMotion")][String]$MigrationType, + [Parameter(Mandatory=$false)]$ValidateOnly=$true + ) + + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { + $hcxEndpointInfo = Get-HcxEndpoint -cloudVCConnection $cloudVCConnection + + $inputArray = @() + foreach ($vm in $VMs) { + $vmView = Get-View -Server $onPremVCConnection -ViewType VirtualMachine -Filter @{"name"=$vm} + + $cloudResourcePoolName = "Compute-ResourcePool" + $cloudFolderName = "Workloads" + $cloudDatastoreName = "WorkloadDatastore" + $cloudDatacenterName = "SDDC-Datacenter" + + $cloudResourcePool = (Get-ResourcePool -Server $cloudVCConnection -Name $cloudResourcePoolName).ExtensionData + $cloudFolder = (Get-Folder -Server $cloudVCConnection -Name $cloudFolderName).ExtensionData + $cloudDatastore = (Get-Datastore -Server $cloudVCConnection -Name $cloudDatastoreName).ExtensionData + $cloudDatacenter = (Get-Datacenter -Server $cloudVCConnection -Name $cloudDatacenterName).ExtensionData + + $placementArray = @() + $placement = @{ + "containerType"="folder"; + "containerId"=$cloudFolder.MoRef.Value; + "containerName"=$cloudFolderName; + } + $placementArray+=$placement + $placement = @{ + "containerType"="resourcePool"; + "containerId"=$cloudResourcePool.MoRef.Value; + "containerName"=$cloudResourcePoolName; + } + $placementArray+=$placement + $placement = @{ + "containerType"="dataCenter"; + "containerId"=$cloudDatacenter.MoRef.Value; + "containerName"=$cloudDatacenterName; + } + $placementArray+=$placement + + $networkArray = @() + $vmNetworks = $vmView.Network + foreach ($vmNetwork in $vmNetworks) { + if($vmNetwork.Type -eq "Network") { + $sourceNetworkType = "VirtualNetwork" + } else { $sourceNetworkType = $vmNetwork.Type } + + $sourceNetworkRef = New-Object VMware.Vim.ManagedObjectReference + $sourceNetworkRef.Type = $vmNetwork.Type + $sourceNetworkRef.Value = $vmNetwork.Value + $sourceNetwork = Get-View -Server $onPremVCConnection $sourceNetworkRef + + $sourceNetworkName = $sourceNetwork.Name + $destNetworkName = $NetworkMappings[$sourceNetworkName] + + $destNetwork = Get-VDPortGroup -Server $cloudVCConnection -Name $destNetworkName + + if($destNetwork.Id -match "DistributedVirtualPortgroup") { + $destNetworkType = "DistributedVirtualPortgroup" + $destNetworkId = ($destNetwork.Id).Replace("DistributedVirtualPortgroup-","") + } else { + $destNetworkType = "Network" + $destNetworkId = ($destNetwork.Id).Replace("Network-","") + } + + $tmp = @{ + "srcNetworkType" = $sourceNetworkType; + "srcNetworkValue" = $vmNetwork.Value; + "srcNetworkHref" = $vmNetwork.Value; + "srcNetworkName" = $sourceNetworkName; + "destNetworkType" = $destNetworkType; + "destNetworkValue" = $destNetworkId; + "destNetworkHref" = $destNetworkId; + "destNetworkName" = $destNetworkName; + } + $networkArray+=$tmp + } + + $input = @{ + "input" = @{ + "migrationType"=$MigrationType; + "entityDetails" = @{ + "entityId"=$vmView.MoRef.Value; + "entityName"=$vm; + } + "source" = @{ + "endpointType"=$hcxEndpointInfo.SourceEndpointType; + "endpointId"=$hcxEndpointInfo.SourceEndpointId; + "endpointName"=$hcxEndpointInfo.SourceEndpointName; + "resourceType"=$hcxEndpointInfo.SourceResourceType; + "resourceId"=$hcxEndpointInfo.SourceResourceId; + "resourceName"=$hcxEndpointInfo.SourceResourceName; + } + "destination" = @{ + "endpointType"=$hcxEndpointInfo.RemoteEndpointType; + "endpointId"=$hcxEndpointInfo.RemoteEndpointId; + "endpointName"=$hcxEndpointInfo.RemoteEndpointName; + "resourceType"=$hcxEndpointInfo.RemoteResourceType; + "resourceId"=$hcxEndpointInfo.RemoteResourceId; + "resourceName"=$hcxEndpointInfo.RemoteResourceName; + } + "placement" = $placementArray + "storage" = @{ + "datastoreId"=$cloudDatastore.Moref.Value; + "datastoreName"=$cloudDatastoreName; + "diskProvisionType"="thin"; + } + "networks" = @{ + "retainMac" = $true; + "targetNetworks" = $networkArray; + } + "decisionRules" = @{ + "removeSnapshots"=$true; + "removeISOs"=$true; + "forcePowerOffVm"=$false; + "upgradeHardware"=$false; + "upgradeVMTools"=$false; + } + "schedule" = @{} + } + } + $inputArray+=$input + } + + $spec = @{ + "migrations"=$inputArray + } + $body = $spec | ConvertTo-Json -Depth 20 + + Write-Verbose -Message "Pre-Validation JSON Spec: $body" + $hcxMigrationValiateUrl = $global:hcxConnection.Server+ "/migrations?action=validate" + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxMigrationValiateUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxMigrationValiateUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" + } + + if($requests.StatusCode -eq 200) { + $validationErrors = ($requests.Content|ConvertFrom-Json).migrations.validationInfo.validationResult.errors + if($validationErrors -ne $null) { + Write-Host -Foreground Red "`nThere were validation errors found for this HCX Migration Spec ..." + foreach ($message in $validationErrors) { + Write-Host -Foreground Yellow "`t" $message.message + } + } else { + Write-Host -Foreground Green "`nHCX Pre-Migration Spec successfully validated" + if($ValidateOnly -eq $false) { + try { + $startDateTime = $StartTime | Get-Date + } catch { + Write-Host -Foreground Red "Invalid input for -StartTime, please check for typos" + exit + } + + try { + $endDateTime = $EndTime | Get-Date + } catch { + Write-Host -Foreground Red "Invalid input for -EndTime, please check for typos" + exit + } + + $offset = (Get-TimeZone).GetUtcOffset($startDateTime).TotalMinutes + $offset = [int]($offSet.toString().replace("-","")) + + $schedule = @{ + scheduledFailover = $true; + startYear = $startDateTime.Year; + startMonth = $startDateTime.Month; + startDay = $startDateTime.Day; + startHour = $startDateTime | Get-Date -UFormat %H; + startMinute = $startDateTime | Get-Date -UFormat %M; + endYear = $endDateTime.Year; + endMonth = $endDateTime.Month; + endDay = $endDateTime.Day; + endHour = $endDateTime | Get-Date -UFormat %H; + endMinute = $endDateTime | Get-Date -UFormat %M; + timezoneOffset = $offset; + } + + foreach ($migration in $spec.migrations) { + $migration.input.schedule = $schedule + } + $body = $spec | ConvertTo-Json -Depth 8 + + Write-Verbose -Message "Validated JSON Spec: $body" + $hcxMigrationStartUrl = $global:hcxConnection.Server+ "/migrations?action=start" + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxMigrationStartUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxMigrationStartUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" + } + + if($requests.StatusCode -eq 200) { + $migrationIds = ($requests.Content | ConvertFrom-Json).migrations.migrationId + Write-Host -ForegroundColor Green "Starting HCX Migration ..." + foreach ($migrationId in $migrationIds) { + Write-Host -ForegroundColor Green "`tMigrationID: $migrationId" + } + } else { + Write-Error "Failed to start HCX Migration" + } + } + } + } else { + Write-Error "Failed to validate HCX Migration spec" + } + } +} + +Function Get-HcxMigration { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/24/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + List all HCX Migrations that are in-progress, have completed or failed + .DESCRIPTION + This cmdlet lists ist all HCX Migrations that are in-progress, have completed or failed + .EXAMPLE + List all HCX Migrations + + Get-HcxMigration + .EXAMPLE + List all running HCX Migrations + + Get-HcxMigration -RunningMigrations + .EXAMPLE + List all HCX Migrations + + Get-HcxMigration -MigrationId +#> + Param ( + [Parameter(Mandatory=$false)][String]$MigrationId, + [Switch]$RunningMigrations + ) + + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { + $spec = @{} + $body = $spec | ConvertTo-Json + + $hcxQueryUrl = $global:hcxConnection.Server + "/migrations?action=query" + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxQueryUrl -Method POST -body $body -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $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 } + } + + if($RunningMigrations){ + $migrations = $migrations | where { $_.jobInfo.state -ne "MIGRATE_FAILED" -and $_.jobInfo.state -ne "MIGRATE_CANCELED"-and $_.jobInfo.state -ne "MIGRATED" } + } + + $results = @() + foreach ($migration in $migrations) { + $tmp = [pscustomobject] @{ + ID = $migration.migrationId; + VM = $migration.migrationInfo.entityDetails.entityName; + State = $migration.jobInfo.state; + Progress = ($migration.migrationInfo.progressDetails.progressPercentage).toString() + " %"; + DataCopied = ([math]::round($migration.migrationInfo.progressDetails.diskCopyBytes/1Gb, 2)).toString() + " GB"; + Message = $migration.migrationInfo.message; + InitiatedBy = $migration.jobInfo.username; + CreateDate = $migration.jobInfo.creationDate; + LastUpdated = $migration.jobInfo.lastUpdated; + } + $results+=$tmp + } + $results + } +} + +Function Connect-HcxVAMI { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Connect to the HCX Enterprise Manager VAMI + .DESCRIPTION + This cmdlet connects to the HCX Enterprise Manager VAMI + .EXAMPLE + Connect-HcxVAMI -Server $HCXServer -Username $VAMIUsername -Password $VAMIPassword +#> + Param ( + [Parameter(Mandatory=$true)][String]$Server, + [Parameter(Mandatory=$true)][String]$Username, + [Parameter(Mandatory=$true)][String]$Password + ) + + $pair = "${Username}:${Password}" + $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair) + $base64 = [System.Convert]::ToBase64String($bytes) + $basicAuthValue = "Basic $base64" + + $headers = @{ + "authorization"="$basicAuthValue" + "Content-Type"="application/json" + "Accept"="application/json" + } + + $global:hcxVAMIConnection = new-object PSObject -Property @{ + 'Server' = "https://${server}:9443"; + 'headers' = $headers + } + $global:hcxVAMIConnection +} + +Function Get-HcxVCConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the onPrem vCenter Server registered with HCX Manager + .DESCRIPTION + This cmdlet returns the onPrem vCenter Server registered with HCX Manager + .EXAMPLE + 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" + + if($PSVersionTable.PSEdition -eq "Core") { + $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $vcData = ($vcRequests.content | ConvertFrom-Json).data.items + + $tmp = [pscustomobject] @{ + Name = $vcData.config.name; + Version = $vcData.config.version; + Build = $vcData.config.buildNumber; + UUID = $vcData.config.vcuuid; + HCXUUID = $vcData.config.uuid; + } + $tmp + } +} + +Function Set-HcxLicense { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Activate HCX Manager with HCX Cloud + .DESCRIPTION + This cmdlet activates HCX Manager with HCX Cloud + .EXAMPLE + Set-HcxLicense -LicenseKey +#> + Param ( + [Parameter(Mandatory=$True)]$LicenseKey + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $hcxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/hcx" + $method = "POST" + + $hcxConfig = @{ + config = @{ + url = "https://connect.hcx.vmware.com"; + activationKey = $LicenseKey; + } + } + + $payload = @{ + data = @{ + items = @($hcxConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$vcConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $hcxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $hcxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered HCX Manager with HCX Cloud" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items } + } else { + Write-Error "Failed to registered HCX Manager" + } + } +} + +Function Set-HcxVCConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Registers on-prem vCenter Server with HCX Manager + .DESCRIPTION + This cmdlet registers on-prem vCenter Server with HCX Manager + .EXAMPLE + Set-HcxVC -VIServer -VIUsername -VIPassword +#> + Param ( + [Parameter(Mandatory=$True)]$VIServer, + [Parameter(Mandatory=$True)]$PSCServer, + [Parameter(Mandatory=$True)]$VIUsername, + [Parameter(Mandatory=$True)]$VIPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI 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" + $method = "POST" + + + $bytes = [System.Text.Encoding]::ASCII.GetBytes($VIPassword) + $base64 = [System.Convert]::ToBase64String($bytes) + + $vcConfig = @{ + config = @{ + url = "https://$VIServer"; + userName = $VIUsername; + password = $base64; + } + } + + $payload = @{ + data = @{ + items = @($vcConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$vcConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $vcConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $vcConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered vCenter Server with HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + + $pscConfig = @{ + config = @{ + lookupServiceUrl = "https://$PSCServer" + providerType = "PSC" + } + } + + $payload = @{ + data = @{ + items = @($pscConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$pscConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $pscConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $pscConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered PSC with HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + + } else { + Write-Error "Failed to registered PSC Server" + } + } else { + Write-Error "Failed to registered vCenter Server" + } + } +} + +Function Get-HcxNSXConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the onPrem NSX-V Server registered with HCX Manager + .DESCRIPTION + This cmdlet returns the onPrem NSX-V Server registered with HCX Manager + .EXAMPLE + Get-HcxNSXConfig +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $nsxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/nsx" + + if($PSVersionTable.PSEdition -eq "Core") { + $nsxRequests = Invoke-WebRequest -Uri $nsxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $nsxRequests = Invoke-WebRequest -Uri $nsxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $nsxData = ($nsxRequests.content | ConvertFrom-Json).data.items + + $tmp = [pscustomobject] @{ + Name = $nsxData.config.url; + Version = $nsxData.config.version; + HCXUUID = $nsxData.config.uuid; + } + $tmp + } +} + +Function Set-HcxNSXConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Registers on-prem NSX-V Server with HCX Manager + .DESCRIPTION + This cmdlet registers on-prem NSX-V Server with HCX Manager + .EXAMPLE + Set-HcxNSXConfig -NSXServer -NSXUsername -NSXPassword +#> + Param ( + [Parameter(Mandatory=$True)]$NSXServer, + [Parameter(Mandatory=$True)]$NSXUsername, + [Parameter(Mandatory=$True)]$NSXPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $nsxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/nsx" + $method = "POST" + + $bytes = [System.Text.Encoding]::ASCII.GetBytes($NSXPassword) + $base64 = [System.Convert]::ToBase64String($bytes) + + $nsxConfig = @{ + config = @{ + url = "https://$NSXServer"; + userName = $NSXUsername; + password = $base64; + } + } + + $payload = @{ + data = @{ + items = @($nsxConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$nsxConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $nsxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $nsxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered NSX Server with HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + } else { + Write-Error "Failed to registered NSX Server" + } + return $config + } +} + +Function Get-HcxCity { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the available HCX Location based on user City and Country input + .DESCRIPTION + This cmdlet returns the available HCX Location based on user City and Country input + .EXAMPLE + Get-HcxCity -City -Country + #> + Param ( + [Parameter(Mandatory=$True)]$City, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $citySearchUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/searchCities?searchString=$City" + $method = "GET" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$citySearchUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully returned results for City search: $City" + + $cityDetails = ($results.Content | ConvertFrom-Json).items + $cityDetails | select City,Country + } else { + Write-Error "Failed to search for city $City" + } + } + } + +Function Get-HcxLocation { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the registered City/Country location for HCX Manager + .DESCRIPTION + This cmdlet returns the registered City/Country location for HCX Manager + .EXAMPLE + Get-HcxLocation +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $locationConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/location" + + if($PSVersionTable.PSEdition -eq "Core") { + $locationRequests = Invoke-WebRequest -Uri $locationConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $locationRequests = Invoke-WebRequest -Uri $locationConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + ($locationRequests.content | ConvertFrom-Json) + } +} + +Function Set-HcxLocation { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Register HCX Manager to a specific City/Country + .DESCRIPTION + This cmdlet register HCX Manager to a specific City/Country + .EXAMPLE + Set-HcxLocation -City -Country +#> + Param ( + [Parameter(Mandatory=$True)]$City, + [Parameter(Mandatory=$True)]$Country, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $citySearchUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/searchCities?searchString=$City" + $method = "GET" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$citySearchUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).items } + + $locationConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/location" + $method = "PUT" + + $cityDetails = ($results.Content | ConvertFrom-Json).items + $cityDetails = $cityDetails | where { $_.city -eq $City -and $_.country -match $Country } + + if(-not $cityDetails) { + Write-Host -ForegroundColor Red "Invalid input for City and/or Country, please provide the exact input from Get-HcxCity cmdlet" + break + } + + $locationConfig = @{ + city = $cityDetails.city; + country = $cityDetails.country; + province = $cityDetails.province; + latitude = $cityDetails.latitude; + longitude = $cityDetails.longitude; + } + + $body = $locationConfig | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$locationConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $locationConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $locationConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 204) { + Write-Host -ForegroundColor Green "Successfully registered datacenter location $City to HCX Manager" + } else { + Write-Error "Failed to registerd datacenter location in HCX Manager" + } + } else { + Write-Error "Failed to search for city $City" + } + } +} +Function Get-HcxRoleMapping { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the System Admin and Enterprise User Group role mappings for HCX Manager + .DESCRIPTION + This cmdlet returns the System Admin and Enterprise User Group role mappings for HCX Manager + .EXAMPLE + Get-HcxRoleMapping +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + + if($PSVersionTable.PSEdition -eq "Core") { + $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + ($roleRequests.content | ConvertFrom-Json) + } +} + +Function Set-HcxRoleMapping { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Configures the System Admin and Enterprise User Group role mappings for HCX Manager + .DESCRIPTION + This cmdlet configures the System Admin and Enterprise User Group role mappings for HCX Manager + .EXAMPLE + Set-HcxRoleMapping -SystemAdminGroup @("DOMAIN\GROUP") -EnterpriseAdminGroup @("DOMAIN\GROUP") +#> + Param ( + [Parameter(Mandatory=$True)][String[]]$SystemAdminGroup, + [Parameter(Mandatory=$True)][String[]]$EnterpriseAdminGroup, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + $method = "PUT" + + $roleConfig = @() + $systemAdminRole = @{ + role = "System Administrator"; + userGroups = $SystemAdminGroup + } + $enterpriseAdminRole = @{ + role = "Enterprise Administrator" + userGroups = $EnterpriseAdminGroup + } + $roleConfig+=$systemAdminRole + $roleConfig+=$enterpriseAdminRole + + $body = $roleConfig | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$locationConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully updated vSphere Group Mappings in HCX Manager" + } else { + Write-Error "Failed to update vSphere Group Mappings" + } + } +} + +Function Get-HcxProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 10/31/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the proxy settings for HCX Manager + .DESCRIPTION + This cmdlet returns the proxy settings for HCX Manager + .EXAMPLE + Get-HcxProxy +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $proxyConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy" + + if($PSVersionTable.PSEdition -eq "Core") { + $proxyRequests = Invoke-WebRequest -Uri $proxyConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $proxyRequests = Invoke-WebRequest -Uri $proxyConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $proxySettings = ($proxyRequests.content | ConvertFrom-Json).data.items + if($proxyRequests) { + $proxySettings.config + } + } +} + +Function Set-HcxProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 10/31/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Configure proxy settings on HCX Manager + .DESCRIPTION + This cmdlet configure proxy settings on HCX Manager + .EXAMPLE + Set-HcxProxy -ProxyServer proxy.vmware.com -ProxyPort 3124 + .EXAMPLE + Set-HcxProxy -ProxyServer proxy.vmware.com -ProxyPort 3124 -ProxyUser foo -ProxyPassword bar +#> + Param ( + [Parameter(Mandatory=$True)]$ProxyServer, + [Parameter(Mandatory=$True)]$ProxyPort, + [Parameter(Mandatory=$False)]$ProxyUser, + [Parameter(Mandatory=$False)]$ProxyPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $proxyConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy" + $method = "POST" + + if(-not $ProxyUser) { $ProxyUser = ""} + if(-not $ProxyPassword) { $ProxyPassword = ""} + + $proxyConfig = @{ + config = @{ + proxyHost = "$ProxyServer"; + proxyPort = "$ProxyPort"; + nonProxyHosts = ""; + userName = "$ProxyUser"; + password = "$ProxyPassword"; + } + } + + $payload = @{ + data = @{ + items = @($proxyConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$proxyConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $proxyConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $proxyConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully updated proxy settings in HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + } else { + Write-Error "Failed to update proxy settings" + } + } +} + +Function Remove-HcxProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 10/31/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the proxy settings for HCX Manager + .DESCRIPTION + This cmdlet returns the proxy settings for HCX Manager + .EXAMPLE + Remove-HcxProxy +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy" + + if($PSVersionTable.PSEdition -eq "Core") { + $proxyRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $proxyRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $proxySettings = ($proxyRequests.content | ConvertFrom-Json).data.items + if($proxyRequests) { + $proxyUUID = $proxySettings.config.UUID + + $deleteProxyConfigURl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy/$proxyUUID" + $method = "DELETE" + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $deleteProxyConfigURl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $deleteProxyConfigURl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully deleted proxy settings in HCX Manager" + } else { + Write-Error "Failed to delete proxy settings" + } + } else { + Write-Warning "No proxy settings were configured" + } + } +} \ No newline at end of file diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 4779b9b..6f176b4 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -10000,63 +10000,75 @@ function Reset-HVMachine { $services.machine.Machine_ResetMachines($machine.id) } } -function Remove-HVMachine(){ +function Remove-HVMachine { <# .Synopsis - Remove a Horizon View desktop or desktops. - + Remove a Horizon View desktop or desktops. + .DESCRIPTION - Deletes a VM or an array of VM's from Horizon. Utilizes an Or query filter to match machine names. + Deletes a VM or an array of VM's from Horizon. Utilizes an Or query filter to match machine names. .PARAMETER HVServer - The Horizon server where the machine to be deleted resides.Parameter is not mandatory, - but if you do not specify the server, than make sure you are connected to a Horizon server + The Horizon server where the machine to be deleted resides. Parameter is not mandatory, + but if you do not specify the server, than make sure you are connected to a Horizon server first with connect-hvserver. .PARAMETER MachineNames - The name or names of the machine(s) to be deleted. Accepts a single VM or an array of VM names.This is a mandatory parameter. + The name or names of the machine(s) to be deleted. Accepts a single VM or an array of VM names.This is a mandatory parameter. + + .PARAMETER DeleteFromDisk + Determines whether the Machine VM should be deleted from vCenter Server. This is only applicable for managed machines. + This must always be true for machines in linked and instant clone desktops. + This defaults to true for linked and instant clone machines and false for all other types. .EXAMPLE - remove-HVMachine -HVServer 'horizonserver123' -MachineNames 'LAX-WIN10-002' - Deletes VM 'LAX-WIN10-002' from HV Server 'horizonserver123' + Remove-HVMachine -HVServer 'horizonserver123' -MachineNames 'LAX-WIN10-002' + Deletes VM 'LAX-WIN10-002' from HV Server 'horizonserver123' .EXAMPLE - remove-HVMachine -HVServer 'horizonserver123' -MachineNames $machines - Deletes VM's contained within an array of machine names from HV Server 'horizonserver123' - + Remove-HVMachine -HVServer 'horizonserver123' -MachineNames $machines + Deletes VM's contained within an array of machine names from HV Server 'horizonserver123' + + .EXAMPLE + Remove-HVMachine -HVServer 'horizonserver123' -MachineNames 'ManualVM01' -DeleteFromDisk:$false + Deletes VM 'ManualVM01' from Horizon inventory, but not from vSphere. Note this only works for Full Clone VMs. + .NOTES Author : Jose Rodriguez Author email : jrodsguitar@gmail.com Version : 1.0 - + ===Tested Against Environment==== Horizon View Server Version : 7.1.1 PowerCLI Version : PowerCLI 6.5, PowerCLI 6.5.1 PowerShell Version : 5.0 #> - - [CmdletBinding( + + [CmdletBinding( SupportsShouldProcess = $true, ConfirmImpact = 'High' )] - - param( - + + param( + [Parameter(Mandatory = $true)] [array] - $MachineNames, - + $MachineNames, + + [Parameter(Mandatory = $false)] + [switch]$DeleteFromDisk = $true, + [Parameter(Mandatory = $false)] $HVServer = $null - ) + ) #Connect to HV Server $services = Get-ViewAPIService -HVServer $HVServer - - if ($null -eq $services) { - Write-Error "Could not retrieve ViewApi services from connection object" + +if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" break - } + } #Connect to Query Service $queryService = New-Object 'Vmware.Hv.QueryServiceService' @@ -10108,9 +10120,9 @@ $trys = 0 foreach($session in $deleteMachine.base.session){ $sessions = $null - [VMware.Hv.SessionId[]]$sessions += $session - - } + [VMware.Hv.SessionId[]]$sessions += $session + + } try{ @@ -10122,8 +10134,8 @@ $trys = 0 #Wait more for Sessions to end - Start-Sleep -Seconds 5 - + Start-Sleep -Seconds 5 + } catch{ @@ -10133,39 +10145,39 @@ $trys = 0 write-host ($deleteMachine.base.Name -join "`n") start-sleep -seconds 5 - + } - - if(($trys -le 10)){ - + + if(($trys -le 10)){ + write-host "`n" write-host "Retrying Logoffs: $trys times" #Recheck existing sessions $deleteMachine = $machineService.Machine_GetInfos($services,$deleteThisMachine.Id) - + } - - $trys++ + + $trys++ } until((!$deleteMachine.base.session.id) -or ($trys -gt 10)) - + } #Create delete spec for the DeleteMachines method $deleteSpec = [VMware.Hv.MachineDeleteSpec]::new() -$deleteSpec.DeleteFromDisk = $true +$deleteSpec.DeleteFromDisk = $DeleteFromDisk $deleteSpec.ArchivePersistentDisk = $false - + #Delete the machines -write-host "Attempting to Delete:" +write-host "Attempting to Delete:" Write-Output ($deleteMachine.base.Name -join "`n") $bye = $machineService.Machine_DeleteMachines($services,$deleteMachine.id,$deleteSpec) [System.gc]::collect() - -} + +} function get-hvhealth { <# diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 new file mode 100644 index 0000000..9eca367 --- /dev/null +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -0,0 +1,88 @@ +# +# Module manifest for module 'VMware.VMC.NSXT' +# +# Generated by: wlam@vmware.com +# +# Generated on: 09/11/18 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'VMware.VMC.NSXT.psm1' + +# Version number of this module. +ModuleVersion = '1.0.0' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = 'c094608a-7480-4751-a14c-c9dd68870607' + +# Author of this module +Author = 'William Lam' + +# Company or vendor of this module +CompanyName = 'VMware' + +# Copyright statement for this module +Copyright = '(c) 2018 VMware. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' + +# Minimum version of the Windows PowerShell engine required by this module +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' +# 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 = @() + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases 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 aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} \ No newline at end of file diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 new file mode 100644 index 0000000..3bfdfe3 --- /dev/null +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -0,0 +1,889 @@ +Function Connect-NSXTProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Retrieves NSX-T Proxy URL + acquire CSP Access Token to then be used with NSXT-T Policy API + .DESCRIPTION + This cmdlet creates $global:nsxtProxyConnection object containing the NSX-T Proxy URL along with CSP Token + .EXAMPLE + Connect-NSXTProxy -RefreshToken $RefreshToken -OrgName $OrgName -SDDCName $SDDCName + .NOTES + You must be logged into VMC using Connect-VmcServer cmdlet +#> + 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) + if($sddc.resource_config.nsxt) { + $nsxtProxyURL = $sddc.resource_config.nsx_api_public_endpoint_url + } else { + Write-Host -ForegroundColor Red "This is not an NSX-T based SDDC" + break + } + } + + $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:nsxtProxyConnection = new-object PSObject -Property @{ + 'Server' = $nsxtProxyURL + 'headers' = $headers + } + $global:nsxtProxyConnection +} + +Function Get-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Segments (Logical Networks) + .DESCRIPTION + This cmdlet retrieves all NSX-T Segments (Logical Networks) + .EXAMPLE + Get-NSXTSegment + .EXAMPLE + Get-NSXTSegment -Name "sddc-cgw-network-1" +#> + Param ( + [Parameter(Mandatory=$False)]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $segmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$segmentsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $segmentsURL -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 + } + + if($requests.StatusCode -eq 200) { + $segments = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $segments = $segments | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($segment in $segments) { + + $subnets = $segment.subnets + $network = $subnets.network + $gateway = $subnets.gateway_addresses + $dhcpRange = $subnets.dhcp_ranges + + $tmp = [pscustomobject] @{ + Name = $segment.display_name; + ID = $segment.Id; + Network = $network; + Gateway = $gateway; + DHCPRange = $dhcpRange; + } + $results+=$tmp + } + $results + } else { + Write-Error "Failed to retrieve NSX-T Segments" + } + } +} + +Function New-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Segment (Logical Networks) + .DESCRIPTION + This cmdlet creates a new NSX-T Segment (Logical Networks) + .EXAMPLE + New-NSXTSegment -Name "sddc-cgw-network-4" -Gateway "192.168.4.1" -Prefix "24" -DHCP -DHCPRange "192.168.4.2-192.168.4.254" +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$True)]$Gateway, + [Parameter(Mandatory=$True)]$Prefix, + [Parameter(Mandatory=$False)]$DHCPRange, + [Switch]$DHCP, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + if($DHCP) { + $dhcpConf = @($DHCPRange) + } else { + $dhcpConf = @($null) + } + + $subnets = @{ + gateway_addresses = @($gateway); + prefix_len = $Prefix; + dhcp_ranges = $dhcpConf + } + + $payload = @{ + display_name = $Name; + subnets = @($subnets) + } + $body = $payload | ConvertTo-Json -depth 4 + + $method = "PUT" + $newSegmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newSegmentsURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newSegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newSegmentsURL -Body $body -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Segment $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Segment" + + } + } +} + +Function Remove-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Segment (Logical Networks) + .DESCRIPTION + This cmdlet removes an NSX-T Segment (Logical Networks) + .EXAMPLE + Remove-NSXTSegment -Id "sddc-cgw-network-4" +#> + 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" + $deleteSegmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteSegmentsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteSegmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteSegmentsURL -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T Segment $Name" + } else { + Write-Error "Failed to remove NSX-T Segments" + + } + } +} + +Function Get-NSXTFirewall { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Firewall Rules on MGW or CGW + .DESCRIPTION + This cmdlet retrieves all NSX-T Firewall Rules on MGW or CGW + .EXAMPLE + Get-NSXTFirewall -GatewayType MGW + .EXAMPLE + Get-NSXTFirewall -GatewayType MGW -Name "Test" +#> + param( + [Parameter(Mandatory=$false)][String]$Name, + [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" + $edgeFirewallURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/edge-communication-maps/default" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$edgeFirewallURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $edgeFirewallURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $edgeFirewallURL -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 + } + + if($requests.StatusCode -eq 200) { + $rules = ($requests.Content | ConvertFrom-Json).communication_entries + + if ($PSBoundParameters.ContainsKey("Name")){ + $rules = $rules | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($rule in $rules | Sort-Object -Property sequence_number) { + $sourceGroups = $rule.source_groups + $source = @() + foreach ($sourceGroup in $sourceGroups) { + if($sourceGroup -eq "ANY") { + $source += $sourceGroup + break + } else { + $sourceGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $sourceGroup + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$sourceGroupURL`n" + } + try { + $requests = Invoke-WebRequest -Uri $sourceGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } 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 + } + $group = ($requests.Content | ConvertFrom-Json) + $source += $group.display_name + } + } + + $destinationGroups = $rule.destination_groups + $destination = @() + foreach ($destinationGroup in $destinationGroups) { + if($destinationGroup -eq "ANY") { + $destination += $destinationGroup + break + } else { + $destionationGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $destinationGroup + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$destionationGroupURL`n" + } + try { + $requests = Invoke-WebRequest -Uri $destionationGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } 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 + } + $group = ($requests.Content | ConvertFrom-Json) + $destination += $group.display_name + } + } + + $serviceGroups = $rule.services + $service = @() + foreach ($serviceGroup in $serviceGroups) { + if($serviceGroup -eq "ANY") { + $service += $serviceGroup + break + } else { + $serviceGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $serviceGroup + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$serviceGroupURL`n" + } + try { + $requests = Invoke-WebRequest -Uri $serviceGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } 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 + } + $group = ($requests.Content | ConvertFrom-Json) + $service += $group.display_name + } + } + + $tmp = [pscustomobject] @{ + SequenceNumber = $rule.sequence_number; + Name = $rule.display_name; + ID = $rule.id; + Source = $source; + Destination = $destination; + Services = $service; + Action = $rule.action; + } + $results+=$tmp + } + $results + + } else { + Write-Error "Failed to retrieve NSX-T Firewall Rules" + } + } +} + +Function New-NSXTFirewall { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Firewall Rule on MGW or CGW + .DESCRIPTION + This cmdlet creates a new NSX-T Firewall Rule on MGW or CGW + .EXAMPLE + New-NSXTFirewall -GatewayType MGW -Name TEST -Id TEST -SourceGroupId ESXI -DestinationGroupId ANY -Service ANY -Logged $true -SequenceNumber 7 -Action ALLOW +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Parameter(Mandatory=$True)]$Id, + [Parameter(Mandatory=$True)]$SequenceNumber, + [Parameter(Mandatory=$True)]$SourceGroupId, + [Parameter(Mandatory=$True)]$DestinationGroupId, + [Parameter(Mandatory=$True)]$Service, + [Parameter(Mandatory=$True)][ValidateSet("ALLOW","DENY")]$Action, + [Parameter(Mandatory=$false)][Boolean]$Logged=$false, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + + if($DestinationGroupId -eq "ANY") { + $destinationGroups = $DestinationGroupId + } else { + $destinationGroups = "/infra/domains/$($GatewayType.toLower())/groups/$DestinationGroupId" + } + + $sourceGroups = @() + foreach ($group in $SourceGroupId) { + $tmp = "/infra/domains/$($GatewayType.toLower())/groups/$group" + $sourceGroups+= $tmp + } + + $services = @() + foreach ($serviceName in $Service) { + if($serviceName -eq "ANY") { + $tmp = "ANY" + } else { + $tmp = "/infra/services/$serviceName" + } + $services+=$tmp + } + + $payload = @{ + display_name = $Name; + resource_type = "CommunicationEntry"; + id = $Id; + sequence_number = $SequenceNumber; + destination_groups = @($destinationGroups); + source_groups = $sourceGroups; + logged = $Logged; + scope = @("/infra/labels/$($GatewayType.toLower())"); + services = $services; + action = $Action; + } + + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $newFirewallURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/edge-communication-maps/default/communication-entries/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newFirewallURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newFirewallURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newFirewallURL -Body $body -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Firewall Rule $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Firewall Rule" + } + } +} + +Function Remove-NSXTFirewall { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Firewall Rule on MGW or CGW + .DESCRIPTION + This cmdlet removes an NSX-T Firewall Rule on MGW or CGW + .EXAMPLE + Remove-NSXTFirewall -Id TEST -GatewayType MGW -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [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 = "DELETE" + $deleteGgroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/edge-communication-maps/default/communication-entries/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteGgroupURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T Firewall Rule $Name" + } else { + Write-Error "Failed to create new NSX-T Firewall Rule" + } + } +} + +Function Get-NSXTGroup { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Groups for MGW or CGW + .DESCRIPTION + This cmdlet retrieves all NSX-T Groups for MGW or CGW + .EXAMPLE + Get-NSXTGroup -GatewayType MGW + .EXAMPLE + Get-NSXTGroup -GatewayType MGW -Name "Test" +#> + param( + [Parameter(Mandatory=$false)][String]$Name, + [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" + $edgeFirewallGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/groups" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$edgeFirewallGroupsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $edgeFirewallGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $edgeFirewallGroupsURL -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 + } + + 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.tags.tag -eq $null) { + $groupType = "USER_DEFINED" + } else { $groupType = $group.tags.tag } + + $members = @() + foreach ($member in $group.expression) { + if($member.ip_addresses) { + $members += $member.ip_addresses + } else { + if($member.resource_type -eq "Condition") { + $members += $member.value + } + } + } + + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Type = $groupType; + Members = $members; + } + $results+=$tmp + } + $results + } else { + Write-Error "Failed to retrieve NSX-T Groups" + } + } +} + +Function New-NSXTGroup { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Group on MGW or CGW + .DESCRIPTION + This cmdlet creates a new NSX-T Firewall Rule on MGW or CGW + .EXAMPLE + New-NSXTGroup -GatewayType MGW -Name Foo -IPAddress @("172.31.0.0/24") +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Parameter(Mandatory=$True)][String[]]$IPAddress, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $expression = @{ + resource_type = "IPAddressExpression"; + ip_addresses = $IPAddress; + } + + $payload = @{ + display_name = $Name; + expression = @($expression); + } + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $newGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/groups/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newGroupURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newGroupURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newGroupURL -Body $body -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Group $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Group" + } + } +} + +Function Remove-NSXTGroup { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Group + .DESCRIPTION + This cmdlet removes an NSX-T Group + .EXAMPLE + Remove-NSXTGroup -Id Foo -GatewayType MGW -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [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 = "DELETE" + $deleteGgroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/groups/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteGgroupURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T Group $Name" + } else { + Write-Error "Failed to create new NSX-T Group" + } + } +} + +Function Get-NSXTService { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Services + .DESCRIPTION + This cmdlet retrieves all NSX-T Services + .EXAMPLE + Get-NSXTService + .EXAMPLE + Get-NSXTService -Name "WINS" +#> + 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" + $serviceGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/services" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$serviceGroupsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $serviceGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $serviceGroupsURL -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 + } + + if($requests.StatusCode -eq 200) { + $services = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $services = $services | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($service in $services | Sort-Object -Propert display_name) { + $serviceEntry = $service.service_entries + $serviceProtocol = $serviceEntry.l4_protocol + $serviceSourcePorts = $serviceEntry.source_ports + $serviceDestinationPorts = $serviceEntry.destination_ports + + $tmp = [pscustomobject] @{ + Name = $service.display_name; + Id = $service.id; + Protocol = $serviceProtocol; + Source = $serviceSourcePorts; + Destination = $serviceDestinationPorts; + } + $results += $tmp + } + $results + } else { + Write-Error "Failed to retrieve NSX-T Services" + } + } +} + +Function New-NSXTService { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Service + .DESCRIPTION + This cmdlet creates a new NSX-T Service + .EXAMPLE + New-NSXTService -Name "MyHTTP2" -Protocol TCP -DestinationPorts @("8080","8081") +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$True)][String[]]$DestinationPorts, + [Parameter(Mandatory=$True)][ValidateSet("TCP","UDP")][String]$Protocol, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $serviceEntry = @() + $entry = @{ + display_name = $name + "-$destinationPort" + resource_type = "L4PortSetServiceEntry"; + destination_ports = @($DestinationPorts); + l4_protocol = $Protocol; + } + $serviceEntry+=$entry + + $payload = @{ + display_name = $Name; + service_entries = $serviceEntry; + } + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $newServiceURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/services/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newServiceURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newServiceURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newServiceURL -Body $body -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 + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Service $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Service" + } + } +} \ No newline at end of file diff --git a/Modules/VMware.VMC/VMware.VMC.psd1 b/Modules/VMware.VMC/VMware.VMC.psd1 index b33fca9..105fec0 100755 Binary files a/Modules/VMware.VMC/VMware.VMC.psd1 and b/Modules/VMware.VMC/VMware.VMC.psd1 differ diff --git a/Modules/VMware.VMC/VMware.VMC.psm1 b/Modules/VMware.VMC/VMware.VMC.psm1 index 7b64047..de3d1ab 100644 --- a/Modules/VMware.VMC/VMware.VMC.psm1 +++ b/Modules/VMware.VMC/VMware.VMC.psm1 @@ -320,7 +320,6 @@ Function Get-VMCSDDCVersion { } } } - Function Get-VMCFirewallRule { <# .NOTES @@ -394,9 +393,8 @@ Function Get-VMCFirewallRule { } $results } - - Function Export-VMCFirewallRule { - <# +Function Export-VMCFirewallRule { +<# .NOTES =========================================================================== Created by: William Lam @@ -413,45 +411,45 @@ Function Get-VMCFirewallRule { .EXAMPLE Export-VMCFirewallRule -OrgName -SDDCName -GatewayType -Path "C:\Users\lamw\Desktop\VMCFirewallRules.json" #> - param( + param( [Parameter(Mandatory=$false)][String]$SDDCName, [Parameter(Mandatory=$false)][String]$OrgName, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$false)][String]$Path ) - if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } - if($GatewayType -eq "MGW") { + if($GatewayType -eq "MGW") { $EdgeId = "edge-1" } else { $EdgeId = "edge-2" } - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - if(-not $orgId) { + if(-not $orgId) { Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" break } - if(-not $sddcId) { + if(-not $sddcId) { Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" break } - $firewallConfigService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config + $firewallConfigService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config - $firewallRules = ($firewallConfigService.get($orgId, $sddcId, $EdgeId)).firewall_rules.firewall_rules - if(-not $ShowAll) { + $firewallRules = ($firewallConfigService.get($orgId, $sddcId, $EdgeId)).firewall_rules.firewall_rules + if(-not $ShowAll) { $firewallRules = $firewallRules | where { $_.rule_type -ne "default_policy" -and $_.rule_type -ne "internal_high" -and $_.name -ne "vSphere Cluster HA" -and $_.name -ne "Outbound Access" } | Sort-Object -Property rule_tag } else { $firewallRules = $firewallRules | Sort-Object -Property rule_tag } - $results = @() - $count = 0 - foreach ($firewallRule in $firewallRules) { + $results = @() + $count = 0 + foreach ($firewallRule in $firewallRules) { if($firewallRule.source.ip_address.Count -ne 0) { $source = $firewallRule.source.ip_address } else { @@ -473,16 +471,15 @@ Function Get-VMCFirewallRule { $count+=1 $results+=$tmp } - if($Path) { + if($Path) { Write-Host -ForegroundColor Green "Exporting $count VMC Firewall Rules to $Path ..." $results | ConvertTo-Json | Out-File $Path } else { $results | ConvertTo-Json } - } - - Function Import-VMCFirewallRule { - <# +} +Function Import-VMCFirewallRule { +<# .NOTES =========================================================================== Created by: William Lam @@ -499,43 +496,43 @@ Function Get-VMCFirewallRule { .EXAMPLE Import-VMCFirewallRule -OrgName -SDDCName -GatewayType -Path "C:\Users\lamw\Desktop\VMCFirewallRules.json" #> - param( + param( [Parameter(Mandatory=$false)][String]$SDDCName, [Parameter(Mandatory=$false)][String]$OrgName, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$false)][String]$Path ) - if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } - if($GatewayType -eq "MGW") { + if($GatewayType -eq "MGW") { $EdgeId = "edge-1" } else { $EdgeId = "edge-2" } - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - if(-not $orgId) { + if(-not $orgId) { Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" break } - if(-not $sddcId) { + if(-not $sddcId) { Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" break } - $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules + $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules - $vmcFirewallRulesJSON = Get-Content -Raw $Path | ConvertFrom-Json + $vmcFirewallRulesJSON = Get-Content -Raw $Path | ConvertFrom-Json - # Create top level Firewall Rules Object - $firewallRules = $firewallService.Help.add.firewall_rules.Create() - # Create top top level Firewall Rule Spec which will be an array of individual Firewall rules as we process them in next section - $ruleSpec = $firewallService.Help.add.firewall_rules.firewall_rules.Create() + # Create top level Firewall Rules Object + $firewallRules = $firewallService.Help.add.firewall_rules.Create() + # Create top top level Firewall Rule Spec which will be an array of individual Firewall rules as we process them in next section + $ruleSpec = $firewallService.Help.add.firewall_rules.firewall_rules.Create() - foreach ($vmcFirewallRule in $vmcFirewallRulesJSON) { + foreach ($vmcFirewallRule in $vmcFirewallRulesJSON) { # Create Individual Firewall Rule Element Spec $ruleElementSpec = $firewallService.Help.add.firewall_rules.firewall_rules.Element.Create() @@ -632,14 +629,13 @@ Function Get-VMCFirewallRule { Write-host "Creating VMC Firewall Rule Spec:" $vmcFirewallRule.Name "..." $ruleSpecAdd = $ruleSpec.Add($ruleElementSpec) } - $firewallRules.firewall_rules = $ruleSpec + $firewallRules.firewall_rules = $ruleSpec - Write-host "Adding VMC Firewall Rules ..." - $firewallRuleAdd = $firewallService.add($orgId,$sddcId,$EdgeId,$firewallRules) - } - - Function Remove-VMCFirewallRule { - <# + Write-host "Adding VMC Firewall Rules ..." + $firewallRuleAdd = $firewallService.add($orgId,$sddcId,$EdgeId,$firewallRules) +} +Function Remove-VMCFirewallRule { +<# .NOTES =========================================================================== Created by: William Lam @@ -656,38 +652,37 @@ Function Get-VMCFirewallRule { .EXAMPLE Remove-VMCFirewallRule -OrgName -SDDCName -GatewayType -RuleId #> - param( + param( [Parameter(Mandatory=$false)][String]$SDDCName, [Parameter(Mandatory=$false)][String]$OrgName, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$false)][String]$RuleId ) - if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } - if($GatewayType -eq "MGW") { + if($GatewayType -eq "MGW") { $EdgeId = "edge-1" } else { $EdgeId = "edge-2" } - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - if(-not $orgId) { + if(-not $orgId) { Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" break } - if(-not $sddcId) { + if(-not $sddcId) { Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" break } - $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules - Write-Host "Removing VMC Firewall Rule Id $RuleId ..." - $firewallService.delete($orgId,$sddcId,$EdgeId,$RuleId) - } - + $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules + Write-Host "Removing VMC Firewall Rule Id $RuleId ..." + $firewallService.delete($orgId,$sddcId,$EdgeId,$RuleId) +} Function Get-VMCLogicalNetwork { <# .NOTES @@ -727,9 +722,17 @@ Function Get-VMCLogicalNetwork { break } - $logicalNetworkService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.logical + # @LucD22 - 21/10/18 - Fix for issue #176 VMware.VMC module only lists firts 20 Logical networks + # Loop until entries (total_count) are returned - $logicalNetworks = ($logicalNetworkService.get_0($orgId, $sddcId)).data | Sort-Object -Property id + $index = [long]0 + + $logicalNetworks = do{ + $netData = $logicalNetworkService.get_0($orgId,$sddcId,$pagesize,$index) + $netData.data | Sort-Object -Property id + $index = $index + $netdata.paging_info.page_size + } + until($index -ge $netData.paging_info.total_count) if($LogicalNetworkName) { $logicalNetworks = $logicalNetworks | Where-Object {$_.Name -eq $LogicalNetworkName} @@ -751,7 +754,6 @@ Function Get-VMCLogicalNetwork { } $results } - Function Remove-VMCLogicalNetwork { <# .NOTES @@ -799,25 +801,24 @@ Function Remove-VMCLogicalNetwork { $logicalNetworkService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.logical $logicalNetworkService.delete($orgId,$sddcId,$lsId) } - Function New-VMCLogicalNetwork { - <# - .NOTES - =========================================================================== - Created by: Kyle Ruddy - Date: 03/06/2018 - Organization: VMware - Blog: https://thatcouldbeaproblem.com - Twitter: @kmruddy - =========================================================================== +<# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 03/06/2018 + Organization: VMware + Blog: https://thatcouldbeaproblem.com + Twitter: @kmruddy + =========================================================================== - .SYNOPSIS - Creates a new Logical Network - .DESCRIPTION - Creates a new Logical Network - .EXAMPLE - New-VMCLogicalNetwork -OrgName -SDDCName -LogicalNetworkName -SubnetMask -Gateway - #> + .SYNOPSIS + Creates a new Logical Network + .DESCRIPTION + Creates a new Logical Network + .EXAMPLE + New-VMCLogicalNetwork -OrgName -SDDCName -LogicalNetworkName -SubnetMask -Gateway +#> [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact='High')] param( [Parameter(Mandatory=$true)][String]$SDDCName, @@ -854,5 +855,454 @@ Function New-VMCLogicalNetwork { $logicalNetworkService.create($orgId, $sddcId, $logicalNetworkSpec) Get-VMCLogicalNetwork -OrgName $OrgName -SDDCName $SDDCName -LogicalNetworkName $LogicalNetworkName } +Function Get-VMCSDDCSummary { + <# + .NOTES + =========================================================================== + Created by: VMware + Date: 09/04/18 + Organization: VMware + Blog: https://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== -Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork' \ No newline at end of file + .SYNOPSIS + Returns a number of useful informational data about a given SDDC within VMC Org + .DESCRIPTION + Returns Version, Create/Expiration Date, Deployment Type, Region, AZ, Instance Type, VPC CIDR & NSX-T + .EXAMPLE + Get-VMCSDDCSummary -Name -Org + #> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $Org).Id + $sddcId = (Get-VMCSDDC -Name $Name -Org $Org).Id + + $sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs" + $sddc = $sddcService.get($orgId,$sddcId) + + $results = [pscustomobject] @{ + Version = $sddc.resource_config.sddc_manifest.vmc_version; + CreateDate = $sddc.created; + ExpirationDate = $sddc.expiration_date; + DeploymentType = $sddc.resource_config.deployment_type; + Region = $sddc.resource_config.region; + AvailabilityZone = $sddc.resource_config.availability_zones; + InstanceType = $sddc.resource_config.sddc_manifest.esx_ami.instance_type; + VpcCIDR = $sddc.resource_config.vpc_info.vpc_cidr; + NSXT = $sddc.resource_config.nsxt; + } + $results + } +} +Function Get-VMCPublicIP { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Retrieves all public IP Addresses for a given SDDC + .DESCRIPTION + This cmdlet retrieves all public IP Address for a given SDDC + .EXAMPLE + Get-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName + #> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + $publicIPs = $publicIPService.list($orgId,$sddcId) + + $publicIPs | select public_ip, name, allocation_id + } + } +Function New-VMCPublicIP { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Request a new public IP Address for a given SDDC + .DESCRIPTION + This cmdlet requests a new public IP Address for a given SDDC + .EXAMPLE + New-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -Description "Test for Randy" +#> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName, + [Parameter(Mandatory=$False)]$Description + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + + $publicIPSpec = $publicIPService.Help.create.spec.Create() + $publicIPSpec.count = 1 + $publicIPSpec.names = @($Description) + + Write-Host "Requesting a new public IP Address for your SDDC ..." + $results = $publicIPService.create($orgId,$sddcId,$publicIPSpec) + } +} +Function Remove-VMCPublicIP { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes a specific public IP Addresses for a given SDDC + .DESCRIPTION + This cmdlet removes a specific public IP Address for a given SDDC + .EXAMPLE + Remove-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -AllocationId "eipalloc-0567acf34e436c01f" +#> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName, + [Parameter(Mandatory=$True)]$AllocationId + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + + Write-Host "Deleting public IP Address with ID $AllocationId ..." + $results = $publicIPService.delete($orgId,$sddcId,$AllocationId) + } +} +Function Get-VMCEdge { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns all the VMC Edges +.DESCRIPTION + Returns all the VMC Edges +.EXAMPLE + Get-VMCEdge -OrgName $orgName -SddcName $SDDCName -EdgeType gatewayServices +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [ValidateSet('gatewayServices','distributedRouter')] + [string]$EdgeType = '' + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $edgeService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges' + $index = [long]0 + $edges = do{ + $edgeData = $edgeService.get($orgId,$sddcId,$EdgeType,'',$index) + $edgeData.edge_page.data | Sort-Object -Property id + $index = $index + $edgeData.edge_page.paging_info.page_size + } + until($index -ge $edgeData.paging_info.total_count) + $edges | %{ + [pscustomobject]@{ + Name = $_.Name + Id = $_.id + Type = $_.edge_type + State = $_.state + Status = $_.edge_status + VNics = $_.number_of_connected_vnics + TenantId = $_.tenant_id + } + } + } +} +Function Get-VMCEdgeStatus { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns the status of the gateway +.DESCRIPTION + Retrieve the status of the specified management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeStatus -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + + $statusService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.status' + $status = $statusService.get($orgId,$sddcId,$edgeId) + + $vmStatus = $status.edge_vm_status | %{ + [pscustomobject]@{ + Name = $_.name + State = $_.edge_VM_status + HAState = $_.ha_state + Index = $_.index + } + } + $featureStatus = $status.feature_statuses | %{ + [pscustomobject]@{ + Service = $_.service + Status = $_.status + } + } + [pscustomobject]@{ + Time = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($status.timestamp/1000)) + Status = $status.edge_status + PublishStatus = $status.publish_status + SystemStatus = $_.system_status + NicInUse = $status.ha_vnic_in_use + } + } +} +Function Get-VMCEdgeNic { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns all interfaces for the gateway +.DESCRIPTION + Retrieve all interfaces for the specified management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeNic -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + + $vnicService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.vnics' + $vnicService.get($orgId,$sddcId,$edgeId) | select -ExpandProperty vnics | %{ + [pscustomobject]@{ + Label = $_.label + Name = $_.Name + Type = $_.type + Index = $_.index + IsConnected = $_.is_connected + Portgroup = $_.portgroup_name + } + } + } +} +Function Get-VMCEdgeNicStat { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns statistics for the gateway interfaces +.DESCRIPTION + Retrieve interface statistics for a management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeNicStat -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + [CmdletBinding(DefaultParameterSetName='Default')] + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName +# [DateTime]$Start, +# [DateTime]$Finish + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + +# $epoch = Get-Date 01/01/1970 +# +# if($start){ +# $startEpoch = (New-TimeSpan -Start $epoch -End $Start.ToUniversalTime()).TotalMilliseconds +# } +# if($Finish){ +# $finishEpoch = (New-TimeSpan -Start $epoch -End $Finish.ToUniversalTime()).TotalMilliseconds +# } + + $vnicStatService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.statistics.interfaces' +# $stats = $vnicStatService.get($orgId,$sddcId,$edgeId,[long]$startEpoch,[long]$finishEpoch) + $stats = $vnicStatService.get($orgId,$sddcId,$edgeId) + + $stats.data_dto | Get-Member -MemberType NoteProperty | where{$_.Name -ne 'Help'} | %{$_.Name} | %{ + $stats.data_dto."$_" | %{ + [pscustomobject]@{ + vNIC = $_.vnic + Timestamp = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($_.timestamp)) + In = $_.in + Out = $_.out + Unit = 'Kbps' + Interval = $stats.meta_dto.interval + } + } + } + } +} +Function Get-VMCEdgeUplinkStat { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns statistics for the uplink interfaces +.DESCRIPTION + Retrieve uplink interface statistics for a management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeUplinkStat -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName +# [DateTime]$Start, +# [DateTime]$Finish + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + +# $epoch = Get-Date 01/01/1970 +# +# if($start){ +# $startEpoch = (New-TimeSpan -Start $epoch -End $Start.ToUniversalTime()).TotalMilliseconds +# } +# if($Finish){ +# $finishEpoch = (New-TimeSpan -Start $epoch -End $Finish.ToUniversalTime()).TotalMilliseconds +# } + + $uplinkStatService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.statistics.interfaces.uplink' +# $stats = $uplinkStatService.get($orgId,$sddcId,$edgeId,[long]$startEpoch,[long]$finishEpoch) + $stats = $uplinkStatService.get($orgId,$sddcId,$edgeId) + + $stats.data_dto | Get-Member -MemberType NoteProperty | where{$_.Name -ne 'Help'} | %{$_.Name} | %{ + if($stats.data_dto."$_".Count -ne 0){ + $stats.data_dto."$_" | %{ + [pscustomobject]@{ + vNIC = $_.vnic + Timestamp = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($_.timestamp)) + In = $_.in + Out = $_.out + Unit = 'Kbps' + Interval = $stats.meta_dto.interval + } + } + } + } + } +} + +Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', + 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', + 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', + 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', + 'Get-VMCSDDCSummary', 'Get-VMCPublicIP', 'New-VMCPublicIP', 'Remove-VMCPublicIP', + 'Get-VMCEdge', 'Get-VMCEdgeNic', 'Get-VMCEdgeStatus', 'Get-VMCEdgeNicStat', 'Get-VMCEdgeUplinkStat' diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 index 95b678f..8a93a97 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.1' +ModuleVersion = '1.2' # ID used to uniquely identify this module GUID = 'f9592e48-6cd3-494e-891b-ee10ee9f7018' @@ -49,7 +49,7 @@ Copyright = 'Copyright (c) 2016 VMware, Inc. All rights reserved.' # Modules that must be imported into the global environment prior to importing this module RequiredModules = @( -@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="10.1.0.8346946"} +@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="10.1.0.8344055"} ) # Assemblies that must be loaded prior to importing this module diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 7752274..df37e98 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -1,5 +1,5 @@ # Script Module : VMware.VMEncryption -# Version : 1.1 +# Version : 1.2 # Copyright © 2016 VMware, Inc. All Rights Reserved. @@ -1844,6 +1844,304 @@ Function Set-VMCryptoUnlock { } } +Function Add-Vtpm { + <# + .SYNOPSIS + This cmdlet adds a Virtual TPM to the specified VM. + + .DESCRIPTION + This cmdlet adds a Virtual TPM to the specified VM. + + .PARAMETER VM + Specifies the VM you want to add Virtual TPM to. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Add-Vtpm $vm1 + + Encrypts $vm1's VM home and adds Virtual TPM + + .NOTES + If VM home is already encrypted, the cmdlet will add a Virtual TPM to the VM. + If VM home is not encrypted, VM home will be encrypted and Virtual TPM will be added. + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "add" + $deviceChange.device = new-object VMware.Vim.VirtualTPM + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Remove-Vtpm { + <# + .SYNOPSIS + This cmdlet removes a Virtual TPM from the specified VM. + + .DESCRIPTION + This cmdlet removes a Virtual TPM from the specified VM. + + .PARAMETER VM + Specifies the VM you want to remove Virtual TPM from. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Remove-Vtpm $vm1 + + .EXAMPLE + C:\PS>Get-VM -Name win2016 |Remove-Vtpm + + Remove Virtual TPM from VM named win2016 + + .NOTES + Removing VirtualTPM will render all encrypted data on this VM unrecoverable. + VM home encryption state will be returned to the original state before Virtual TPM is added + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding(SupportsShouldProcess=$true, ConfirmImpact = "High")] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $message = "Removing Virtual TPM will render all encrypted data on this VM unrecoverable" + if ($PSCmdlet.ShouldProcess($message, $message + "`n Do you want to proceed", "WARNING")) { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "remove" + $deviceChange.device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } + } +} + +Function Get-VtpmCsr { + <# + .SYNOPSIS + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + + .DESCRIPTION + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + The CSR is a ComObject X509enrollment.CX509CertificateRequestPkcs10 + + .PARAMETER VM + Specifies the VM you want to get the CSRs Virtual TPM from. + + .PARAMETER KeyType [RSA | ECC] + Specify that only get CSR with public key RSA algorithm. + If none is specified, both CSR will get returned + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Get-VtpmCsr $vm1 -KeyType RSA + + .NOTES + Both RSA and ECC CSRs objects will be returned. If ECC or RSA is specified, + only the corresponding object will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False)] + [String]$KeyType + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # Check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $CSRs = @() + foreach ($csrArray in $vtpm.EndorsementKeyCertificateSigningRequest) { + $csrString = [System.Convert]::ToBase64String($csrArray) + $csr = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10 + + #decode a base64 string into a CSR object + $csr.InitializeDecode($csrString,6) + if ($keyType) { + if ($csr.PublicKey.Algorithm.FriendlyName -eq $KeyType){ + return $csr + } + } else { + $CSRs += $csr + } + } + return $CSRs + } +} + +Function Set-VtpmCert{ + <# + .SYNOPSIS + This cmdlet replaces certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet replaces certificates to Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to replace the certificates to. + + .PARAMETER Cert + Specifies the certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Set-VtpmCert $vm1 $certObj + + .EXAMPLE + C:\PS>Get-VM -Name win2016 | Set-VtpmCert $certObj + + Replace the appropriate certificate specified + + .NOTES + Only RSA or ECC certs will be overwritten + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + + [Parameter(Mandatory=$True)] + [System.Security.Cryptography.X509Certificates.X509Certificate] $Cert + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + #check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $certOid = New-Object System.Security.Cryptography.Oid($Cert.GetKeyAlgorithm()) + + # Check which certificate to overwrite + $certLocation = GetKeyIndex $vtpm.EndorsementKeyCertificate $certOid.FriendlyName + if ($certLocation -eq -1) { + Write-Error "No Certificate with Matching Algorithm $($certOid.FriendlyName) found" + return + } + + $vtpm.EndorsementKeyCertificate[$certLocation] = $cert.GetRawCertData() + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.Operation = "edit" + $deviceChange.Device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Get-VtpmCert{ + <# + .SYNOPSIS + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to get the certificate from + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>$certs = Get-VtpmCert $vm1 + + .NOTES + An array of certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contain a Virtual TPM" + return + } + + $certs = @() + $vtpm.EndorsementKeyCertificate|foreach { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($_) + $certs += $cert + } + return $certs + } +} + Function ConfirmIsVCenter{ <# .SYNOPSIS @@ -2038,4 +2336,49 @@ Function GetCryptoManager { } } +Function GetKeyIndex{ + <# + .SYNOPSIS + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .DESCRIPTION + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .PARAMETER Certs + Specifies the list of certificats. Expected format is byte[][] + + .PARAMETER KeyType + Specifies the keytype to search for + + .EXAMPLE + C:\PS>$keyIndex = GetKeyIndex $Certs RSA + C:\PS>$keyIndex = GetKeyIndex $Certs ECC + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True)] + [byte[][]] $Certs, + + [Parameter(Mandatory=$True)] + [String] $KeyType + ) + process { + for ($i=0;$i -lt $Certs.Length; $i++) { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($Certs.Get($i)) + $certType = New-Object System.Security.Cryptography.Oid($cert.GetKeyAlgorithm()) + if ( $certType.FriendlyName -eq $keyType) { + return $i + } + } + return -1 + } +} + Export-ModuleMember *-* diff --git a/Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 b/Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 new file mode 100644 index 0000000..ccf5d85 --- /dev/null +++ b/Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 @@ -0,0 +1,82 @@ +function Validate-ESXiPackages { + <# + .DESCRIPTION + Compares all ESXi Host VIBs within a vSphere with a reference Hosts. + + .NOTES + File Name : Validate-ESXiPackages.ps1 + Author : Markus Kraus + Version : 1.0 + State : Ready + + Tested Against Environment: + + vSphere Version: 6.0 U2, 6.5 U1 + PowerCLI Version: PowerCLI 10.0.0 build 7895300 + PowerShell Version: 4.0 + OS Version: Windows Server 2012 R2 + + .LINK + https://mycloudrevolution.com/ + + .EXAMPLE + Validate-ESXiPackages -Cluster (Get-Cluster) -RefernceHost (Get-VMHost | Select-Object -First 1) + + .PARAMETER Cluster + vSphere Cluster to verify + + .PARAMETER RefernceHost + The VIB Reference ESXi Host + #> + + [CmdletBinding()] + param( + [Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage="vSphere Cluster to verify")] + [ValidateNotNullorEmpty()] + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.ComputeResourceImpl] $Cluster, + [Parameter(Mandatory=$True, ValueFromPipeline=$false, HelpMessage="The VIB Reference ESXi Host")] + [ValidateNotNullorEmpty()] + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl] $RefernceHost + ) + + Process { + + #region: Get reference VIBs + $EsxCli2 = Get-ESXCLI -VMHost $RefernceHost -V2 + $RefernceVibList = $esxcli2.software.vib.list.invoke() + #endregion + + #region: Compare reference VIBs + $MyView = @() + foreach ($VmHost in ($Cluster | Get-VMHost)) { + + $EsxCli2 = Get-ESXCLI -VMHost $VmHost -V2 + $VibList = $esxcli2.software.vib.list.invoke() + [Array]$VibDiff = Compare-Object -ReferenceObject $RefernceVibList.ID -DifferenceObject $VibList.ID + + if($VibDiff.Count -gt 0) { + $VibDiffSideIndicator = @() + foreach ($Item in $VibDiff) { + $VibDiffSideIndicator += $($Item.SideIndicator + " " + $Item.InputObject) + } + } + else { + $VibDiffSideIndicator = $null + } + + $Report = [PSCustomObject] @{ + Host = $VmHost.Name + Version = $VmHost.Version + Build = $VmHost.Build + VibDiffCount = $VibDiff.Count + VibDiff = $VibDiff.InputObject + VibDiffSideIndicator = $VibDiffSideIndicator + } + $MyView += $Report + + } + #region: Compare reference VIBs + + $MyView + } +} \ No newline at end of file diff --git a/Scripts/ReadVMSnapshotConfig.ps1 b/Scripts/ReadVMSnapshotConfig.ps1 new file mode 100644 index 0000000..fe274ee --- /dev/null +++ b/Scripts/ReadVMSnapshotConfig.ps1 @@ -0,0 +1,104 @@ +function Get-VMSnapshotConfigContent { +<# + .SYNOPSIS + Reads .vmsd file content + + .DESCRIPTION + Build the vmsd file http URI following https://code.vmware.com/apis/358/vsphere#/doc/vim.FileManager.html + and reads its content with the session established by Connect-VIServer + + .INPUTS + VirtualMachine + + .OUTPUTS + String - the content of the vmsd file + + .NOTES + Author: Dimitar Milov + Version: 1.0 + + .EXAMPLE + Get-VM | Get-VMSnapshotConfigContent +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory=$true, ValueFromPipeline=$true)] + [ValidateNotNull()] + [VMware.VimAutomation.Types.VirtualMachine] + $VM +) + +PROCESS { + # Create web client from current session + $sessionKey = $vm.GetClient().ConnectivityService.CurrentUserSession.SoapSessionKey + $certValidationHandler = $vm.GetClient().ConnectivityService.GetValidationHandlerForCurrentServer() + $webClient = [vmware.vimautomation.common.util10.httpclientUtil]::CreateHttpClientWithSessionReuse($certValidationHandler, $sessionKey, $null) + + # Build VMSD file http URI + # https://code.vmware.com/apis/358/vsphere#/doc/vim.FileManager.html + $vmName = $vm.Name + $datastoreName = ($vm | Get-Datastore).Name + $dcName = ($vm | Get-Datacenter).Name + $serverAddress = $vm.GetClient().ConnectivityService.ServerAddress + $vmsdUri = [uri]"https://$serverAddress/folder/$vmName/$vmName.vmsd?dcPath=$dcName&dsName=$datastoreName" + + # Get VMSD content as string + $task = $webClient.GetAsync($vmsdUri) + $task.Wait() + $vmsdContent = $task.Result.Content.ReadAsStringAsync().Result + + # Dispose web client + $webClient.Dispose() + + # Result + $vmsdContent +} + +} + +function Get-VMSnapshotConfigSetting { +<# + .SYNOPSIS + Gets the value of a specified key from the snapshot config file content + + .DESCRIPTION + Reads the VM's snapshot config file and searches for specified key. + If key is found its value is returned as an output + + .INPUTS + VirtualMachine and key + + .OUTPUTS + String - config value for the specified key + + .NOTES + Author: Dimitar Milov + Version: 1.0 + + .EXAMPLE + Get-VM | Get-VMSnapshotConfigSetting -Key "numSentinels" +#> +[CmdletBinding()] +param( + [Parameter(Mandatory=$true, ValueFromPipeline=$true)] + [ValidateNotNull()] + [VMware.VimAutomation.Types.VirtualMachine] + $VM, + + [Parameter(Mandatory=$true)] + [ValidateNotNull()] + [string] + $Key +) + +PROCESS { + $content = Get-VMSnapshotConfigContent -vm $vm + + $keyMatch = $content | Select-String ('{0} = "(?.*)"' -f $key) + + if ($keyMatch.Matches -ne $null) { + $keyMatch.Matches[0].Groups["value"].Value + } +} +} diff --git a/Scripts/Set-CustomAttributesInGuestinfo.ps1 b/Scripts/Set-CustomAttributesInGuestinfo.ps1 new file mode 100644 index 0000000..d76d3ee --- /dev/null +++ b/Scripts/Set-CustomAttributesInGuestinfo.ps1 @@ -0,0 +1,84 @@ +<# +.NOTES + Script name: Set-CustomAttributesInGuestinfo.ps1 + Created on: 10/04/2018 + Author: Doug Taliaferro, @virtually_doug + Description: Gets Custom Attributes assigned to a VM and makes them available to the guest OS. + Dependencies: None known + + ===Tested Against Environment==== + vSphere Version: 6.5 + PowerCLI Version: 10.0.0.7893909 + PowerShell Version: 5.1.14409.1005 + OS Version: Windows 7, 10 + Keyword: VM, Attributes, Guestinfo + +.SYNOPSIS + Gets Custom Attributes assigned to a VM and makes them available to the guest OS. + +.DESCRIPTION + Gets the custom attributes assigned to one or more VMs and sets their values in the + VM's 'guestinfo' advanced settings. This makes the attributes available within the + guest OS using VM tools (vmtoolsd.exe) and allows the attributes to be used as metadata + for applications or management agents that run inside the guest. If the attribute name + contains spaces they are removed in naming the advanced setting. + + For example, if a VM has a custom attribute named 'Created On', the advanced setting + becomes: + 'guestinfo.CreatedOn' = '08/08/2018 14:24:17' + + This can be retrieved in the guest OS by running: + vmtoolsd.exe --cmd "info-get guestinfo.CreatedOn" + +.PARAMETER VMs + One or more VMs returned from the Get-VM cmdlet. + +.PARAMETER Attributes + The names of the Custom Attributes to get. If the names contain spaces they must be + enclosed in quotes. The spaces will be removed to name the advanced setting. + +.PARAMETER vCenter + The vCenter server to connect to. Optional if you are already connected. + +.EXAMPLE + .\Set-CustomAttributesInGuestInfo.ps1 -VM (get-vm testvm01) -Attributes 'Created On', 'Created By' + + Gets the custom attributes 'Created On' and 'Created By' for 'testvm01' and sets their + values in 'guestinfo.CreatedOn' and 'guestinfo.CreatedBy'. + +.EXAMPLE + .\Set-CustomAttributesInGuestInfo.ps1-VM (get-cluster Dev-01 | get-vm) -Attributes 'Created On' + + Gets the custom attribute 'Created On' for all VMs in the Dev-01 cluster and sets 'guestinfo.CreatedOn' + on each VM. +#> +#Requires -modules VMware.VimAutomation.Core +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true,Position=0)] + $VMs, + [Parameter(Mandatory=$true,Position=1)] + [string[]]$Attributes, + [string]$vCenter +) +if ($vCenter) { + Connect-VIServer $vCenter +} + +ForEach ($vm in $VMs) { + ForEach ($attributeName in $Attributes) { + # Get the custom attribute with a matcing key name + $customField = $vm.CustomFields | Where-Object Key -eq $attributeName + if ($customField) { + # Remove white space from the attribute name because the advanced + # setting name cannot contain spaces + $attributeNameNoSpaces = $customField.Key -replace '\s','' + $guestinfoName = "guestinfo.$attributeNameNoSpaces" + $guestinfoValue = $customField.Value + Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'" + New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null + } else { + Write-Host "$($vm): custom attribute '$attributeName' not set on this VM" + } + } +} diff --git a/Scripts/Set-TagsInGuestinfo.ps1 b/Scripts/Set-TagsInGuestinfo.ps1 new file mode 100644 index 0000000..c245c05 --- /dev/null +++ b/Scripts/Set-TagsInGuestinfo.ps1 @@ -0,0 +1,98 @@ +<# +.NOTES + Script name: Set-TagsInGuestinfo.ps1 + Created on: 10/02/2018 + Author: Doug Taliaferro, @virtually_doug + Description: Gets the vSphere Tags assigned to a VM and makes them available to the guest OS. + Dependencies: None known + + ===Tested Against Environment==== + vSphere Version: 6.5 + PowerCLI Version: 10.0.0.7893909 + PowerShell Version: 5.1.14409.1005 + OS Version: Windows 7, 10 + Keyword: VM, Tags, Guestinfo + +.SYNOPSIS + Gets the vSphere Tags assigned to a VM and makes them available to the guest OS. + +.DESCRIPTION + Gets the tags assigned to one or more VMs from one or more categories and sets the tag values + in the VM's 'guestinfo' advanced settings. This makes the tags available within the guest OS + using VM tools (vmtoolsd.exe) and allows the tags to be used as metadata for applications or + management agents that run inside the guest. + + For example, if a VM has a tag named 'Accounting' from the + category 'Departments', the advanced setting becomes: + guestinfo.Departments = Accounting + + This can be retrieved in the guest OS by running: + vmtoolsd.exe --cmd "info-get guestinfo.Departments" + + If multiple tags are assigned from the same category, they are joined using the specified + delimter (a semicolon by default): + guestinfo.Departments = Accounting;Sales + +.PARAMETER VMs + One or more VMs returned from the Get-VM cmdlet. + +.PARAMETER Categories + The names of tag categories that should be set in the advanced settings. + + .PARAMETER Delimiter + The delimiting character used for multiple tags of the same category. Defaults to a + semicolon. + +.PARAMETER vCenter + The vCenter server to connect to. Optional if you are already connected. + +.EXAMPLE + .\Set-TagsInGuestInfo.ps1 -VM (get-vm testvm01) -Categories Departments, Environment + + Gets tags assigned to 'testvm01' in the Departments and Environment categories and + sets their values in 'guestinfo.Departments' and 'guestinfo.Environment'. + +.EXAMPLE + .\Set-TagsInGuestInfo.ps1 -VM (get-cluster Dev-01 | get-vm) -Categories Departments + + Gets tags assigned to all VMs in the Dev-01 cluster and sets 'guestinfo.Departments' + on each VM. +#> +#Requires -modules VMware.VimAutomation.Core +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true,Position=0)] + $VMs, + [Parameter(Mandatory=$true,Position=1)] + [string[]]$Categories, + [string]$Delimiter = ';', + [string]$vCenter +) +if ($vCenter) { + Connect-VIServer $vCenter +} + +ForEach ($categoryName in $Categories) { + $category = Get-TagCategory -Name $categoryName + if ($category) { + $guestinfoName = "guestinfo.$category" + + # Get Tag assignments for the VMs + $tags = Get-TagAssignment -Entity $VMs -Category $category + + # Group the tags by VM (in this case the Entity property of Group-Object) + $groups = $tags | Group-Object -Property Entity + + # Get each VM and set the guestinfo + ForEach ($item in $groups) { + $vm = get-vm $item.Name + # Multiple tags of the same category are joined + $guestinfoValue = $item.Group.Tag.Name -join $Delimiter + + Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'" + New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null + } + } else { + Write-Host "Category '$categoryName' was not found." + } +} diff --git a/Scripts/VMC Example Script.ps1 b/Scripts/VMware_Cloud_on_AWS/VMC Example Script.ps1 similarity index 100% rename from Scripts/VMC Example Script.ps1 rename to Scripts/VMware_Cloud_on_AWS/VMC Example Script.ps1 diff --git a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 new file mode 100644 index 0000000..2a41690 --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 @@ -0,0 +1,66 @@ +# Author: Kyle Ruddy +# Product: VMware Cloud on AWS +# Description: VMware Cloud on AWS Single Host Deployment Script using PowerCLI +# Requirements: +# - PowerShell 3.x or newer +# - PowerCLI 6.5.4 or newer + +# Set details for SDDC +$oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" +$sddcName = "PowerCLI-1Host-SDDC" +$hostCount = "1" +$awsRegion = "US_WEST_2" +$useAwsAccount = $false + +# --- Deployment code --- +# Connect to VMware Cloud Service +Connect-Vmc -RefreshToken $oauthToken | Out-Null + +# Get ORG ID +$orgSvc = Get-VmcService -Name com.vmware.vmc.orgs +$org = $orgSvc.List() +Write-Output -InputObject "Org: $($org.display_name) ID: $($org.id)" + +# Check to use the already existing AWS account connection +if ($useAwsAccount -eq $true) { + # Get Linked Account ID + $connAcctSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.connected_accounts + $connAcctId = $connAcctSvc.get($org.id) | Select-Object -ExpandProperty id + Write-Output -InputObject "Account ID: $connAcctId" + + # Get Subnet ID + $compSubnetSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.compatible_subnets + $vpcMap = $compSubnetSvc.Get($org.id, $connAcctId, $region) | Select-Object -ExpandProperty vpc_map + $compSubnets = $vpcMap | Select-Object -ExpandProperty Values | Select-Object -ExpandProperty subnets + $compSubnet = $compSubnets | where {$_.name -ne $null} | Select-Object -first 1 + Write-Output -InputObject "Subnet CIDR $($compSubnet.subnet_cidr_block) ID: $($compSubnet.subnet_id)" +} +elseif ($useAwsAccount -eq $false) { + Write-Output -InputObject "AWS Account Not Configured - you must connect to an AWS account within 14 days of creating this SDDC" +} + +# Deploy the SDDC +$sddcSvc = Get-VmcService com.vmware.vmc.orgs.sddcs +$sddcCreateSpec = $sddcSvc.Help.create.sddc_config.Create() +$sddcCreateSpec.region = $awsRegion +$sddcCreateSpec.Name = $sddcName +$sddcCreateSpec.num_hosts = $hostCount +if ($org.properties.values.sddcTypes) {$sddcCreateSpec.sddc_type = "1NODE"} +$sddcCreateSpec.Provider = "AWS" + +if ($useAwsAccount -eq $true) { + $accountLinkSpec = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.Create() + $accountLinkSpec.connected_account_id = $connAcctId + $custSubId0 = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.customer_subnet_ids.Element.Create() + $custSubId0 = $compSubnet.subnet_id + $accountLinkSpec.customer_subnet_ids.Add($custSubId0) | Out-Null + $sddcCreateSpec.account_link_sddc_config.Add($accountLinkSpec) | Out-Null +} +elseif ($useAwsAccount -eq $false) { + $accountLinkDelaySpec = $sddcSvc.Help.create.sddc_config.account_link_config.delay_account_link.Create() + $accountLinkDelaySpec = $true + $sddcCreateSpec.account_link_config.delay_account_link = $accountLinkDelaySpec +} + +$newSddc = $sddcSvc.create($org.Id, $sddcCreateSpec) +$newSddc | Select-Object resource_id,status,task_type,start_time,task_id \ No newline at end of file diff --git a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 new file mode 100644 index 0000000..de5b870 --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 @@ -0,0 +1,209 @@ +# Author: Kyle Ruddy +# Product: VMware Cloud on AWS +# Description: VMware Cloud on AWS Firewall Rule Accelerator for PowerCLI +# Requirements: +# - PowerShell 3.x or newer +# - PowerCLI 6.5.4 or newer +# - Use Default IP Addresses +# - Use NSX-V on VMware Cloud on AWS + +#---------- USER VARIABLES ---------------------------------------- + +$oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" +$orgId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' +$sddcId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' + +# ---------- DO NOT MODIFY BELOW THIS ------------------------------ + + +Connect-Vmc -RefreshToken $oauthToken | Out-Null + +$orgSvc = Get-VmcService -Name com.vmware.vmc.orgs + +if ($orgId) { + $org = $orgSvc.List() | where {$_.id -eq $orgId} +} +else {$org = $orgSvc.List()} + +if ($org -eq $null) {Write-Output "No Org Found. Exiting."; break} + +$sddcSvc = Get-VmcService -Name com.vmware.vmc.orgs.sddcs + +if ($sddcId) { + $sddc = $sddcSvc.Get($org.id, $sddcId) +} +else {$sddc = $sddcSvc.List($org.id)} + +if ($sddc -eq $null) {Write-Output "No SDDC Found. Exiting."; break} +elseif ($sddc -is [array]) {Write-Output "Multiple SDDCs Found. Please Specify an SDDC ID. Exiting."; break} + +$edgeSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges +$mgwEdge = ($edgeSvc.Get($org.id,$sddcId,'gatewayServices') | Select-Object -ExpandProperty edge_page).data | where {$_.id -eq 'edge-1'} + +$ipsecSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.ipsec.config +$ipsecVPN = $ipsecSvc.Get($org.id, $sddcId, $mgwEdge.id) + +$localSubnet = $ipsecVPN.sites.sites.local_subnets.subnets +$vpnSubnet = $ipsecVPN.sites.sites.peer_subnets.subnets +$vcMgmtIP = $sddc.resource_config.vc_management_ip +$vcPublicIP = $sddc.resource_config.vc_public_ip +$esxSubnet = $sddc.resource_config.esx_host_subnet +$ipsecVPNname = $ipsecVPN.sites.sites.name + +function Add-VMCFirewallRule { + <# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 08/22/2018 + Organization: VMware + Blog: https://www.kmruddy.com + Twitter: @kmruddy + =========================================================================== + .SYNOPSIS + Creates a Firewall Rule for a given SDDC + .DESCRIPTION + Creates a Firewall Rule for a given SDDC + .EXAMPLE + Add-VMCFirewallRule -OrgId -sddcId -FwRuleName -SourceIpAddress -DestIpAddress -Service + + #> + param( + [Parameter(Mandatory=$true)] + [String]$OrgId, + [Parameter(Mandatory=$true)] + [String]$SddcId, + [Parameter(Mandatory=$false)] + [ValidateSet('Management Gateway','Compute Gateway')] + [String]$Edge = 'Management Gateway', + [Parameter(Mandatory=$true)] + [String]$FwRuleName, + [Parameter(Mandatory=$false)] + $SourceIpAddress, + [Parameter(Mandatory=$false)] + $DestIpAddress, + [Parameter(Mandatory=$true)] + [ValidateSet('HTTPS','ICMP','SSO','Provisioning','Any','Remote Console')] + [String]$Service, + [Parameter(Mandatory=$false)] + [ValidateSet('accept')] + $FwAction = 'accept' + + ) + + if ($edge -eq 'Management Gateway') {$EdgeId = 'edge-1'} + elseif ($edge -eq 'Compute Gateway') {$EdgeId = 'edge-2'} + else {Write-Output "No Valid Edge Input Found."} + + $fwRuleSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules + + $ruleElementSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.Create() + $fwRules = $fwRuleSvc.Help.add.firewall_rules.Create() + $ruleSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Create() + + # AppSpec + $appSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.application.Create() + # ServiceSpec + $serviceSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.application.service.Element.Create() + + if ($Service -eq 'HTTPS') { + $protocol = 'TCP' + $port = @("443") + } + elseif ($Service -eq 'ICMP') { + $protocol = 'ICMP' + $icmpType = 'any' + + } + elseif ($Service -eq 'SSO') { + $protocol = 'TCP' + $port = @("7444") + } + elseif ($Service -eq 'Provisioning') { + $protocol = 'TCP' + $port = @("902") + } + elseif ($Service -eq 'Any') { + $protocol = 'Any' + $port = $null + } + elseif ($Service -eq 'Remote Console') { + $protocol = 'TCP' + $port = @("903") + } + else {Write-Output "No Protocol Found."; break} + + $serviceSpec.protocol = $protocol + + # Process ICMP Type from JSON + $icmpType = $null + if($protocol -eq 'ICMP') { + $icmpType = 'any' + } + + if ($icmpType) { + $serviceSpec.icmp_type = $icmpType} + if ($port) { + $serviceSpec.port = $port + $serviceSpec.source_port = @("any") + } + + $addSpec = $ruleElementSpec.application.service.Add($serviceSpec) + + + # Create Source Spec + if($SourceIpAddress) { + $srcSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.source.Create() + $srcSpec.exclude = $false + $srcSpec.ip_address = @($SourceIpAddress) + $ruleElementSpec.source = $srcSpec + } + + + # Create Destination Spec + if($DestIpAddress) { + $destSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.destination.Create() + $destSpec.exclude = $false + $destSpec.ip_address = @($DestIpAddress) + $ruleElementSpec.destination = $destSpec + + } + + + $ruleElementSpec.rule_type = "user" + $ruleElementSpec.enabled = $true + $ruleElementSpec.logging_enabled = $false + + $ruleElementSpec.action = $FwAction + $ruleElementSpec.name = $FwRuleName + + # Add the individual FW rule spec into our overall firewall rules array + Write-Output "Creating VMC Firewall Rule: $FwRuleName" + $ruleSpecAdd = $ruleSpec.Add($ruleElementSpec) + + $fwRules.firewall_rules = $ruleSpec + $fwRuleAdd = $fwRuleSvc.add($orgId,$sddcId,$EdgeId,$fwRules) + +} + + +# vCenter (ANY) to VPN +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "vCenter (ANY) to $ipsecVPNname" -SourceIpAddress $vcMgmtIP -DestIpAddress $vpnSubnet -Service 'Any' + +# ESXi (ANY) to VPN +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "ESXi (ANY) to $ipsecVPNname" -SourceIpAddress $esxSubnet,'10.2.16.0/20' -DestIpAddress $vpnSubnet -Service 'Any' + +# VPN to vCenter (HTTPS) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to vCenter (HTTPS)" -SourceIpAddress $vpnSubnet -DestIpAddress $vcMgmtIP -Service 'HTTPS' + +# VPN to vCenter (ICMP) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to vCenter (ICMP)" -SourceIpAddress $vpnSubnet -DestIpAddress $vcMgmtIP -Service 'ICMP' + +# VPN to ESXi (Provisioning) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (Provisioning)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'Provisioning' + +# VPN to ESXi (Remove Console) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (Remote Console)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'Remote Console' + +# VPN to ESXi (ICMP) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (ICMP)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'ICMP' \ No newline at end of file diff --git a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 new file mode 100644 index 0000000..59ddb7a --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 @@ -0,0 +1,114 @@ +<# +.SYNOPSIS + Takes email address input in order to create VMware Cloud on AWS invites for the desired Organization +.DESCRIPTION + Script which can be used to automate the process of adding new users to a specified VMware Cloud on AWS Organization +.NOTES + Author: Kyle Ruddy, @kmruddy, kmruddy.com +.PARAMETER newUserEmail + Plain text email address or array of email addresses +.PARAMETER roleName + Desired role name of the new users, default is Organization Member +.EXAMPLE + PS > ./VMWonAWS_InviteUsers.ps1 -newUserEmail 'testuser@vmware.com' +.EXAMPLE + PS > ./VMWonAWS_InviteUsers.ps1 -newUserEmail $arrayOfEmailAddresses +#> +[CmdletBinding(SupportsShouldProcess=$True)] + param ( + + [Parameter (Mandatory = $True, Position=0)] + $newUserEmail, + [Parameter (Mandatory = $False, Position=1)] + [ValidateSet("Organization Member","Organization Owner","Support User")] + [string]$roleName = "Organization Member" + ) + + # Set Static Variables for your environment + $oauthToken = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + $orgID = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + + ### DO NOT MODIFY CODE BELOW THIS LINE ### + $inviteReport = @() + $userEmail = @() + + # Email Validation Testing + if ($newUserEmail -is [array]) { + foreach ($email in $newUserEmail) { + try { + $userEmail += [mailAddress]$email | select-object -ExpandProperty Address + } + catch { + Write-Warning "$email is not a valid email address" + } + } + } + else { + try { + $userEmail += [mailAddress]$newUserEmail | select-object -ExpandProperty Address + } + catch { + Write-Warning "$newUserEmail is not a valid email address" + } + } + + if ($userEmail.Count -eq 0) { + Write-Warning "No valid email addresses found." + Break + } + + # Validation and translation of the role name to the role ID + if ($roleName -eq 'Organization Member') { + $orgRoleNames = @("org_member") + } + elseif ($roleName -eq 'Organization Owner') { + $orgRoleNames = @("org_owner") + } + elseif ($roleName -eq 'Support User') { + $orgRoleNames = @("support_user") + } + + # Creating custom objects to start building out the body input + $bodyObj = new-object -TypeName System.Object + $SvcRoleNames = @("vmc-user:full") + $SvcDefinitionLink = '/csp/gateway/slc/api/definitions/external/ybUdoTC05kYFC9ZG560kpsn0I8M_' + $bodyObj | Add-Member -Name 'orgRoleNames' -MemberType Noteproperty -Value $orgRoleNames + $serviceRolesDtos = New-Object -TypeName System.Object + $serviceRolesDtos | Add-Member -Name 'serviceDefinitionLink' -MemberType Noteproperty -Value $SvcDefinitionLink + $serviceRolesDtos | Add-Member -Name 'serviceRoleNames' -MemberType Noteproperty -Value $SvcRoleNames + $bodyObj | Add-Member -Name 'serviceRolesDtos' -MemberType Noteproperty -Value @($serviceRolesDtos) + $bodyObj | Add-Member -Name 'usernames' -MemberType Noteproperty -Value $userEmail + $body = $bodyObj | ConvertTo-Json -Depth 100 + + # Connecting to the REST API service for authentication and then to perform the POST method + $connection = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$oauthToken" -Method Post + $accesskey = ($connection.content | Convertfrom-json).access_token + $inviteUsers = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/orgs/$orgID/invitations" -headers @{"csp-auth-token"="$accesskey"} -Method Post -Body $body -ContentType "application/json" + + # Outputting the successful invite which was just created + $orgInviteRefResponse = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/orgs/$orgid/invitations" -headers @{"csp-auth-token"="$accessKey"} -Method Get + if ($orgInviteRefResponse) { + $orgInviteRefObject = $orgInviteRefResponse | ConvertFrom-Json + + foreach ($inviteRef in $orgInviteRefObject) { + $link = $inviteRef.refLink + $orgInviteResponse = Invoke-WebRequest -Uri "https://console.cloud.vmware.com$link" -headers @{"csp-auth-token"="$accessKey"} -Method Get + + $orgInviteObject = $orgInviteResponse.content | ConvertFrom-Json + + foreach ($emailInput in $userEmail) { + + if ($orgInviteObject.username -eq $emailInput) { + $i = New-Object System.Object + $i | Add-Member -Type NoteProperty -Name InviteID -Value $orgInviteObject.refLink.Substring($orgInviteObject.refLink.Length - 36) + $i | Add-Member -Type NoteProperty -Name Username -Value $orgInviteObject.username + $i | Add-Member -Type NoteProperty -Name Status -Value $orgInviteObject.status + $i | Add-Member -Type NoteProperty -Name OrgRoles -Value ($orgInviteObject.OrgRoleNames -join ", ") + $i | Add-Member -Type NoteProperty -Name Requester -Value $orgInviteObject.generatedBy + $inviteReport += $i + } + } + } + } + + return $inviteReport \ No newline at end of file diff --git a/Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 b/Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 new file mode 100644 index 0000000..eb591bb --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 @@ -0,0 +1,37 @@ +$refreshToken = 'your-refresh-token' + +$reportPath = '.\VMC-services.xlsx' + +Connect-Vmc -RefreshToken $refreshToken > $null + +$columns = @{} +$services = Get-VmcService | Sort-Object -Property Name +$services | ForEach-Object -Process { + $_.Help | Get-Member -MemberType NoteProperty | where{'Constants','Documentation' -notcontains $_.Name} | + ForEach-Object -Process { + if(-not $columns.ContainsKey($_.Name)){ + $columns.Add($_.Name,'') + } + } +} +$columns = $columns.Keys | Sort-Object +$report = @() +foreach($service in $services){ + $obj = [ordered]@{ + Name = $service.Name + } + $columns | ForEach-Object -Process { + $obj.Add($_,'') + } + + $service.Help | Get-Member -MemberType NoteProperty | where{'Constants','Documentation' -notcontains $_.Name} | + ForEach-Object -Process { +# $obj.Item($_.Name) = "$($service.Help.$($_.Name).Documentation)" + $obj.Item($_.Name) = "X" + } + $report += New-Object PSObject -Property $obj +} +$report | Export-Excel -Path $reportPath -WorksheetName 'Services' -FreezeTopRow -BoldTopRow -AutoSize -Show + +Disconnect-Vmc -Confirm:$false +