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
{
	param
	(
		[parameter(Mandatory = $true)]
		[pscustomobject]$VMs
	)

	$results = foreach ($row in $var)
	{
		$cpu, $mem = $row.Name -split ',', 2
		[pscustomobject]@{
			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.

"NumOfVMs","NumOfCPUs","MemoryGB"
"1","2","8"
"12","1","4"
"4","4","8"
"2","4","4"
"9","1","8"
"5","4","12"
"22","4","32"
"6","4","16"
"2","1","12"
"1","4","24"
"1","1","16"
"1","4","6"
"1","1","6"
"1","24","32"
"1","4","25"
"3","2","16"
"1","8","6"
"1","1","3"

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:
name;description;startrange;endrange;subnetmask;scopeid;router

$dhcpserver = "1.1.1.1"
$scopes = Import-Csv -Path dhcp.csv -Delimiter ";"
foreach ($scope in $scopes)
{
	$name = $scope.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=192.168.6.4′ 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 192.168.6.0/24 \
--gateway 192.168.6.1 \
--ip-range 192.168.6.192/27 \
--aux-address='host=192.168.6.4' 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 192.168.1.192/27 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
{
	[CmdletBinding()]
	param
(
		[parameter(
			 ValueFromPipeline = $true,
			 position = 0,
			 Mandatory = $true)]
	[string]$computername
)

	process
	{
		$Request = @{
			'domain'	  = 'domain1.company.net'
			'name'    = $computername
		}
		$lab = Invoke-WebRequest -Uri https://reporting.company.net/searchcomputer.php -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
		}
		else
		{
			$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)]
	$file
)
$vms = Import-Csv $file

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

Create AD users from a CSV-file

Here is an example of a script to create AD users from a CSV-file and assign a temoporary password.

param
(
	[parameter(Mandatory = $true)]
	$infile,
	$output
)

$OU = "OU=Users,DC=PSLABB,Dc=local"

$users = Import-Csv -Path $infile


foreach ($user in $users)
{
	$rand = Get-Random -Minimum 1000 -Maximum 9999
	$pwd = "Temp$rand"
	$name = "$($user.givenname)" + " " + $($user.surname)
	
	New-ADUser -Name $name -GivenName $user.Givenname -Surname $user.Surname -SamAccountName $user.username -user $user.username -Description "Tempuser" -path $ou -enabled $true -AccountPassword (convertTo-securestring -AsPlainText "Temp$rand" -Force)
	
	$details = @{
		'Name'= $name;
		'username'  = $($user.username);
		'Password'     = $pwd
	}
	$results = New-Object PSObject -Property $details
	$results | Export-Csv -Path $output -NoTypeInformation -Append
	
}