-
Notifications
You must be signed in to change notification settings - Fork 17
/
hyperv-vm-monitor.ps1
160 lines (133 loc) · 4.84 KB
/
hyperv-vm-monitor.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<#
.SYNOPSIS
powershell script to monitor hyper-v vm state changes
.DESCRIPTION
this script will monitor hyper-v vm state changes.
press ctrl-c to exit.
requirements:
at least windows 8 / 2012
admin powershell prompt
admin access to os
remote requirements:
powershell access
https://raw.githubusercontent.com/jagilber/powershellScripts/master/hyperv-vm-monitor.ps1
.NOTES
File Name : hyperv-vm-monitor.ps1
Author : jagilber
Version : 170609 original
History :
.EXAMPLE
.\hyperv-vm-monitor.ps1 -hypervisors machine1,machine2
monitor two hypervisor machines machine1 and machine2
.EXAMPLE
.\hyperv-vm-monitor.ps1 -hypervisors machine1,machine2 -command "powershell.exe .\somescript.ps1"
monitor two hypervisor machines machine1 and machine2.
launches command powershell .\somescript.ps1 <vmname> in new window on modified vm event
.PARAMETER hypervisors
comma separated list of hypervisor machine names
.PARAMETER command
command to run on a modified vm event
#>
param(
[string]$command,
[string[]]$hypervisors,
[switch]$continue
)
$ErrorActionPreference = "Continue"
$currentVmStates = new-object Collections.ArrayList
$newVmStates = new-object Collections.ArrayList
if (!$hypervisors)
{
if ((Get-WindowsFeature -Name Hyper-v).InstallState -eq "Installed")
{
$hypervisors = @($env:COMPUTERNAME)
}
else
{
write-host "specify -hypervisors to monitor. exiting"
exit
}
}
foreach ($hvm in $hypervisors)
{
write-host "checking machine $($hvm)"
[void]$currentVmStates.AddRange((get-vm -ComputerName $hvm | select-object Name, State, Uptime, Status, ComputerName))
#[void]$currentVmStates.AddRange((get-vm -ComputerName $hvm | select-object Name,State,Uptime,Status,ComputerName,HardDrives))
}
$currentVmStates | Format-Table
$count = 0
while ($true)
{
if (!$currentVmStates)
{
if (!$continue)
{
Write-Warning "unable to query current vm states. exiting"
exit
}
Write-Warning "unable to query current vm states."
}
foreach ($hvm in $hypervisors)
{
write-verbose "checking machine $($hvm)"
[void]$newVmStates.AddRange((get-vm -ComputerName $hvm | select-object Name, State, Uptime, Status, ComputerName))
#[void]$newVmStates.AddRange((get-vm -ComputerName $hvm | select-object Name,State,Uptime,Status,ComputerName,HardDrives))
}
foreach ($currentVmState in $currentVmStates)
{
if (!$newVmStates.Name.Contains($currentVmState.Name))
{
write-host
write-host "$((get-date).ToString("o")) removed vm $($currentVmState.Name)" -ForegroundColor Red
$currentVmState | Format-Table *
}
}
foreach ($newVmState in $newVmStates)
{
if (!$currentVmStates.Name.Contains($newVmState.Name))
{
write-host
write-host "$((get-date).ToString("o")) new vm $($newVmState.Name)" -ForegroundColor Green
$newVmState | Format-Table *
}
else
{
$currentVm = $currentVmStates | where-object Name -eq $newVmState.Name
if (($currentVm.state -ne $newVmState.state) `
-or ($currentVm.Uptime -gt $newVmState.Uptime) `
-or ($currentVm.ComputerName -ne $newVmState.ComputerName) `
-or ($currentVm.Status -ne $newVmState.Status)) #`
#-or ($currentVm.HardDrives.Count -ne $newVmState.HardDrives.Count))
{
write-host
write-host "$((get-date).ToString("o")) modified vm $($newVmState.Name)" -ForegroundColor Yellow
write-host "vvvv old state vvvv" -ForegroundColor Gray
$currentVm | ft *
#$currentVm.HardDrives.Path | ft *
write-host "vvvv new state vvvv" -ForegroundColor Green
$newVmState | ft *
#$newVmState.HardDrives.Path | ft *
if ($command -and ($newVmState.State -eq "Running") -and ($newVmState.Status -eq "Operating normally"))
{
write-host "running command: cmd.exe /c start $($command) $($newVmState.Name)"
#Invoke-expression -Command "cmd.exe /c start $($command) $($newVmState.Name)"
Start-Process -FilePath "cmd.exe" -ArgumentList "/c start $($command) $($newVmState.Name) $($newVmState.ComputerName)"
}
}
}
}
$currentVmStates.Clear()
$currentVmStates.AddRange($newVmStates)
$newVmStates.Clear()
if ($count -eq 80)
{
$count = 0
write-host "."
}
else
{
write-host "." -NoNewline
$count++
}
Start-Sleep -Seconds 1
}