diff --git a/Modules/VCSAPasswordPolicy/VCSAPasswordPolicy.psm1 b/Modules/VCSA/VCSA.psm1 similarity index 64% rename from Modules/VCSAPasswordPolicy/VCSAPasswordPolicy.psm1 rename to Modules/VCSA/VCSA.psm1 index 55963ca..a0bac0e 100644 --- a/Modules/VCSAPasswordPolicy/VCSAPasswordPolicy.psm1 +++ b/Modules/VCSA/VCSA.psm1 @@ -36,4 +36,33 @@ Function Get-VCSAPasswordPolicy { } else { Write-Host "`nUnable to find VCSA named $VCSAName" } +} + +Function Get-VCSAIdentitySource { +<# + .DESCRIPTION Retrieves vCenter Server Appliance Identity Source Configuration + .NOTES Author: William Lam + .PARAMETER VCSAName + Inventory name of the VCSA VM + .PARAMETER VCSARootPassword + Root password for VCSA VM + .EXAMPLE + Get-VCSAIdentitySource -VCSAName "MGMT-VCSA-01" -VCSARootPassword "VMware1!" +#> + Param ( + [Parameter(Mandatory=$true)][String]$VCSAName, + [Parameter(Mandatory=$true)][String]$VCSARootPassword + ) + + $vm = Get-Vm -Name $VCSAName + + if($vm) { + $identitySources = Invoke-VMScript -ScriptText "/opt/vmware/bin/sso-config.sh -get_identity_sources 2> /dev/null | sed -ne '/^*/,$ p'" -vm $vm -GuestUser "root" -GuestPassword $VCSARootPassword + + Write-Host -ForegroundColor green "`nIdentity Sources: " + $identitySources + + } else { + Write-Host "`nUnable to find VCSA named $VCSAName" + } } \ 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 index 42be532..649efe2 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -120,10 +120,12 @@ Function Get-NSXTSegment { $network = $subnets.network $gateway = $subnets.gateway_address $dhcpRange = $subnets.dhcp_ranges + $type = $segment.type $tmp = [pscustomobject] @{ Name = $segment.display_name; ID = $segment.Id; + TYPE = $type; Network = $network; Gateway = $gateway; DHCPRange = $dhcpRange; @@ -156,6 +158,8 @@ Function New-NSXTSegment { New-NSXTSegment -Name "sddc-cgw-network-4" -Gateway "192.168.4.1/24" -DHCP -DHCPRange "192.168.4.2-192.168.4.254" -DomainName 'vmc.local' .EXAMPLE New-NSXTSegment -Name "sddc-cgw-network-5" -Gateway "192.168.5.1/24" + .EXAMPLE + New-NSXTSegment -Name "sddc-cgw-network-5" -Gateway "192.168.5.1/24" -Disconnected #> Param ( [Parameter(Mandatory=$True)]$Name, @@ -163,6 +167,7 @@ Function New-NSXTSegment { [Parameter(Mandatory=$False)]$DHCPRange, [Parameter(Mandatory=$False)]$DomainName, [Switch]$DHCP, + [Switch]$Disconnected, [Switch]$Troubleshoot ) @@ -178,9 +183,21 @@ Function New-NSXTSegment { } } - $payload = @{ - display_name = $Name; - subnets = @($subnets) + if($Disconnected) { + $payload = @{ + display_name = $Name; + subnets = @($subnets) + advanced_config = @{ + local_egress = "False" + connectivity = "OFF"; + } + type = "DISCONNECTED"; + } + } else { + $payload = @{ + display_name = $Name; + subnets = @($subnets) + } } if($DomainName) { @@ -221,6 +238,98 @@ Function New-NSXTSegment { } } +Function Set-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 03/04/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Set a NSX-T Segment (Logical Networks) to either connected or disconnected + .DESCRIPTION + This cmdlet set an NSX-T Segment (Logical Networks) to either connected or disconnected + .EXAMPLE + New-NSXTSegment -Name "sddc-cgw-network-4" -Disconnected + .EXAMPLE + New-NSXTSegment -Name "sddc-cgw-network-4" -Connected + +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Switch]$Disconnected, + [Switch]$Connected, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $SegmentId = (Get-NSXTSegment -Name $Name).Id + + if($Disconnected) { + $type = "DISCONNECTED" + $connectivity = "OFF" + $localEgress = "False" + $gateway = (Get-NSXTSegment -Name $Name).Gateway + } + + If($Connected) { + $type = "ROUTED" + $connectivity = "ON" + $localEgress = "True" + $gateway = (Get-NSXTSegment -Name $Name).Gateway + } + + $subnets = @{ + gateway_address = $gateway; + } + + $payload = @{ + advanced_config = @{ + local_egress = $localEgress; + connectivity = $connectivity; + } + type = $type; + subnets = @($subnets) + } + + $body = $payload | ConvertTo-Json -depth 4 + + $method = "PATCH" + $aegmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-1s/cgw/segments/$SegmentId" + + 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 $aegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $aegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + if($_.Exception.Response.StatusCode -eq "Unauthorized") { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } else { + Write-Error "Error in updating NSX-T Segment connectivity" + Write-Error "`n($_.Exception.Message)`n" + break + } + } + + if($requests.StatusCode -eq 200) { + Write-Host "Successfully updated NSX-T Segment $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } + } +} + Function Remove-NSXTSegment { <# .NOTES diff --git a/Modules/VyOS/VyOS.psm1 b/Modules/VyOS/VyOS.psm1 new file mode 100644 index 0000000..4c1c952 --- /dev/null +++ b/Modules/VyOS/VyOS.psm1 @@ -0,0 +1,330 @@ +Function Set-VMKeystrokes { + param( + [Parameter(Mandatory=$true)][String]$VMName, + [Parameter(Mandatory=$true)][String]$StringInput, + [Parameter(Mandatory=$false)][Boolean]$ReturnCarriage, + [Parameter(Mandatory=$false)][Boolean]$DebugOn + ) + + # Map subset of USB HID keyboard scancodes + # https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2 + $hidCharacterMap = @{ + "a"="0x04"; + "b"="0x05"; + "c"="0x06"; + "d"="0x07"; + "e"="0x08"; + "f"="0x09"; + "g"="0x0a"; + "h"="0x0b"; + "i"="0x0c"; + "j"="0x0d"; + "k"="0x0e"; + "l"="0x0f"; + "m"="0x10"; + "n"="0x11"; + "o"="0x12"; + "p"="0x13"; + "q"="0x14"; + "r"="0x15"; + "s"="0x16"; + "t"="0x17"; + "u"="0x18"; + "v"="0x19"; + "w"="0x1a"; + "x"="0x1b"; + "y"="0x1c"; + "z"="0x1d"; + "1"="0x1e"; + "2"="0x1f"; + "3"="0x20"; + "4"="0x21"; + "5"="0x22"; + "6"="0x23"; + "7"="0x24"; + "8"="0x25"; + "9"="0x26"; + "0"="0x27"; + "!"="0x1e"; + "@"="0x1f"; + "#"="0x20"; + "$"="0x21"; + "%"="0x22"; + "^"="0x23"; + "&"="0x24"; + "*"="0x25"; + "("="0x26"; + ")"="0x27"; + "_"="0x2d"; + "+"="0x2e"; + "{"="0x2f"; + "}"="0x30"; + "|"="0x31"; + ":"="0x33"; + "`""="0x34"; + "~"="0x35"; + "<"="0x36"; + ">"="0x37"; + "?"="0x38"; + "-"="0x2d"; + "="="0x2e"; + "["="0x2f"; + "]"="0x30"; + "\"="0x31"; + "`;"="0x33"; + "`'"="0x34"; + ","="0x36"; + "."="0x37"; + "/"="0x38"; + " "="0x2c"; + } + + $vm = Get-View -ViewType VirtualMachine -Filter @{"Name"="^$($VMName)$"} + + # Verify we have a VM or fail + if(!$vm) { + Write-host "Unable to find VM $VMName" + return + } + + $hidCodesEvents = @() + foreach($character in $StringInput.ToCharArray()) { + # Check to see if we've mapped the character to HID code + if($hidCharacterMap.ContainsKey([string]$character)) { + $hidCode = $hidCharacterMap[[string]$character] + + $tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent + + # Add leftShift modifer for capital letters and/or special characters + if( ($character -cmatch "[A-Z]") -or ($character -match "[!|@|#|$|%|^|&|(|)|_|+|{|}|||:|~|<|>|?|*]") ) { + $modifer = New-Object Vmware.Vim.UsbScanCodeSpecModifierType + $modifer.LeftShift = $true + $tmp.Modifiers = $modifer + } + + # Convert to expected HID code format + $hidCodeHexToInt = [Convert]::ToInt64($hidCode,"16") + $hidCodeValue = ($hidCodeHexToInt -shl 16) -bor 0007 + + $tmp.UsbHidCode = $hidCodeValue + $hidCodesEvents+=$tmp + + if($DebugOn) { + Write-Host "Character: $character -> HIDCode: $hidCode -> HIDCodeValue: $hidCodeValue" + } + } else { + Write-Host "The following character `"$character`" has not been mapped, you will need to manually process this character" + break + } + } + + # Add return carriage to the end of the string input (useful for logins or executing commands) + if($ReturnCarriage) { + # Convert return carriage to HID code format + $hidCodeHexToInt = [Convert]::ToInt64("0x28","16") + $hidCodeValue = ($hidCodeHexToInt -shl 16) + 7 + + $tmp = New-Object VMware.Vim.UsbScanCodeSpecKeyEvent + $tmp.UsbHidCode = $hidCodeValue + $hidCodesEvents+=$tmp + } + + # Call API to send keystrokes to VM + $spec = New-Object Vmware.Vim.UsbScanCodeSpec + $spec.KeyEvents = $hidCodesEvents + Write-Host "Sending `'$StringInput`' ...`n" + $results = $vm.PutUsbScanCodes($spec) +} + +Function New-VyOSInstallation { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function automates the installation and configuration of VyOS from ISO + .PARAMETER VMName + The name of the VyOS VM + .PARAMETER ManagementPassword + The password to configure for the vyos user + .EXAMPLE + New-VyOSInstallation -VMName VyOS-Router -ManagementPassword VMware1! +#> + param( + [Parameter(Mandatory=$true)][String]$VMName, + [Parameter(Mandatory=$true)][String]$ManagementPassword + ) + + # Login to console and install VyOS before starting configuration + Set-VMKeystrokes -VMName $VMName -StringInput "vyos" -ReturnCarriage $true + Set-VMKeystrokes -VMName $VMName -StringInput "vyos" -ReturnCarriage $true + Set-VMKeystrokes -VMName $VMName -StringInput "install image" -ReturnCarriage $true + Set-VMKeystrokes -VMName $VMName -StringInput "yes" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput "Auto" -ReturnCarriage $true + Start-Sleep -Seconds 1 + Set-VMKeystrokes -VMName $VMName -StringInput "sda" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput "yes" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput " " -ReturnCarriage $true + Start-Sleep -Seconds 10 + Set-VMKeystrokes -VMName $VMName -StringInput "vyos-router" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput " " -ReturnCarriage $true + Start-Sleep -Seconds 10 + Set-VMKeystrokes -VMName $VMName -StringInput "$ManagementPassword" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput "$ManagementPassword" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput "sda" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput "reboot" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Set-VMKeystrokes -VMName $VMName -StringInput "y" -ReturnCarriage $true + Start-Sleep -Seconds 5 + Get-VM $VMName | Get-CDDrive | Set-CDDrive -Connected $false -Confirm:$false -ErrorAction Ignore -WarningAction Ignore | Out-Null + + Write-Host -ForegroundColor Green "VyOS has been installed, VM will reboot for changes to go into effect" +} + +Function New-VyOSConfiguration { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function automates the installation and configuration of VyOS from ISO + .PARAMETER VMName + The name of the VyOS VM + .PARAMETER ManagementPassword + The password to configure for the vyos user + .PARAMETER ConfigFile + The path to VyOS configuration file + .PARAMETER ManagementAddress + The IP Address of the OUTSIDE Interface (eth0) + .PARAMETER ManagementGateway + The Gateway Addrss of the OUTSIDE Interface (eth0) + .PARAMETER ManagementDNSDomain + The DNS Domain on the WAN network + .PARAMETER ManagementDNSServer + The DNS Server on the WAN Network + .PARAMETER ManagementJumpHostIP + The IP Address of Windows Jumphost that can be used to RDP into various VLANs + .EXAMPLE + New-VyOSConfiguration -VMName VyOS-Router -ConfigFile vyos.template -ManagementAddress 192.168.30.156/24 -ManagementGateway 192.168.30.1 -ManagementDNSDomain primp-industries.com -ManagementDNSServer 192.168.30.2 -ManagementJumpHostIP 192.168.30.199 -ManagementPassword VMware1! +#> + param( + [Parameter(Mandatory=$true)][String]$VMName, + [Parameter(Mandatory=$true)][String]$ConfigFile, + [Parameter(Mandatory=$true)][String]$ManagementAddress, + [Parameter(Mandatory=$true)][String]$ManagementGateway, + [Parameter(Mandatory=$true)][String]$ManagementDNSDomain, + [Parameter(Mandatory=$true)][String]$ManagementDNSServer, + [Parameter(Mandatory=$true)][String]$ManagementJumpHostIP, + [Parameter(Mandatory=$true)][String]$ManagementPassword + ) + + # Login to console and install VyOS before starting configuration + Set-VMKeystrokes -VMName $VMName -StringInput "vyos" -ReturnCarriage $true + Set-VMKeystrokes -VMName $VMName -StringInput "$ManagementPassword" -ReturnCarriage $true + + foreach ($cmd in Get-Content -Path $ConfigFile | Where-Object { $_.Trim() -ne '' }) { + if($cmd.Contains('[MANAGEMENT_ADDRESS]')) { + $cmd = $cmd.replace('[MANAGEMENT_ADDRESS]',$ManagementAddress) + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } elseif($cmd.Contains('[MANAGEMENT_IP]')) { + $ManagementAddress = $ManagementAddress.substring(0,$ManagementAddress.IndexOf('/')) + $cmd = $cmd.replace('[MANAGEMENT_IP]',$ManagementAddress) + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } elseif($cmd.Contains('[MANAGEMENT_GATEWAY]')) { + $cmd = $cmd.replace('[MANAGEMENT_GATEWAY]',$ManagementGateway) + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } elseif($cmd.Contains('[JUMPHOST_VM_IP]')) { + $cmd = $cmd.replace('[JUMPHOST_VM_IP]',$ManagementJumpHostIP) + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } elseif($cmd.Contains('[MANAGEMENT_DNS_DOMAIN]')) { + $cmd = $cmd.replace('[MANAGEMENT_DNS_DOMAIN]',$ManagementDNSDomain) + $cmd = $cmd.replace('[MANAGEMENT_DNS_SERVER]',$ManagementDNSServer) + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } elseif($cmd.Contains('[MANAGEMENT_DNS_SERVER]')) { + $cmd = $cmd.replace('[MANAGEMENT_DNS_SERVER]',$ManagementDNSServer) + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } else { + if($Troubleshoot) { + $cmd + } else { + Set-VMKeystrokes -VMName $VMName -StringInput $cmd -ReturnCarriage $true + Start-Sleep -Seconds 1 + } + } + } + + <# + # Configure and Enable VyOS REST API + # REST API not very functional, no GET operatoin and a bit kludgey on setup + + $httpApiConf = "http-api.conf" + + $config = @" +{ + "listen_address": "$($ManagementAddress.substring(0,$ManagementAddress.IndexOf('/')))", + "port": 8080, + "debug": true, + "api_keys": [ + {"id": "powercli", "key": "${ManagementPassword}"} + ] +} +"@ + + $config | Set-Content "$httpApiConf" + + Get-Item "$httpApiConf" | Copy-VMGuestFile -LocalToGuest -Destination "/home/vyos/${httpApiConf}" -VM (Get-VM $VMName) -GuestUser "vyos" -GuestPassword "$ManagementPassword" -Force + + Write-Host "Creating VyOS REST API Configuration /etc/vyos/${httpApiConf} ..." + $scriptText = "echo `"${ManagementPassword}`" | sudo -S cp /home/vyos/${httpApiConf} /etc/vyos/${httpApiConf}" + Invoke-VMScript -ScriptText $scriptText -vm (Get-VM $VMName) -GuestUser "vyos" -GuestPassword $ManagementPassword + + Write-Host "Starting VyOS REST API ..." + $scriptText = "echo `"${ManagementPassword}`" | sudo -S systemctl start vyos-http-api" + Invoke-VMScript -ScriptText $scriptText -vm (Get-VM $VMName) -GuestUser "vyos" -GuestPassword $ManagementPassword + #> +} \ No newline at end of file diff --git a/Modules/VyOS/vyos.template b/Modules/VyOS/vyos.template new file mode 100644 index 0000000..023ec46 --- /dev/null +++ b/Modules/VyOS/vyos.template @@ -0,0 +1,66 @@ +configure + +set service ssh port 22 + +set interfaces ethernet eth0 address '[MANAGEMENT_ADDRESS]' +set interfaces ethernet eth0 description 'Outside' +set interfaces ethernet eth1 address '192.168.0.1/24' +set interfaces ethernet eth1 description 'Inside' +set nat source rule 100 outbound-interface 'eth0' +set nat source rule 100 translation address '[MANAGEMENT_IP]' +set nat source rule 100 translation address 'masquerade' +set protocols static route 0.0.0.0/0 next-hop [MANAGEMENT_GATEWAY] + +set interfaces ethernet eth1 mtu '1700' +set interfaces ethernet eth1 vif 10 address '172.30.10.1/24' +set interfaces ethernet eth1 vif 10 description 'VLAN 10 for MGMT' +set interfaces ethernet eth1 vif 20 address '172.30.20.1/24' +set interfaces ethernet eth1 vif 20 description 'VLAN 20 for HOST VTEP' +set interfaces ethernet eth1 vif 20 mtu '1700' +set interfaces ethernet eth1 vif 30 address '172.30.30.1/24' +set interfaces ethernet eth1 vif 30 description 'VLAN 30 for EDGE VTEP' +set interfaces ethernet eth1 vif 30 mtu '1700' +set interfaces ethernet eth1 vif 40 address '172.30.40.1/24' +set interfaces ethernet eth1 vif 40 description 'VLAN 40 for EDGE UPLINK' +set interfaces ethernet eth1 vif 40 mtu '1700' + +set nat destination rule 100 description 'RDP to [JUMPHOST_VM_IP]:3389' +set nat destination rule 100 destination port '3389' +set nat destination rule 100 inbound-interface 'eth0' +set nat destination rule 100 protocol 'tcp' +set nat destination rule 100 translation address '192.168.0.10' +set nat destination rule 100 translation port '3389' + +set service dns forwarding domain [MANAGEMENT_DNS_DOMAIN] server [MANAGEMENT_DNS_SERVER] +set service dns forwarding domain 10.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER] +set service dns forwarding domain 20.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER] +set service dns forwarding domain 30.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER] +set service dns forwarding domain 40.30.172.in-addr.arpa. server [MANAGEMENT_DNS_SERVER] +set service dns forwarding allow-from 0.0.0.0/0 +set service dns forwarding listen-address 192.168.0.1 +set service dns forwarding listen-address 172.30.10.1 +set service dns forwarding listen-address 172.30.20.1 +set service dns forwarding listen-address 172.30.30.1 +set service dns forwarding listen-address 172.30.40.1 +set service dns forwarding name-server 8.8.8.8 +set service dns forwarding name-server 8.8.8.4 + +set nat source rule 10 outbound-interface eth0 +set nat source rule 10 source address 172.30.10.0/24 +set nat source rule 10 translation address masquerade + +set nat source rule 20 outbound-interface eth0 +set nat source rule 20 source address 172.30.20.0/24 +set nat source rule 20 translation address masquerade + +set nat source rule 30 outbound-interface eth0 +set nat source rule 30 source address 172.30.30.0/24 +set nat source rule 30 translation address masquerade + +set nat source rule 40 outbound-interface eth0 +set nat source rule 40 source address 172.30.40.0/24 +set nat source rule 40 translation address masquerade + +commit +save +exit \ No newline at end of file