pamiller21
Enthusiast
Enthusiast

Applying NSXT Tag to a VM

Jump to solution

I am switching over to NSXT from V and trying to figure out how to convert my script to apply NSXT Tags to new VMs being built.  Any help would be appreciated 

0 Kudos
1 Solution

Accepted Solutions
Zsoldier
Expert
Expert

Have you tried running the code I posted above verbatim?  There are lots of problems w/ the way that you've modified your script.  $apiendpoint is not defined correctly since you've commented it out and is not before you capture your base_url.  Commenting out scope doesn't work the way you've done here.  I've cleaned up my script example further so you can omit scope if you don't need it and change the get-vm call to base on a vmnamefilter variable.  

Also, you do not need to import the PowerNSX module unless you are making additional calls to an NSX-V instance in the same script.

#Requires -Module vmware.powercli
$Credential = Get-Credential
$skipcertcheck = $true
$AuthMethod = “Basic”
$NSXMgr=”0.0.0.0”
$apiendpoint = "/api/v1/fabric"
$base_url = ("https://" + $NSXMgr + $apiendpoint)
$tag = "Naka"
$scope = "NakaScope"  # If scope not required, simply define as $null or ""
$vmnamefilter = "nakabuntu" # Not required.  Will loop through all VM's otherwise.

$vms = Get-VM $vmnamefilter | Get-View -Property "Config"
# Add Tags to existing tags (Valid for NSX-T 3.1.2, previous versions only have update_tag)
$endpoint = "/virtual-machines"
$action = "add_tags"
Foreach ($vm in $vms)
{
    $vmid = $vm.Config.InstanceUuid
    If ([string]::IsNullOrWhiteSpace($Scope)){
    $JSON = "
    {
        `"external_id`":`"$vmid`",
        `"tags`": [
            {
                `"tag`":`"$Tag`"
            }
            ]
    }
    "
    }
    Else{
        $JSON = "
        {
            `"external_id`":`"$vmid`",
            `"tags`": [
                {
                    `"scope`":`"$scope`",
                    `"tag`":`"$Tag`"
                }
                ]
        }
        "
    }
    $Data = Invoke-restmethod -Uri ($base_url + $EndPoint + "?action=" + $action) -Method POST -Body $JSON -ContentType 'application/json' -Credential $Credential -SkipCertificateCheck:$skipcertcheck -Authentication:$AuthMethod
}

 

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier

View solution in original post

19 Replies
LucD
Leadership
Leadership
pamiller21
Enthusiast
Enthusiast

I did not, my google-fu failed to find it.  I am doing some testing and missing something.  This seems to be used to apply a tag to nearly a full cluster I am trying to figure out how to filter it down to a single VM.

 

#############################
# Connect to vCenter #
#############################
Import-Module -Name VMware.PowerCLI
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$vc = 'URL'
$Cred = Import-Clixml /home/scripts/creds/creds.xml

Connect-VIServer $VC -Credential $Cred

#############################
# Connect to NSX-T #
#############################
Import-Module -Name VMware.PowerCLI
Import-Module PowerNSX
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$NSXCred = Import-Clixml /home/scripts/creds/nsxt.xml
$skipcertcheck = $true
$AuthMethod = “Basic”
$NSXMgr = ”URL”
$policyapi = "/policy/api/v1"
$base_url = ( "https://" + $NSXMgr + $policyapi )
$posturl = "https://$NSXMgr/api/v1/fabric/virtual-machines?action=update_tags"

$NSXTag = 'TAG'
$vm = 'SINGLE VM'
$vms = Get-VM $vm | ForEach-Object { $_ | Get-View }


foreach ($vm in $vms) {
$vmid = $vm.Config.InstanceUuid }

$geturl = "https://$NSXMgr/api/v1/fabric/virtual-machines?external_id=$vmid&included_fields=tags"
$getrequest = Invoke-RestMethod -Uri $geturl -Authentication Basic -Credential $nsxcred -Method Get -ContentType "application/json" -SkipCertificateCheck
$getresult = $getrequest.results | ConvertTo-Json -Compress
$currenttags = [regex]::match($getresult,'\[([^\)]+)\]').Groups[1].Value

$JSON = @"
{"external_id":"$vmid","tags": [{"scope":"$newscope","tag":"$NSXTag"},$currenttags]}
"@

Invoke-RestMethod -Uri $posturl -Authentication Basic -Credential $NSXCred -Method Post -Body $JSON -ContentType "application/json" -SkipCertificateCheck

0 Kudos
LucD
Leadership
Leadership

I think the script is for a single VM, the $vm = 'SINGLE VM' line seems to indicate that.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
pamiller21
Enthusiast
Enthusiast

What I pasted there was my mangled transformation of the site's script.  It doesn't seem to apply a tag to that single vm or do anything.  Not sure how to make it do that.

0 Kudos
Zsoldier
Expert
Expert

You need to define $newscope variable is what it looks like.

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
pamiller21
Enthusiast
Enthusiast

Somewhere that said it was optional, I don't have a scoped defined on my tag either so not sure what to put.

0 Kudos
Zsoldier
Expert
Expert

Scope can be anything really.  There are also other methods of tag updates available depending on version you are working against.  Which NSX-T version are you using?  3.1.2 gives you more options outside of just update tag to simplify your scripting too.  2.5.x limits to just update.

https://vdc-download.vmware.com/vmwb-repository/dcr-public/d6de7a5e-636f-4677-8dbd-6f4ba91fa5e0/36b4...

 

 

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
pamiller21
Enthusiast
Enthusiast

I am running 3.1.2, so can I put in any random keyword in the scope field?

Tags (1)
0 Kudos
pamiller21
Enthusiast
Enthusiast

@LucD When I run the code you sent I get this error:

ERROR:

Invoke-RestMethod: {
"httpStatus" : "BAD_REQUEST",
"error_code" : 220,
"module_name" : "common-services",
"error_message" : "Unexpected character (']' (code 93)): expected a value"

CODE:

#############################
# Connect to vCenter #
#############################
Import-Module -Name VMware.PowerCLI
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$vc = 'URL'
$Cred = Import-Clixml /home/scripts/creds/creds.xml

Connect-VIServer $VC -Credential $Cred

#############################
# Connect to NSX-T #
#############################
Import-Module -Name VMware.PowerCLI
Import-Module PowerNSX
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$NSXCred = Import-Clixml /home/scripts/creds/nsxt.xml
$skipcertcheck = $true
$AuthMethod = “Basic”
$NSXMgr = ”URL”
$policyapi = "/policy/api/v1"
$base_url = ( "https://" + $NSXMgr + $policyapi )
$posturl = "https://$NSXMgr/api/v1/fabric/virtual-machines?action=update_tags"

$NSXTag = 'TAG'
$vmName = 'SINGLE VM'
$vm = Get-VM -Name $vmName

$vmid = $vm.ExtensionData.Config.InstanceUuid

$geturl = "https://$NSXMgr/api/v1/fabric/virtual-machines?external_id=$vmid&included_fields=tags"
$getrequest = Invoke-RestMethod -Uri $geturl -Authentication Basic -Credential $nsxcred -Method Get -ContentType "application/json" -SkipCertificateCheck
$getresult = $getrequest.results | ConvertTo-Json -Compress
$currenttags = [regex]::match($getresult,'\[([^\)]+)\]').Groups[1].Value

$JSON = @"
{"external_id":"$vmid","tags": [{"scope":"$newscope","tag":"$NSXTag"},$currenttags]}
"@

Invoke-RestMethod -Uri $posturl -Authentication Basic -Credential $NSXCred -Method Post -Body $JSON -ContentType "application/json" -SkipCertificateCheck

Tags (1)
0 Kudos
Zsoldier
Expert
Expert

Basically means malformed json.  Here is script cleaned up a bit.

 

#Requires -Module vmware.powercli
$Credential = Get-Credential
$skipcertcheck = $true
$AuthMethod = “Basic”
$NSXMgr=”0.0.0.0”
$apiendpoint = "/api/v1/fabric"
$base_url = ("https://" + $NSXMgr + $apiendpoint)
$tag = "Naka"
$scope = "NakaScope"

$vms = Get-VM -Name nakabuntu | Get-View -Property "Config"
# Add Tags to existing tags (Valid for NSX-T 3.1.2, previous versions only have update_tag)
$endpoint = "/virtual-machines"
$action = "add_tags"
Foreach ($vm in $vms)
{
    $vmid = $vm.Config.InstanceUuid
    $JSON = "
    {
        `"external_id`":`"$vmid`",
        `"tags`": [
            {
                `"scope`":`"$scope`",
                `"tag`":`"$Tag`"
            }
            ]
    }
    "

    $Data = Invoke-restmethod -Uri ($base_url + $EndPoint + "?action=" + $action) -Method POST -Body $JSON -ContentType 'application/json' -Credential $Credential -SkipCertificateCheck:$skipcertcheck -Authentication:$AuthMethod
}

 

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
pamiller21
Enthusiast
Enthusiast

I ran that code and it didn't give me any errors, but also didn't do the tag.  Any idea what I can check into now?

0 Kudos
Zsoldier
Expert
Expert

Did you change the get-vm filter?

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
pamiller21
Enthusiast
Enthusiast

Ya I updated it to a variable and set the variable earlier, here is exactly what I tried:

#############################
# Connect to vCenter #
#############################
Import-Module -Name VMware.PowerCLI
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$vc = 'vcsa.ruralnex.com'
$Cred = Import-Clixml /home/scripts/creds/creds.xml

Connect-VIServer $VC -Credential $Cred

#############################
# Connect to NSX-T #
#############################
Import-Module -Name VMware.PowerCLI
Import-Module PowerNSX
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$NSXCred = Import-Clixml /home/scripts/creds/nsxt.xml
$skipcertcheck = $true
$AuthMethod = “Basic”
$NSXMgr = ”URL”
$policyapi = "/policy/api/v1"
#$base_url = ( "https://" + $NSXMgr + $policyapi )
$base_url = ("https://" + $NSXMgr + $apiendpoint)
$posturl = "https://$NSXMgr/api/v1/fabric/virtual-machines?action=update_tags"

$NSXTag = 'Alerta'
$vmName = 'alerta03_replica'
$vm = Get-VM -Name $vmName

##Requires -Module vmware.powercli
#$Credential = Get-Credential
#$skipcertcheck = $true
#$AuthMethod = “Basic”
#$NSXMgr=”0.0.0.0”
#$apiendpoint = "/api/v1/fabric"

#$tag = "Naka"
$scope = "Servers"

$vms = Get-VM -Name $vmName | Get-View -Property "Config"
# Add Tags to existing tags (Valid for NSX-T 3.1.2, previous versions only have update_tag)
$endpoint = "/virtual-machines"
$action = "add_tags"
Foreach ($vm in $vms)
{
$vmid = $vm.Config.InstanceUuid
$JSON = "
{
`"external_id`":`"$vmid`",
`"tags`": [
{
# `"scope`":`"$scope`",
`"tag`":`"$NSXTag`"
}
]
}
"

$Data = Invoke-restmethod -Uri ($base_url + $EndPoint + "?action=" + $action) -Method POST -Body $JSON -ContentType 'application/json' -Credential $NSXCred -SkipCertificateCheck:$skipcertcheck -Authentication:$AuthMethod
}

0 Kudos
Zsoldier
Expert
Expert

Have you tried running the code I posted above verbatim?  There are lots of problems w/ the way that you've modified your script.  $apiendpoint is not defined correctly since you've commented it out and is not before you capture your base_url.  Commenting out scope doesn't work the way you've done here.  I've cleaned up my script example further so you can omit scope if you don't need it and change the get-vm call to base on a vmnamefilter variable.  

Also, you do not need to import the PowerNSX module unless you are making additional calls to an NSX-V instance in the same script.

#Requires -Module vmware.powercli
$Credential = Get-Credential
$skipcertcheck = $true
$AuthMethod = “Basic”
$NSXMgr=”0.0.0.0”
$apiendpoint = "/api/v1/fabric"
$base_url = ("https://" + $NSXMgr + $apiendpoint)
$tag = "Naka"
$scope = "NakaScope"  # If scope not required, simply define as $null or ""
$vmnamefilter = "nakabuntu" # Not required.  Will loop through all VM's otherwise.

$vms = Get-VM $vmnamefilter | Get-View -Property "Config"
# Add Tags to existing tags (Valid for NSX-T 3.1.2, previous versions only have update_tag)
$endpoint = "/virtual-machines"
$action = "add_tags"
Foreach ($vm in $vms)
{
    $vmid = $vm.Config.InstanceUuid
    If ([string]::IsNullOrWhiteSpace($Scope)){
    $JSON = "
    {
        `"external_id`":`"$vmid`",
        `"tags`": [
            {
                `"tag`":`"$Tag`"
            }
            ]
    }
    "
    }
    Else{
        $JSON = "
        {
            `"external_id`":`"$vmid`",
            `"tags`": [
                {
                    `"scope`":`"$scope`",
                    `"tag`":`"$Tag`"
                }
                ]
        }
        "
    }
    $Data = Invoke-restmethod -Uri ($base_url + $EndPoint + "?action=" + $action) -Method POST -Body $JSON -ContentType 'application/json' -Credential $Credential -SkipCertificateCheck:$skipcertcheck -Authentication:$AuthMethod
}

 

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
pamiller21
Enthusiast
Enthusiast

Thank you very much for this, sorry I goofed up the script the first time.

cvv2
Contributor
Contributor

Thank you, with a few tweaks my rollout script worked the way I want again.

0 Kudos
vespavbb
Enthusiast
Enthusiast

Hi,

I´m just trying to use this script, but I´m not able to connect to nsx via invoke-restmethod. I use the complete script...

 $Data = Invoke-restmethod -Uri ($base_url + $EndPoint + "?action=" + $action) -Method POST -Body $JSON -ContentType 'application/json' -Credential $Credential -SkipCertificateCheck:$skipcertcheck -Authentication:$AuthMethod

 

Invoke-RestMethod : A parameter cannot be found that matches parameter name 'SkipCertificateCheck'.
At line:1 char:164
+ ... lication/json' -Credential $Credential -SkipCertificateCheck:$skipcer ...
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

VCP4,VCP5,VCP6
0 Kudos
Zsoldier
Expert
Expert

SkipCertificateCheck is only available via Powershell Core I believe.  

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
LucD
Leadership
Leadership

That is correct


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos