Storing the VMware NSX config in version control

Almost any organization that I've had the pleasure of talking with, uses Git either for code repositories where their developers work or for doing version control on their infrastructure systems. Git is an excellent version control tool and is widely used for both developers and also infrastructure configuration. This post goes into how to put the VMware NSX configuration into version control using Git.

Not all infrastructure components (server systems, network devices, etc) have a proper audit log on what happens in the configuration and who is doing what exactly. This is where version control can lend a helping hand to store device configurations throughout the time for reference. It will know exactly what has changed and when. Sometimes even by who (depending on the device output). I've been using version control for network devices for a very long time, ever since I did a "whoops" on a switch (yes, both running and startup config gone) when I was a junior network admin. One of my favorite tools, RANCID, uses version control to store the show running-configuration of devices to generate a change log for the networks configuration.

Note: I'm currently talking about retrieving configuration from running devices and storing it. There's another trend called Infrastructure-as-Code where the config is first put inside version control and then pushed out the devices through an automated process. That's a step further then what this post explains (and to be honest, a step further then what most of my customers need/want).

NSX Version Control

The native version control (audit log) within NSX isn't that great (side note: this is in relation to NSX-v, NSX-T has better version control). The Distributed Firewall has a Saved Configurations feature where it stores the last 100 changes, but the rest (Edges, Logical Switches, Security Groups/Tags/Policies, etc, etc) isn't that thorough. You have an option to create a back-up of the NSX Manager in its entirety, which generates a zip file with all configuration in there - but not viewable. Most of all, it does not keep the differences between certain back-ups. Restores mean a restore of the entire NSX Manager config. So the backup functionality isn't a version control system.


Luckily, the NSX API has the ability to export the configuration in a readable format (XML) which can be used to do version control on.

I've been wanting to get my home lab under version control (so I can easily recover small bits of config) and lately a couple of asks from NSX customers has lead to a script that uses the NSX API via PowerNSX to read out the NSX configuration and put it in a Git repository. The next paragraph will explain how to use it, but there's an example of the output:

Git Repository with NSX Configuration Difference view for removing a Security Tag
NSX Configuration in Git. Difference view between versions.
(removing a Security Tag)

NSX to Git Script

As usual, you can find the script in one of my GitHub repositories, here. It's a pretty simple task to use it, but there are a few preparation steps involved. I'll go into those below.


Before you can run nsx-to-git.ps1, you will need to install PowerCLI and PowerNSX. You also need Git installed and ready to go.

Instantiating a Git repository

We're going to be storing the NSX configuration inside a Git repository. This means you need to have at a repository somewhere. This can be on local disk of where you're running the script, or it can be a remote Git server. I vote remote, as the intent is to create a version control system which is available to consult for multiple people.

Do not put it on a public GitHub repository. The configuration doesn't include passwords and such, but it does include your entire IP schema and firewall rules. Make it a private/company Git server. GitLab is an awesome option for internal Git repositories. A manual on how to install and use GitLab can be found here.

Once you have a target repository set up, instantiate a local repository and link it to your remote one:

cd ~
mkdir nsx-to-git-output
git init
git remote add origin
echo '# NSX Configuration' >
git add
git commit -a -m 'Initial commit'
git push -u origin master

This sequence creates a new directory called nsx-to-git-output in your home directory. Feel free to put it somewhere else. When doing the git push, it will ask you for the credentials to use for the remote repository.

Running NSX-to-Git

After the Git repository has been instantiated and you've successfully linked it to your remote repository, you can run the script like so:

On Linux / MacOS:

./nsx-to-git.ps1 -GitBinary "/usr/bin/git" -GitRepoPath ~/nsx-to-git-output

On Windows:

.\nsx-to-git.ps1 -GitBinary "C:\Program Files\Git\bin\git.exe" -GitRepoPath ~\nsx-to-git-output

Here is an example of how it will look:

Running NSX-to-Git


Scheduling is what this type of version control is all about, as you'd want to automatically archive a version of the current configuration every X interval. That interval is something you need to think about. My home lab is on an interval of 10 minutes because of the number of changes that can happen quickly. Most other tools go for a 30-minute interval, but it's all up to you.

Before you can schedule this script, you need to do a couple of things:


This script depends on a connection to the NSX Manager and vCenter, which need credentials. You don't want to insert those credentials in plain text in the scheduled task, so store these into an encrypted credential file. Here's how:

Creating PowerShell credentials

When you execute Get-Credential, you will be prompted for a username and password. On the first go, input the login for your NSX Manager and on the second go, input our vCenter credentials. After this, you will have created 2 files, each with separately encrypted credentials for the required connections.

Running from a Scheduled Task

As mentioned before, the nsx-to-git.ps1 script relies on an existing connection to NSX and vCenter. This means you need to connect to NSX and vCenter before nsx-to-git.ps1 is executed. You can do this by having a simple pre-run script that establishes the connections and then goes on to run nsx-to-git.ps1. Here's mine:


Import-Module VMware.PowerCLI
Import-Module PowerNSX

$cred_nsx     = (Import-Clixml -Path C:\Users\martijn\Desktop\NSX-to-Git\cred-nsx.xml)
$cred_vcenter = (Import-Clixml -Path C:\Users\martijn\Desktop\NSX-to-Git\cred-vcenter.xml)

Connect-NsxServer -NsxServer manager.nsx.lab.local -Credential $cred_nsx -VICredential $cred_vcenter

C:\Users\martijn\Desktop\NSX-to-Git\nsx-to-git.ps1 -GitBinary "C:\Program Files\Git\bin\git.exe" -GitRepoPath C:\Users\martijn\Desktop\NSX-to-Git\output

* of course, modifying the paths to each file.

Then create a scheduled task to start the program Powershell.exe with these arguments:

-ExecutionPolicy Bypass C:\Users\martijn\Desktop\NSX-to-Git\run-nsx-to-git.ps1 -RunType $true -Path C:\Users\martijn\Desktop\NSX-to-Git

* of course, modifying the paths to each file.


That's it! You now have a copy of your NSX configuration in version control that's updated every x interval, with a complete record of what changed.

Commit log of NSX-to-Git



Share the wealth!


  1. Great post! Have you run into any cases in your environment where values in certain objects come back in a different order between runs?

    For example, ipset-0 has, the first time and, the next time? Same values just different order. This is seen just from raw API call, so its not something that gets introduced from powershell.

    We are chewing on this problem and I’m curious if it was something you solved. NSX 6.3.2 in this case.

    • Martijn

      May 22, 2018 at 05:00

      Hi Ed,

      Thanks! And yes, I’m seeing that happen with IP sets and some NSX Manager configurations. Unfortunately, it seems like the API is wired that way. Normally you wouldn’t care in which order it returns, but in this case, it’s pretty annoying. I’m checking internally with VMware to see if there’s anything that can be done about it. 😉

      • Thanks Martijn! We might try to figure out a way to normalize that data before it goes into git, if we can get some time set aside for that.

  2. With the release of Powershell core 6.2 this script runs beautifully on linux as well. It had some issues storing the credentials with the previous releases but those are fixed now. There’s only one issue that I struggle with; the git repo path. I’ve raised an issue on the project’s github page to resolve this. Any chance we can work on this?

Leave a Reply

Your email address will not be published. Required fields are marked *

© 2024 Lostdomain

Theme by Anders NorénUp ↑