Script to add Tag to multiple VMs

What happens if you need to add a tag to multiple Virtual Machine in vCenter server. Well one way to do is go to vCenter and add it manually by going to individual Virtual Machine. Or fun way to do it, create a Powershell script. In my case, it was couple hundred Virtual Machines, so I went with 2nd option. Follow on to read more.

Steps to run script

  • $VIServer – Enter IP Address/FQDN of vCenter Server
  • $Admin – User Account with access to vCenter Server
  • $PathToCredentials/$PathToReport – Folder location of script file
  • $tagname – Name of Tag

Save below file as ps1 extension and you should be good.

It checks if VM exists in vCenter server, it will be good list and then tag will be added. If VM doesn’t exists then it will be dropped from list.

$VIServer = ""
$Admin = ''
$PathToCredentials = ""
$PathToReport = ""
$tagtoaddvm = "<enter folder location>\VMList.txt"
$tagname = ""
$GoodVMList = "<enter folder location>\GoodVMList.txt"
Set-Content -Path $GoodVMList -Value $null
Function Get-Credentials {
    Param (
	    [String]$AuthUser = $env:USERNAME,
        [string]$PathToCred
    )
    $CredFile = $AuthUser.Replace("\","~")
    If (-not $PathToCred)
    {
        $PathToCred = Split-Path $MyInvocation.MyCommand.Path
    }
    $File = Join-Path -Path $PathToCred -ChildPath "\Credentials-$CredFile.crd"
	#And find out if it's there, if not create it
    If (-not (Test-Path $File))
	{	(Get-Credential $AuthUser).Password | ConvertFrom-SecureString -Key $Key | Set-Content $File
    }
	#Load the credential file 
    $Password = Get-Content $File | ConvertTo-SecureString -Key $Key
    $AuthUser = (Split-Path $File -Leaf).Substring(12).Replace("~","\")
    $AuthUser = $AuthUser.Substring(0,$AuthUser.Length - 4)
	$Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password)
    Return $Credential
}
function add-tag {
    $GoodVMs = Get-Content $GoodVMList
    foreach ($GoodVM in $GoodVMs) {
        $checkgoodVM = Get-VM -Name $GoodVM
        Try {
            $tagassign = New-TagAssignment -Tag $tag -Entity $checkgoodVM -ErrorAction SilentlyContinue 3>$null
        }
        Catch {
            Throw "Error adding tag $tagname to VM $VM because ""$($Error[1])"""
        }
    }
}
If (-not $PathToCredentials)
{
    $PathToCredentials = Split-Path $MyInvocation.MyCommand.Path
}
If (-not $PathToReport)
{
    $PathToReport = Split-Path $MyInvocation.MyCommand.Path
}
$Cred = Get-Credentials $Admin $PathToCredentials
Try {
    $Conn = Connect-VIServer $VIServer -Credential $Cred -ErrorAction SilentlyContinue 3>$null
		write-host $VIServer
}
Catch {
    Throw "Error connecting to $VIServer because ""$($Error[1])"""
}
$VMList = Get-Content $tagtoaddvm
foreach($VM in $VMList) {
    Try {
        $checkVM = Get-VM -Name $VM -ErrorAction SilentlyContinue 3>$null
        if ($checkVM.Name -ne $null) {
            Write-Host $checkVM
            Add-Content -Path $GoodVMList -Value "$checkVM"
        }
    }
    Catch {
        Throw "VM $VM not found in vCenter $VIServer"    
    }
}
$tag = Get-Tag -Name $tagname
$GoodVMs = Get-Content $GoodVMList
if (!($GoodVMs -eq "")) {
    add-tag
    #Write-Host "adding tag for $GoodVMs"
}
else {
    Write-Host "No VMs found for Tag Addition in vCenter"
}
Try {
	$Conn = Disconnect-VIServer -Server $VIServer -confirm:$false -ErrorAction SilentlyContinue 3>$null
}
Catch {
    Throw "Error connecting to $VIServer because ""$($Error[1])"""
}

Leave a Reply