Skip to content

Instantly share code, notes, and snippets.

@Cyreex
Created January 4, 2018 14:55
Show Gist options
  • Save Cyreex/6fac6531879f4c0524b365c693e00da8 to your computer and use it in GitHub Desktop.
Save Cyreex/6fac6531879f4c0524b365c693e00da8 to your computer and use it in GitHub Desktop.
<#
.SYNOPSIS
Migrate single Virtual Network Gateway with the NAT Rules between NVGRE Network Services.
.DESCRIPTION
General features of that script:
- Migrate Virtual Network Gateway with several different external IPs
- Good protection from the fool :)
- Show all collected information about Virtual Network Gateway before delete
- You will newer lost of your data
.PARAMETER VMMServer
Your System Center VMM Server
.EXAMPLE
./NVGRE-Migration.ps1
.NOTES
Was tested with System Center VMM 2016
VPN settings migration isn't supported
.LINK
http://www.lin.by
#>
param(
[string]$VMMServer
)
#Enter SCVMM Server name, if then not exists
while (!(Get-ScvmmServer -ComputerName $VMMServer)) {
$SCVMMServer = Read-Host "Enter VMM Server Name:"
}
function SelectNetworkService($Side) {
<#
.SYNOPSIS
Show list VMM Network Services (NVGRE Only). You must select one of they.
.PARAMETER Side
May be "SOURCE" or "DESTINATION"
#>
#Is receive all Network Services with NVGRE enabled
$NetworkServices = Get-SCNetworkService | WHERE {$_.NVGRESupported -eq $true} | SORT Name
#Show list NVGRE Services
$counter = 0
foreach ($NetworkService in $NetworkServices) {
Write-Host $counter, $NetworkService.Name -ForegroundColor Yellow
$counter++
}
#Select NVGRE Services
$NetworkServiceNumber = Read-Host "Enter $Side NetworkService number"
while (!$NetworkServices[$NetworkServiceNumber]) {
Write-Host "Please enter correct $Side NetworkService number!" -ForegroundColor Red
$NetworkServiceNumber = Read-Host "Enter $Side NetworkService number"
}
Write-Host ($NetworkServices[$NetworkServiceNumber]).Name selected successfully -ForegroundColor green
return $NetworkServices[$NetworkServiceNumber]
}
function SelectNetwork() {
<#
.SYNOPSIS
Show list of VMM Networks on selected VMM Network Service. You must select one of they
#>
#Show list of networks on selected VMM Network Service
$counter = 0
foreach ($ListSourceNetwork in $VmNetworksOnSourceNetworkService) {
Write-Host $counter, $ListSourceNetwork.Name, $ListSourceNetwork.Owner -ForegroundColor Yellow
$counter++
}
#Select one number of network
$SourceNetworkNumber = Read-Host "Enter SOURCE network number"
#Check selected network
while (!$VmNetworksOnSourceNetworkService[$SourceNetworkNumber]) {
Write-Host "Please enter correct Network number!" -ForegroundColor Red
$SourceNetworkNumber = Read-Host "Enter SOURCE network number"
}
Write-Host ($VmNetworksOnSourceNetworkService[$SourceNetworkNumber]).Name selected successfully -ForegroundColor green
return $VmNetworksOnSourceNetworkService[$SourceNetworkNumber]
}
function CheckData() {
<#
.SYNOPSIS
Validation of entered data
.DESCRIPTION
You should check all data about your migrate gateway:
- Source and destination VMM Network Service
- Existings external IP Addressess (may be several)
- Existings NAT Rules (yor can copy and save they)
If all information is correct, your should type Y or y. If no - type any other letter, and script will be end.
#>
Write-Host "Check all data:" -BackgroundColor Green
Write-Host "Selected Network: $SelectedNetwork ($SourceNetworkService)" -ForegroundColor Magenta
Write-Host "External IP Addressess:" -ForegroundColor Magenta
$ExternalIPAddressess
Write-Host "Nat Rules:" -ForegroundColor Magenta
foreach ($NatRule in $NatRules) {
Write-Host $NatRule.Name, $NatRule.ExternalIPAddress, $NatRule.ExternalPort, $NatRule.InternalIPAddress, $NatRule.InternalPort -ForegroundColor Magenta
}
Write-Host "Source NetworkService: $SourceNetworkService" -ForegroundColor Magenta
Write-Host "Destination NetworkService: $DestinationNetworkService" -ForegroundColor Magenta
#Waiting your confirmation entered data
$checker = Read-Host "Is information correct? (Y/N)"
if ($checker -eq "Y" -or $checker -eq "y") {
Write-Host "Ok" -ForegroundColor Green
} else {
Write-Host "You have selected $checker. Script was break!" -ForegroundColor Red
break
}
}
function CheckDestinationNetworkService() {
<#
.SYNOPSIS
Checking that destination Network Service has available network domain
#>
$MaxRoutingDomains = $DestinationNetworkService.MaxRoutingDomainSupported
$Counter = 0
foreach ($VmNetwork in $VmNetworks) {
$VMNetworkGateway = Get-SCVMNetworkGateway -VMMServer $VMMServer -VMNetwork $VMNetwork
if ($VMNetworkGateway.NetworkGateway.Name -eq $DestinationNetworkService) {
$Counter++
}
}
if ($MaxRoutingDomains -gt $Counter) {
Write-Host "Destination gateway test was passed" -ForegroundColor Green
return $true
} else {
Write-Host "Destination gateway test failed! He isn't have free routing domains. Please select another NetworkService!" -ForegroundColor Red
return $false
}
}
#Select source NetworkService
$SourceNetworkService = SelectNetworkService("SOURCE")
#Getting all VM Networks with VMNetworkGateways
$VmNetworks = Get-SCVMNetwork -VMMServer $VMMServer | WHERE {$_.VMNetworkGateways -ne $NULL}
#Select VM Networks on source NetworkService
$VmNetworksOnSourceNetworkService=@()
foreach ($VmNetwork in $VmNetworks) {
$VMNetworkGateway = Get-SCVMNetworkGateway -VMMServer $VMMServer -VMNetwork $VMNetwork
if ($VMNetworkGateway.NetworkGateway.Name -eq $SourceNetworkService) {
$VmNetworksOnSourceNetworkService+=$VmNetwork
}
}
#If NetworkService not contain domains, script will be break
if ($VmNetworksOnSourceNetworkService.Count -eq 0) {
Write-Host "Source NetworkService $SourceNetworkService not contain domains" -ForegroundColor Yellow
break
}
#Show and select network
$SelectedNetwork = SelectNetwork
#Collect information about VMNetwork
$GW = Get-SCVMNetworkGateway -VmmServer $VMMServer -VMNetwork $SelectedNetwork
$NatRules = Get-SCNATRule -VMMServer $VMMServer -VMNetworkGateway $GW
$ExternalIPAddressess = $NatRules | WHERE {$_.ExternalPort -eq 0} | SELECT ExternalIPAddress, NATConnection -Unique
$NatRules = $NatRules | WHERE {$_.ExternalPort -ne 0}
#Create NAT Rules Array
$NatRulesArr = @()
foreach ($i in $NatRules) {
$NatRulesProps = @{
name = $i.Name
ExternalIPAddress = $i.ExternalIPAddress
ExternalPort = $i.ExternalPort
InternalIPAddress = $i.InternalIPAddress
InternalPort = $i.InternalPort
Protocol = $i.Protocol
NATConnection = $i.NATConnection.ToString()
}
$tmpObject = New-Object -TypeName PSObject -Property $NatRulesProps
$NatRulesArr+=$tmpObject
}
#Select destination network service
Do {$DestinationNetworkService = SelectNetworkService("DESTINATION")}
While (!(CheckDestinationNetworkService))
#Check that all collected data is correct
CheckData
#Set the errors variable (marker)
$Errors = $false
#Remove old Network Service Gateway
if (($GW).Count -eq 1) {
try {
Remove-SCVMNetworkGateway -VMMServer $VMMServer -VMNetworkGateway $GW
} catch {
Write-Host "Gateway wasn't removed!" -ForegroundColor Red
$_.Exception.Message
$Errors = $true
} finally {
if ($errors -eq $false) {Write-Host "Gateway was removed" -ForegroundColor Green}
}
} else {
Write-Host "GW Count NOT equal 1! (($GW).Count)" -ForegroundColor Red
$Errors = $true
}
#Add new Virtual Network Gateway
if ($Errors -eq $false) {
try {
Add-SCVMNetworkGateway -VMMServer $VMMServer -Name $GW.Name -EnableBGP $false -NetworkGateway $DestinationNetworkService -VMNetwork $SelectedNetwork
} catch {
Write-Host "Gateway wasn't created!" -ForegroundColor Red
$_.Exception.Message
$Errors = $true
} finally {
if ($errors -eq $false) {Write-Host "Geteway was created" -ForegroundColor Green}
}
}
#Add NAT Connections
if ($Errors -eq $false) {
try {
$NewGW = Get-SCVMNetworkGateway -VMMServer $VMMServer -VMNetwork $SelectedNetwork
$NatConnection = @()
foreach ($ExternalIPAddress in $ExternalIPAddressess) {
$NatConnection += Add-SCNATConnection -VMMServer $VMMServer -Name $ExternalIPAddress.NATConnection.ToString() -VMNetworkGateway $NewGW -ExternalIPAddress $ExternalIPAddress.ExternalIPAddress.IPAddressToString
}
} catch {
Write-Host "NAT connections wasn't created!" -ForegroundColor Red
$_.Exception.Message
$Errors = $true
} finally {
if ($errors -eq $false) {Write-Host "Nat connections was created" -ForegroundColor Green}
}
}
#Add NAT Rules
foreach ($NatRule in $NatRulesArr) {
if ($Errors -eq $false) {
try {
$TargetNatConnection = $NatConnection | WHERE {$_.Name -eq $NatRule.NATConnection}
if ($TargetNatConnection) {
Add-SCNATRule -VMMServer $VMMServer -NATConnection $TargetNatConnection -Name $NatRule.Name -ExternalPort $NatRule.ExternalPort -InternalPort $NatRule.InternalPort -InternalIPAddress $NatRule.InternalIPAddress -Protocol $NatRule.Protocol
} else {
Write-Host "NAT rule $NatRule.Name wasn't created, because TargetNatConnection is fill!" -ForegroundColor Yellow
}
} catch {
Write-Host "NAT rule wasn't created!" -ForegroundColor Red
$_.Exception.Message
$Errors = $true
} finally {
$name = $NatRule.Name
if ($errors -eq $false) {Write-Host "NAT rule $name was created" -ForegroundColor Green}
}
}
}
#Check and show job status
if ($errors -eq $false) {
Write-Host "All tasks completed successfully!" -ForegroundColor Green
} else {
Write-Host "Tasks completed with errors!" -ForegroundColor Red
}
#The End!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment