Export/Import vCloud Director 5.1 OrgNetworks with PowerCLI

I decided to provide an extension on the last post I did, Creating OrgNetworks in vCloud Director 5.1 with PowerCLI.  I had a need for being able to export OrgNetworks from a vCD 5.1 environment and be able to replicate/rebuild/recreate the OrgNetworks from the exported list.  Due to this need I attempted to create a PowerCLI script to do this for me.  Here is what I came up with, mind you it isn’t the sexiest script in the world but it worked for my needs and can be easily adjusted to fit yours.  

Here is the script for the export:

#
# Export-OrgNetworks.ps1
# Created by: James Bowling <james.bowling@vsential.com>
#

<#
.SYNOPSIS
Exports OrgNetworks to a CSV file export

.DESCRIPTION
Use this script to export all OrgNetworks in a specified VDC to a CSV file.

.SYNTAX
Export-OrgNetworks.ps1 -s cloud.vsential.lab -v 1001 -f OrgNetworks.csv

.PARAMETER Server
The vCloud Director server you want to connect to.

.PARAMETER Vdc
The oVDC you want to export OrgNetworks from.

.PARAMETER File
The output path and filename for the export to go to.

.EXAMPLE
Export-OrgNetworks.ps1 -s vcloud.vsential.lab -v 1001 -f OrgNetworks-Exported.csv
This command will export the OrgNetworks of oVDC 1001 into .\OrgNetworks-Exported.csv.
#>

# Take in command line arguments for vCD, oVDC, and output file.
param(
[parameter(Mandatory = $true, HelpMessage="vCD Server")][alias("-server","s")][ValidateNotNullOrEmpty()][string[]]$CIServer,
[parameter(Mandatory = $true, HelpMessage="OrgVDC")][alias("-vdc","v")][ValidateNotNullOrEmpty()][string[]]$OrgVdc,
[parameter(Mandatory = $true, HelpMessage="Filename")][alias("-file","f")][ValidateNotNullOrEmpty()][string[]]$OrgNetFile
)

# Connect to vCloud Director server
Write-Host "Connecting to $CIServer..."
Connect-CIServer $CIServer | Out-Null

# Export OrgNetworks to a CSV File
Write-Host "Exporting all OrgNetworks in $OrgVdc to $OrgNetFile"

$report = @()

$report += Get-OrgNetwork | Foreach {
$_ | Select Org,Name,Description,NetworkType,Gateway,Netmask,PrimaryDns,SecondaryDns,NetworkPool,StaticIPPool,ExternalNetwork,Id,@{N="IsShared";E={($_.extensiondata.isshared)}}
}

$report | Export-Csv -NoTypeInformation -Path $($OrgNetFile)

Write-Host "Export complete to $OrgNetFile"

# Disconnect from vCloud Director server
Disconnect-CIServer $CIServer -Confirm:$false

Pretty straight forward deal here.  You run it like so:

.\Export-OrgNetworks.ps1 -s vcloud.vsential.lab -v 1001 -f OrgNetworks.csv

For an explanation of the parameters just look in the script or run get-help Export-OrgNetworks.ps1.  Now that we have the wonderful CSV with our exported data, I needed to be able to parse and recreate these networks from the CSV.  You need to understand that the Edge Gateway devices and all other required information was pre-built in the vCD environment.  So for those of you who are looking to use this to rebuild your networks from scratch, please build the necessary backing devices as this will only build the OrgNetworks.  Here is what I came up with this, again, not the sexiest script in the world but works well for me:

#
# Rebuild-OrgNetworks.ps1
# Created by: James Bowling <james.bowling@vsential.com>
#

<#
.SYNOPSIS
Recreates OrgNetworks from a CSV file export

.DESCRIPTION
Based on information within a CSV file of exported OrgNetworks, one can recreate
all OrgNetworks from this file.

.PARAMETER server
The vCloud Director server FQDN.

.PARAMETER org
The Organization name to create networks in.

.PARAMETER vdc
The OrgVDC within the Org to create the networks for.

.PARAMETER file
The input csv file of the exported OrgNetworks.

.EXAMPLE
Rebuild-OrgNetworks -s vcloud.vsential.lab -o 1002 -v 1001 -f OrgNetworks-Exported.csv
This command will rebuild the OrgNetworks in said file in said OrgVdc on said vCD Server.

.NOTES
TODO: Build checks into the code.
TODO: Add rebuild of services, if any, on routed networks.
#>

# Take in command line arguments
param(
[parameter(Mandatory = $true, HelpMessage="vCD Server")][alias("-server","s")][ValidateNotNullOrEmpty()][string[]]$CIServer,
[parameter(Mandatory = $true, HelpMessage="Org")][alias("-org","o")][ValidateNotNullOrEmpty()][string[]]$OrgName,
[parameter(Mandatory = $true, HelpMessage="OrgVDC")][alias("-vdc","v")][ValidateNotNullOrEmpty()][string[]]$OrgVdc,
[parameter(Mandatory = $true, HelpMessage="Filename")][alias("-file","f")][ValidateNotNullOrEmpty()][string[]]$OrgNetFile
)

function debug {
Write-Host ""
Write-Host "Debug Information:"
Write-Host "Org Network Name: $orgNetName"
Write-Host "Org Name: "$org.name
Write-Host "Created Network Name: "$mynetwork.name
if ($_.networktype -eq "Routed"){ Write-Host "Edge Gateway Href: "$edgegateway.href }
if ($_.networktype -eq "Routed|Isolated"){ Write-Host "IP Addresses: "$ippool[0] $ippool[1] }
if ($_.networktype -eq "Direct"){ Write-Host "External Network Href: "$externalnetwork.href }
Write-Host ""
}

function createrouted {
$orgNetName = $_.name
$org = Get-OrgVdc $OrgName | Get-CIView
$edgegateway = Search-Cloud -QueryType EdgeGateway | Get-CIView | ?{$_.name -like "$OrgName*"}
Write-Host "Creating Routed OrgNetwork: $orgNetName in $OrgName"

$mynetwork = new-object vmware.vimautomation.cloud.views.orgvdcnetwork
$mynetwork.name = $orgNetName
$mynetwork.edgegateway = $edgegateway.href
$mynetwork.isshared = $_.isshared

$mynetwork.configuration = new-object vmware.vimautomation.cloud.views.networkconfiguration
$mynetwork.configuration.fencemode = "natRouted"

$mynetwork.configuration.ipscopes = new-object vmware.vimautomation.cloud.views.ipscopes
$scope = new-object vmware.vimautomation.cloud.views.ipscope
$scope.gateway = $_.gateway
$scope.netmask = $_.netmask
$scope.dns1 = $_.primarydns
$scope.dns2 = $_.secondarydns

$scope.ipranges = new-object vmware.vimautomation.cloud.views.ipranges
$scope.ipranges.iprange = new-object vmware.vimautomation.cloud.views.iprange

# Split StaticIPPools string for separation of start/end addresses
$ippool = @()
$ippool += @($_.staticippool.split("-").trim())

$scope.ipranges.iprange[0].startaddress = $ippool[0]
$scope.ipranges.iprange[0].endaddress = $ippool[1]

$mynetwork.configuration.ipscopes.ipscope += $scope

$result = $org.CreateNetwork($mynetwork)
if ($debug -eq "1"){ debug }
}

function createdirect {
# Get External Network HRef Value
Write-Host "Retrieving External Network HRef Id..."
$externalnetworkname = $_.externalnetwork
$externalnetwork = Get-ExternalNetwork | Get-CIView | ?{$_.name -like "$externalnetworkname*"}

$orgNetName = $_.Name
$org = Get-OrgVdc $OrgName | Get-CIView
Write-Host "Creating Direct OrgNetwork: $orgNetName in $OrgName"

$mynetwork = new-object vmware.vimautomation.cloud.views.orgvdcnetwork
$mynetwork.name = $OrgNetName
$mynetwork.isshared = $_.isshared

$mynetwork.configuration = new-object vmware.vimautomation.cloud.views.networkconfiguration
$mynetwork.configuration.fencemode = "bridged"

$mynetwork.configuration.parentnetwork = New-Object vmware.vimautomation.cloud.views.reference
$mynetwork.configuration.parentnetwork.href = $externalnetwork.href

$result = $org.CreateNetwork($mynetwork)
if ($debug -eq "1"){ debug }
}

function createisolated {
$orgNetName = $_.Name
$org = Get-OrgVdc $OrgName | Get-CIView
Write-Host "Creating Isolated OrgNetwork: $orgNetName in $OrgName"

$mynetwork = new-object vmware.vimautomation.cloud.views.orgvdcnetwork
$mynetwork.name = $orgNetName
$mynetwork.isshared = $_.isshared

$mynetwork.configuration = new-object vmware.vimautomation.cloud.views.networkconfiguration
$mynetwork.configuration.fencemode = "isolated"

$mynetwork.configuration.ipscopes = new-object vmware.vimautomation.cloud.views.ipscopes
$scope = new-object vmware.vimautomation.cloud.views.ipscope
$scope.gateway = $_.gateway
$scope.netmask = $_.netmask
$scope.dns1 = $_.primarydns
$scope.dns2 = $_.secondarydns

$scope.ipranges = new-object vmware.vimautomation.cloud.views.ipranges
$scope.ipranges.iprange = new-object vmware.vimautomation.cloud.views.iprange

# Split StaticIPPools string for separation of start/end addresses
$ippool = @()
$ippool += @($_.staticippool.split("-").trim())

$scope.ipranges.iprange[0].startaddress = $ippool[0]
$scope.ipranges.iprange[0].endaddress = $ippool[1]

$mynetwork.configuration.ipscopes.ipscope += $scope

$result = $org.CreateNetwork($mynetwork)
if ($debug -eq "1"){ debug }
}

# Set to 1 to enable debug output
$debug = "0"

# Connect to vCloud Director server
Connect-CIServer $CIServer | Out-Null

# Read in OrgNetwork CSV File
$OrgNetworks = Import-CSV $OrgNetFile
ForEach ($_ in $OrgNetworks){
if ($_.networktype -eq "Routed"){ createrouted }
elseif ($_.networktype -eq "Direct"){ createdirect }
elseif ($_.networktype -eq "Isolated"){ createisolated }
else { Write-Host "Cannot determine network type!" }
}

# Disconnect from vCloud Director server
Disconnect-CIServer $CIServer -Confirm:$false

The script can be run as follows: .\Rebuild-OrgNetworks.ps1 -s vcloud.vsential.lab -o 1002-Org -v 1002-VDC -f OrgNetworks.csv

At a future date I hope to add the ability to recreate any services associated with the networks and possibly the ability to create Edge Gateway devices for you, if needed.  If you have any suggestions, comments, and/or questions then sound off in the comments and I will do my best to help you out.  I hope to see many different iterations of this from the community and if you modify this then please let me know, I would love to see what you did!

And one more thing, like my last post, a lot of the information I used to build this was built on information that Jake Robinson (GeekAfterFive.com) posted about creating vApp networks in vCD 5.1, so definitely thanks to him for his awesomeness and guidance!  So with that said, I hope that you find this useful and happy scripting!