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

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

Fix VMware tools not running on Windows servers

I had some trouble with VMwaretools stopping on some machines and decided to automate restart och vmware tools. I wrote this script which takes a view parameter to view current status. If you start the script whitout the view parameter it will try to restart vmware tools.


[parameter(Mandatory = $false)]

#Connect to Vcenter
$cred = Get-Credential
Connect-VIServer vcenter -Credential $cred | Out-Null

Write-Host -ForegroundColor Green "Collecting VMs"
$toolsvm=get-vm | where { $_.GuestId -like "*Windows*" -and $_.Extensiondata.Summary.Guest.ToolsStatus -like "toolsnotrunning" -and $_.Powerstate -eq "PoweredOn"}

#Stop script if no VMs reports tools not running
if ($toolsvm -eq $null)
Write-Host "Nothing to fix"
Disconnect-VIServer vcenter -Confirm:$false

if ($view)
Write-Host "VMs whitout tools running"
foreach ($vm in $toolsvm)
Write-Host $vm

foreach ($vm in $toolsvm)

if ($vm -match "^(?<Name>\S*)\s.*$") { $vm_name = $Matches.Name }
else { $vm_name = $vm }

$vm_hostname = $ +".domain.local"

if (Test-Connection -Computername $vm_hostname -BufferSize 16 -Count 1 -Quiet)
Invoke-Command -Computername $vm_hostname -ScriptBlock { stop-Service -name vmvss; start-service vmvss } -Credential $cred
Write-Host "Service restarted on $vm_name"
Write-Host -ForegroundColor Red "Unable to contact $vm_name"

#Disconnect from Vcenter.
Disconnect-VIServer vcenter -Confirm:$false

Create a new host via OP5 API with powershell

If you need to create a new host with OP5 api you can use something like this.
Template, hostgroups and contactgroups are not mandatory and can be removed from hash table.


function new-op5host
	[parameter(Mandatory = $true)]
	[parameter(Mandatory = $true)]
	$username = 'api_user$Default'
	$password = "password"
	$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $password)))
	$hash = @{
		file_id = "etc/hosts.cfg";
		host_name = "$hostname";
		address = "$";
		alias = "$alias";
		max_check_attempts = "3";
		notification_interval = "5";
		notification_options = "d", "r";
		notification_period = "24x7";
		template = "Win_hosts";
		hostgroups = "Windows servers";
		contact_groups = "Windowsservrar"
	$jsonData = $hash | convertto-json
	$result = Invoke-RestMethod -Method POST -ContentType "application/json" -Uri "" -Body $jsonData -Headers @{ Authorization = ("Basic {0}" -f $base64AuthInfo) }
	$result = Invoke-RestMethod -Method POST -ContentType "application/json" -Uri "" -Headers @{ Authorization = ("Basic {0}" -f $base64AuthInfo) }

Change wallpaper on windows 7

I needed a script to change desktop wallpaper for all users using the default one with an outdated company logo on. I came up with this startup script as a solution. Set $filesize to the size of the old wallpaper to only change wallpapers with same filesize. Use as logon script.

$filesize = 100593
$bg = Get-Item ("$env:USERPROFILE\appdata\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg)
if ($bg.length -eq $filesize)
Copy-item "\\fileserver\UsrLogon\wallpaper\img0.jpg" "$env:USERPROFILE\appdata\Roaming\Microsoft\Windows\Themes\img0.jpg" -Force
Set-ItemProperty -path 'HKCU:\Control Panel\Desktop\' -name wallpaper -value "$env:USERPROFILE\appdata\Roaming\Microsoft\Windows\Themes\img0.jpg"
rundll32.exe user32.dll, UpdatePerUserSystemParameters