Ansible dynamic inventory with Vcenter

In order to create your Ansible groups based on vmware tags you need to create a inventory file and name it to something.vmware.yaml.

Also make sure to enable vmware inventory plugin in ansible.cfg

enable_plugins = vmware_vm_inventory


plugin: vmware_vm_inventory
strict: False
username: administrator@vsphere.local
password: secretpassword
validate_certs: false
with_tags: true
    - 'name'
    - 'config.uuid'
    - ''
    - 'guest.toolsStatus'
    - 'guest.toolsRunningStatus'
    - 'guest.ipAddress'
    - 'configIssue'
    - 'config.bootOptions'
    - 'config.annotation'
    - 'config.alternateGuestName'
      ansible_host: 'guest.ipAddress'
        - key: 'tags'
          separator: ''

Test new inventory with ansible-inventory –graph -i vcenter.vmware.yaml Groups named Linux, ansible_managed,win are created from Vmware tags.

[root@d4e7b19ae23b playbooks]# ansible-inventory --graph -i vcenter.vmware.yaml
| |--Ansible01_564d4590-0ab7-8192-33c4-8690b6394208
| |--Ansible01_564d4590-0ab7-8192-33c4-8690b6394208
| |--SQL2016_421e22dd-ecbd-83f2-6010-b679a3840a70
| |--2019Template_42237f2e-f317-3fbd-2688-023de31ffcdf
| |--AD_564d896d-f1cb-3837-4c15-6355e1b78b1d
| |--Docker01_4223eb67-2e2b-519c-0f90-959234307b44
| |--Esxi1_4223f791-c6b1-294b-b8be-00441105f73b
| |--Ubuntu_template_4223cce6-d618-6994-1550-db4d872cdf98
| |--Vcenter7_564d3c9f-07a3-90fa-60df-bfb39b3f697b
| |--Win10_01_564da1fa-1da0-7b6b-d386-8b173a48fbc6
| |--centos_template_42232f6e-96bb-f385-7ea4-aedaec2dedea
| |--esxi-01_422366be-06b3-eb4e-b837-cb472cce4208
| |--esxi-02_4223d129-24c4-98fe-205f-af445f578a03
| |--esxi-03_4223e353-2be9-a388-5203-60f887bfb14a
| |--SQL2016_421e22dd-ecbd-83f2-6010-b679a3840a70

Add users or groups to local admin group

Sometimes you need to add users or groups in local Administrators group on a windows server. This function helps to accomplish that on one or more servers. Load a text- or csv-file and pipe it to Add-AdminGroup. All servers not responding will be shown at the end for later follow-up.

function Add-AdminGroup
	Param (
		[parameter(Mandatory = $true,
				   ValueFromPipeline = $true,
				   position = 0)]
		[Alias('IPAddress', '__Server', 'CN', 'server')]
		[Alias('groupname', 'adgroup')]
		if (Test-Connection -quiet -Computername $computername)
			Write-Output "Adding $group to local administrators on" $Computername
			Invoke-Command -ComputerName $Computername -ScriptBlock {
			Add-LocalGroupMember -Group Administrators -Member $args[0]
			} -ArgumentList $group
			write-output "No response from" $Computername
			$failed += $computername
			foreach ($obj in $failed)
				Write-Output $obj

List VMs according to memory and CPU usage

For internal billing purpose I needed a way list all Windows VMs for a given subsidiary and their CPU and memory configuration.

Connect-VIServer -Server vcenter.corp.lan

$var = get-vm -location Subsidiary1 | Where{ $_.Guest.OSFullName -like '*windows*' }  | select numcpu, memorygb | Group-Object numcpu,memorygb

function get-numOfVms
		[parameter(Mandatory = $true)]

	$results = foreach ($row in $var)
		$cpu, $mem = $row.Name -split ',', 2
			NumOfVMs = $row.Count
			NumOfCPUs   = $cpu
			MemoryGB = $mem.Trim()
	return $results
$total = get-numOfVms -VMs $var
$total | Export-Csv -Path totalvms.csv -NoTypeInformation


Example of totalvms.csv. It gives you a number of each specific CPU and memory configuration.


Create DHCP scopes from a CSV file

A fast way to import multiple DHCP scopes to a DHCP server. Some settings needs to be added on top level. For example DNS servers.

Required header in CSV:

$dhcpserver = ""
$scopes = Import-Csv -Path dhcp.csv -Delimiter ";"
foreach ($scope in $scopes)
	$name = $
	$description = $scope.description
Write-Output "Creating scope  $name"
Add-DhcpServerv4Scope -ComputerName $dhcpserver -Name "$name" -Description "$description" -StartRange $scope.startrange -EndRange $scope.endrange -SubnetMask $scope.subnetmask -State Active -LeaseDuration 1.00:00:00
Set-DhcpServerv4OptionValue -Router $scope.router -ScopeId $scope.scopeid -ComputerName $dhcpserver

Docker and macvlan

If you want to use docker containers in your regular LAN subnet you need to setup a new Docker network with macvlan driver.

First create your Docker network. — ip-range specifies all addresses that Docker will manage. Chose a part of your subnet outside your DHCP-scoop if you have one to avoid ip conflicts.
–aux-address=’host=′ docker_net is tied to your host interface to allow your containers to comunicate with your host.

[root@docker01 ~]# docker network create -d macvlan -o parent=ens224 \
--subnet \
--gateway \
--ip-range \
--aux-address='host=' docker_net

As you can see when running docker network ls we have a new network called docker_net with macvlan driver.

Docker network

Next step is to create a macvlan interface, in this example called docker_int.
[root@docker01 ~]# ip addr add docker_int link ens224 type macvlan mode bridge

Configure the interface with your selected host address and bring it up. Last step is to add a IP route to tell your host how to connect to to al Docker containers.

[root@docker01 ~]# ip link add docker_int link ens224 type macvlan mode bridge
[root@docker01 ~]# ip link set docker-shim up
[root@docker01 ~]# ip route add dev docker_int

Run a container and connect it to docker_net
[root@docker01 ~]# docker run nginx -network docker_net

If you want to check container ip run:

[root@docker01 ~]# docker inspect CONTAINER_ID

Invoke webrequest example

This example uses invoke-webrequest to retrieve computer information from a company reporting webpage. Only text inside TD elements are stored in a array for future use and added to a PSObject.

function Get-ComputerInfo
			 ValueFromPipeline = $true,
			 position = 0,
			 Mandatory = $true)]

		$Request = @{
			'domain'	  = ''
			'name'    = $computername
		$lab = Invoke-WebRequest -Uri -Body $Request -Method Post

		$output = $lab.ParsedHtml.body.getElementsBytagname('TD') | select -expand innerhtml

		if ($output[7] -match '\D\d\d\d\d\d\d\d')
			$user = Get-ADUser -Identity $output[7] | select -ExpandProperty name
			$user = "Unknown"
			$output[7]= "Unknown"

		$result = New-Object PSObject -Property @{
			Computername	    = $output[0];
			OU				    = $output[2];
			IP				    = $output[6];
			OS				    = $output[3];
			LastUser		    = $output[7];
			LastUSerFullName    = $user;
			LastSeen		    = $output[5];
			Master			    = $output[4];
		Write-Output $result | select computername, ou, ip, os, master, lastuser, lastuserfullname, lastseen
	}#End Process

Migrate VMs between clusters with powecli

A short script to migrate VMs to a new cluster or host. Migrates one vm at a time to save network bandwith. After migration it upgrades Vmware tools to match current host version.

Takes a CSV file as input with VMs to migrate.

Param (
	[Parameter (Mandatory = $True)]
$vms = Import-Csv $file

foreach ($vm in $vms)
	Write-Host "Migrating VM" $
	Move-VM -VM $ -Destination Cluster01
	Write-Host "Updating Vm-tools on " $
	Update-Tools -VM $ -NoReboot