In this Blog I will explain how to use Groups in NSX and how to create Groups with PowerCLI.
About NSX Firewall and Groups
The NSX Firewall is working based on IP to IP Communication, like all other Firewalls. But NSX will use different Identifiers to get the IP Information for the Firewall entries.
Instead of creating Firewall Rules based on Source/Destination IP(s) you will use Source/Destination Group(s).
Inside the Group you can can define how IP Addresses will be identified. My personal recommendation, using Membership Criteria based on following Identifiers:
- Virtual Machine TAG (Equals, Contains, Starts with, Ends with)
- Virtual Machine Name (Equals, Contains, Starts with, Ends with, Not Equals)
- Virtual Machine OS Name (Equals, Contains, Starts with, Ends with, Not Equals)
- Virtual Machine Computer Name (Equals, Contains, Starts with, Ends with, Not Equals)
- Segment Port TAG (Equals)
- Segment TAG (Equals)
- IP Set TAG (Equals)
Identifiers can be combined with “AND” or “OR”.
“AND” means all conditions must match, “OR” means at least one condition must match.
But you can also create Groups based on IP Networks or IP Addresses. This is useful to create Firewall Rules for Devices/Networks that are not directly connected to NSX.
You can also integrate your Active Directory in NSX and use AD Attributes to create your groups. This can be used for VDI or Remote Desktop environments to control Network Access based on the current User.
NSX Firewall can be used with the same principles you are using for Active Directory. Nobody will create new AD Groups if a new Employee starts working in a company. Normally you will check the rights from the new Employee and put him in the existing AD Groups.
We can do the same with NSX. Instead of creating a Firewall Entry for each new Server/Application, we set the right Tags to the new Machine and with the Tags the Machine is automatically Member in different Groups. If the Machine will be deleted, all Firewall Entries (IPtoIP) will be deleted automatically.
Creating Groups with PowerCLI
The Datasource for the Group Content can be different files like .csv file or in my example a .json file.
In my example I will create the Groups WEB, APP and DB for Virtual Machines (VirtualMachine) and also for Containers (SegmentPort).
But before we jump into the Details let’s have a look at the expected API Structure!
NSX Policy API Structure for Groups
GET https://<policy-mgr>/policy/api/v1/infra/domains/default/groupsNSX
{
"expression":[
{
"member_type":"VirtualMachine",
"key":"Tag",
"operator":"EQUALS",
"value":"WEB",
"resource_type":"Condition"
},
{
"conjunction_operator":"OR",
"resource_type":"ConjunctionOperator"
},
{
"member_type":"SegmentPort",
"key":"Tag",
"operator":"EQUALS",
"value":"WEB",
"resource_type":"Condition"
}
],
"resource_type":"Group",
"id":"A_WEB",
"display_name":"A_WEB",
"tags":[
{
"scope":"",
"tag":"PowerCLI"
}
]
}
The Order is sometimes a little bit complicated, but If you look only on the Brackets and Curly Brackets it become easier….;-) You will see that the output starts with the Group Content and on the bottom you will find the Group Information.
Now we will check the Fields in the Group Information:
"resource_type":"Group",
"id":"A_WEB",
"display_name":"A_WEB",
"tags":[
{
"scope":"",
"tag":"PowerCLI"
}
The “id” and “display_name” can be identical, but the “id” must be unique! If you search later for the Object with an API call you must search with the “id” in the NSX Manager UI you will see the “display_name”.
“tags” are optional but this will help to find Objects our Group of Objects faster.
Next we will check the first part in the Group Content:
"expression": [
{
"member_type": "VirtualMachine",
"key": "Tag",
"operator": "EQUALS",
"value": "WEB",
"resource_type": "Condition"
}
Be aware that the Text is case sensitive!
The “member_type” can be either “VirtualMachine”, “SegmentPort”, “Segment” or “IPSet”.
Depends on your Input, you may not have all options available.
The “key” can be “Name”, “Tag”, “OSName” or “ComputerName”
The “operator” can be “EQUALS”,”CONTAINS”, “STARTSWITH”, ENDSWITH”, “NOTEQUALS”
“value” will deliver the content for the “operator”. In the example above Virtual Machines with the exact Tag “WEB” will math this condition.
If you have only one criteria the “resource_type” will be “Condition”. But if you have more than one criteria (up to 5 criteria are allowed) you need to define how to combine the criteria.
Either all criteria must match “AND” or any criteria must match “OR”.
This will be done with “resource_type”: “ConjunctionOperator”
{
"conjunction_operator": "OR",
"resource_type": "ConjunctionOperator"
}
Now we are ready to create the Content!
Create Group Content for PowerCLI
I decided to use a .json file for my content because you can use .json also to retrieve the information from a Database or other CMDBs in your environment.
In my example I will create the Groups WEB, APP and DB for Virtual Machines (VirtualMachine) and also for Containers (SegmentPort). The Fields are simmilar the same we see before but in a different order to make it better readable.
[
{
"display_name":"A_WEB",
"id":"A_WEB",
"tag":"PowerCLI",
"groupspecinput":[
{
"member_type":"VirtualMachine",
"key":"Tag",
"value":"WEB",
"operator":"EQUALS",
"conjunction_operator":"OR"
},
{
"member_type":"SegmentPort",
"key":"Tag",
"value":"WEB",
"operator":"EQUALS"
}
]
},
{
"display_name":"A_APP",
"id":"A_APP",
"tag":"PowerCLI",
"groupspecinput":[
{
"member_type":"VirtualMachine",
"key":"Tag",
"value":"APP",
"operator":"EQUALS",
"conjunction_operator":"OR"
},
{
"member_type":"SegmentPort",
"key":"Tag",
"value":"APP",
"operator":"EQUALS"
}
]
},
{
"display_name":"A_DB",
"id":"A_DB",
"tag":"PowerCLI",
"groupspecinput":[
{
"member_type":"VirtualMachine",
"key":"Tag",
"value":"DB",
"operator":"EQUALS",
"conjunction_operator":"OR"
},
{
"member_type":"SegmentPort",
"key":"Tag",
"value":"DB",
"operator":"EQUALS"
}
]
}
]
You can paste the Text directly in the PowerShell Sript into a variable
$jsonfilegroups = 'Above_JSON_file'
And convert the Content into PowerShell Format
$jsonfilegroupsconverted = ConvertFrom-Json -InputObject $jsonfilegroups
Or you store the content as .json file and load the .json file into a PowerShell Variable. I will use this Option for my example.
$jsonfilegroupsconverted = Get-Content -Raw -Path /path/to/groups.json | ConvertFrom-Json
First we will set the Parameters for the Group
{
"display_name":"A_WEB",
"id":"A_WEB",
"tag":"PowerCLI",
And inside the Group we will create a list with the criteria
"groupspecinput":[
{
"member_type":"VirtualMachine",
"key":"Tag",
"value":"WEB",
"operator":"EQUALS",
"conjunction_operator":"OR"
},
{
"member_type":"SegmentPort",
"key":"Tag",
"value":"WEB",
"operator":"EQUALS"
}
]
May you recognize in the first block I set the “conjunction_operator”:”OR”. In the second block I didn’t set the “conjunction_operator”. If you would like to create more criteria, you need to set the “conjunction_operator” on all blocks but not on the last one!
When we created the .json file we can create the PowerCLI Script
Creating the PowerCLI Sscript
First we will convert the .json file into PowerShell format:
$jsonfilegroupsconverted = Get-Content -Raw -Path groups.json | ConvertFrom-Json
Your output should look similar. You can see that you have a second list inside the list under groupspecinput.
If you would like to check the list under groupspecinput you can do this with following command:
$jsonfilegroupsconverted.groupspecinput
Because we would create more than one group with this script, we need to create a foreach loop
foreach ($groupitem in $jsonfilegroupsconverted) {
Inside the the Loop we will retrieve the information to create a Group
$groupsvc = Get-NsxtPolicyService -Name com.vmware.nsx_policy.infra.domains.groups
and set the Group information we used in our .json file. The $groupdomainspec should be “default” if you didn’t change anything in NSX Manager.
$groupspec = $groupsvc.Help.patch.group.Create()
$groupspec.display_name = $groupitem.display_name
$groupdomainspec = "default"
$groupidspec = $groupsvc.Help.patch.group_id.Create()
$groupidspec = $groupitem.id
To find the objects better, we set also a Tag on the Group
$grouptag = $groupsvc.Help.patch.group.tags.Element.Create()
$grouptag.tag = $groupitem.tag
$groupspec.tags.Add($grouptag) | Out-Null
foreach ($criteria in $groupitem.groupspecinput) {
$groupspecexp = $groupsvc.Help.patch.group.expression.Element.condition.Create()
$groupspecexp.member_type = $criteria.member_type
$groupspecexp.key = $criteria.key
$groupspecexp.value = $criteria.value
$groupspecexp.operator = $criteria.operator
$groupspec.expression.Add($groupspecexp) | Out-Null
If we set more than one criteria we defined in our .json file the “conjuction_operator”. If the “conjunction_operator” exist, the Script will execute the commands. If not, the script will directly jump to the next section.
if ($criteria.conjunction_operator) {
$groupspec_conj = $groupsvc.Help.patch.group.expression.Element.conjunction_operator.Create()
$groupspec_conj.conjunction_operator = $criteria.conjunction_operator
$groupspec.expression.Add($groupspec_conj) | Out-Null
}
Now we need to close the criteria foreach loop and create the group.
}
$groupsvc.patch($groupdomainspec, $groupidspec, $groupspec)
To close the first foreach Loop we need to set again a curly bracket
}
If everything works fine you should see in your NSX Manager the newly created groups
In my last Blog (https://www.vrealize.it/2019/12/22/add-or-remove-tags-in-nsx-t-with-powercli/) I explained how to set Tags on VMs. So I will also see the effective Members in the Group
Following you will find my complete Script (without the .json part)
$jsonfilegroupsconverted = Get-Content -Raw -Path groups.json | ConvertFrom-Json
#Create Groups
Write-Output ""
Write-Host "Create Groups" -ForegroundColor Green
foreach ($groupitem in $jsonfilegroupsconverted) {
$groupsvc = Get-NsxtPolicyService -Name com.vmware.nsx_policy.infra.domains.groups
#Add Group Content
$groupspec = $groupsvc.Help.patch.group.Create()
$groupspec.display_name = $groupitem.display_name
$groupdomainspec = "default"
#Add Group ID
$groupidspec = $groupsvc.Help.patch.group_id.Create()
$groupidspec = $groupitem.id
#Add TAG
$grouptag = $groupsvc.Help.patch.group.tags.Element.Create()
$grouptag.tag = $groupitem.tag
$groupspec.tags.Add($grouptag) | Out-Null
#Add Group Membership Criteria
foreach ($criteria in $groupitem.groupspecinput) {
$groupspecexp = $groupsvc.Help.patch.group.expression.Element.condition.Create()
$groupspecexp.member_type = $criteria.member_type
$groupspecexp.key = $criteria.key
$groupspecexp.value = $criteria.value
$groupspecexp.operator = $criteria.operator
$groupspec.expression.Add($groupspecexp) | Out-Null
#Combine Criterias
if ($criteria.conjunction_operator) {
$groupspec_conj = $groupsvc.Help.patch.group.expression.Element.conjunction_operator.Create()
$groupspec_conj.conjunction_operator = $criteria.conjunction_operator
$groupspec.expression.Add($groupspec_conj) | Out-Null
}
}
$groupsvc.patch($groupdomainspec, $groupidspec, $groupspec)
Write-Host "Created Group" $groupidspec
}
Happy Reading!
- Setup NSX Application Platform from Scratch(K8S+MetallB+NFS Storage) - 25. February 2022
- Securing you K8S-Network with Antrea ClusterNetworkPolicy - 28. September 2020
- Integrate NSX Advanced Load Balancer (Formerly Avi Networks) in NSX-T - 17. August 2020
Hey! Love you blogs… I was wondering if you could help me with creating a group based on an AD Group. It doesn’t seem to be the same as creating a group and might require some additional expressions… I’m doing all my work in PowerCLI based on some of the other scripts on your site.
I think it needs to use the DN and Base DN, and this is what I have so far…
Not sure if it will come through on this form.
#Create Group – User – AD (IDFW)
#Variables
$groupdomain = “default”
$groupid = “Lab – $UserName – AD Group”
$dn = “CN=KAhnemann-NSX,OU=NSX Groups,OU=Groups,OU=AccudataLab,DC=AccudataLab,DC=com”
$basedn = “DC=AccudataLab,DC=com”
$groupmember_type = “IdentityGroup”
#Retrieve Group Information
$groupdata = Get-NsxtPolicyService -Name com.vmware.nsx_policy.infra.domains.groups
#Set Group Variables
$groupspecification = $groupdata.Help.patch.group.Create()
$groupspecification.display_name = $groupid
$groupspecification.description = $description
#Add Group Member Variables
$groupexpspecification = $groupdata.Help.patch.group.expression.Element.condition.Create()
$groupexpspecification.member_type = $groupmember_type
$groupexpspecification.domain_base_distinguished_name = $basedn
$groupexpspecification.distinguished_name = $dn
$groupspecification.expression.Add($groupexpspecification) | Out-Null
#Add Powercli TAG to Group
$grouptag = $groupdata.Help.patch.group.tags.Element.Create()
$grouptag.tag = $powerclitag
$groupspecification.tags.Add($grouptag) | Out-Null
#Add User TAG to Group
$grouptag = $groupdata.Help.patch.group.tags.Element.Create()
$grouptag.tag = $usertag
$groupspecification.tags.Add($grouptag) | Out-Null
#Create Group
$groupdata.patch($groupdomain, $groupid, $groupspecification)
I get this error
PS C:\Users\adminka>
PS C:\Users\adminka>
PS C:\Users\adminka>
PS C:\Users\adminka> #Create Group – User – AD (IDFW)
PS C:\Users\adminka> #Variables
PS C:\Users\adminka> $groupdomain = “default”
PS C:\Users\adminka> $groupid = “Lab – $UserName – AD Group”
PS C:\Users\adminka> $dn = “CN=KAhnemann-NSX,OU=NSX Groups,OU=Groups,OU=AccudataLab,DC=AccudataLab,DC=com”
PS C:\Users\adminka> $basedn = “DC=AccudataLab,DC=com”
PS C:\Users\adminka> $groupmember_type = “IdentityGroup”
PS C:\Users\adminka> #Retrieve Group Information
PS C:\Users\adminka> $groupdata = Get-NsxtPolicyService -Name com.vmware.nsx_policy.infra.domains.groups
PS C:\Users\adminka> #Set Group Variables
PS C:\Users\adminka> $groupspecification = $groupdata.Help.patch.group.Create()
PS C:\Users\adminka> $groupspecification.display_name = $groupid
PS C:\Users\adminka> $groupspecification.description = $description
PS C:\Users\adminka> #Add Group Member Variables
PS C:\Users\adminka> $groupexpspecification = $groupdata.Help.patch.group.expression.Element.condition.Create()
PS C:\Users\adminka> $groupexpspecification.member_type = $groupmember_type
PS C:\Users\adminka> $groupexpspecification.domain_base_distinguished_name = $basedn
SetValueInvocationException: Exception setting “domain_base_distinguished_name”: “The property ‘domain_base_distinguished_name’ cannot be found on this object. Verify that the property exists and can be set.”
PS C:\Users\adminka> $groupexpspecification.distinguished_name = $dn
SetValueInvocationException: Exception setting “distinguished_name”: “The property ‘distinguished_name’ cannot be found on this object. Verify that the property exists and can be set.”
PS C:\Users\adminka> $groupspecification.expression.Add($groupexpspecification) | Out-Null
PS C:\Users\adminka> #Add Powercli TAG to Group
PS C:\Users\adminka> $grouptag = $groupdata.Help.patch.group.tags.Element.Create()
PS C:\Users\adminka> $grouptag.tag = $powerclitag
PS C:\Users\adminka> $groupspecification.tags.Add($grouptag) | Out-Null
PS C:\Users\adminka> #Add User TAG to Group
PS C:\Users\adminka> $grouptag = $groupdata.Help.patch.group.tags.Element.Create()
PS C:\Users\adminka> $grouptag.tag = $usertag
PS C:\Users\adminka> $groupspecification.tags.Add($grouptag) | Out-Null
PS C:\Users\adminka> #Create Group
PS C:\Users\adminka> $groupdata.patch($groupdomain, $groupid, $groupspecification)
Thanks!
Hello Daniel,
Do you have example which shows how to create the Security Groups from excel file?