Кто создал виртуальную машину в ESXI
Добрый день! Уважаемые читатели и гости IT блога Pyatilistnik. В прошлый раз я вам рассказал как можно самому создать виртуальную машину на базе VMware Workstation, чтобы у вас всегда под рукой был тестовый стенд. Продолжим тему виртуализации и сегодня на повестке дня будет разобрана ситуация, что вы хотите навести порядок в своей инфраструктуре, вам необходимо понимать кто создает виртуальные машины, чтобы эта информация у вас раз в неделю приходила на почту в виде таблицы. Можно сказать это такой аудит и своевременное уведомление, о том что меняется в вашем серверном парке. Думаю, что мой опыт окажется для кого-то очень полезным и плодотворным.
Для чего мониторить новые, созданные виртуальные сервера
Ранее я вам приводил пример рабочего скрипта, задачей которого было выявлять появившиеся за последнюю неделю объекты компьютеров AD с отправкой вам на почту, это удобно, но бывают ситуации, что вы зайдя на свой гипервизор или vCenter сервер обнаруживаете, что на нем есть виртуальная машина в которой нет "Custom Attribute", чтобы идентифицировать чья она, за кем числится и для чего вообще, может быть уже VM неактуальная и зазря кушает ресурсы. Вы конечно можете спросить своих коллег, но они могут забыть что это делали, давайте я покажу как искать концы в таком случае.
Ниже я вам покажу, как вам настроить вот такое оповещение себе на почту:
Как узнать, кто создал виртуальную машину через vCenter
Нам помогу в нашей задаче два командлета:
Командлет Get-VM является одним из основных командлетов в PowerCLI для работы с виртуальными машинами в среде VMware vSphere. Он позволяет получить информацию о виртуальных машинах, а также выполнять различные операции с ними.
Командлет Get-VIEvent - Назначение командлета Get-VIEvent состоит в получении информации о событиях, произошедших в вашей виртуальной среде VMware. У данного командлета есть нужные нам ключи:
- VmCreatedEvent: Этот ключ используется для фильтрации событий создания виртуальных машин. Когда новая виртуальная машина создается в среде VMware, возникает событие VmCreatedEvent, которое можно получить с помощью командлета Get-VIEvent.
- VmClonedEvent: Этот ключ используется для фильтрации событий клонирования виртуальных машин. Когда виртуальная машина клонируется в среде VMware, возникает событие VmClonedEvent.
- VmDeployedEvent: Этот ключ используется для фильтрации событий развертывания виртуальных машин. Когда виртуальная машина развертывается из шаблона или файла OVF в среде VMware, возникает событие VmDeployedEvent.
- VmRegisteredEvent: Этот ключ используется для фильтрации событий регистрации виртуальных машин. Когда виртуальная машина регистрируется на хосте в среде VMware, возникает событие VmRegisteredEvent.
Теперь когда мы знаем нужные нам командлеты можно приступать к делу. Первое, что вы должны сделать, это открыть PowerCLI и подключиться к вашему vCenter серверу.
# Создаем переменную $VM в которой запросим информацию по виртуальной машине SQL16
$VM = get-vm SQL16
# Создадим переменную $Event в которой получим нужную нам информацию
$Event = $VM | Get-VIEvent -Types Info | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent" -or $_.Gettype().Name -eq "VmClonedEvent"}
# Выводим нужные нам поля, кто создал и когда создал
$Event | Select-Object CreatedTime, UserName
Теперь для автоматизации и получения исходной таблицы на почту, как в скриншоте выше, я поделюсь с вами вот таким скриптом.
$viserver = @("vcenter.root.pyatilistnik.org") #указанием имя сервера vCenter.
$creds_file = "$PSScriptRoot\vicreds_vuser.xml" #указанием пути к файлу с учетными данными.
$creds = Get-ViCredentialStoreItem -File $creds_file -ErrorAction Stop #Получение учетных данных из файла.
$user = $password = $null
$user = ($creds | ? {$_.Host -eq $viserver}).User
$password = ($creds | ? {$_.Host -eq $viserver}).Password
try {
Connect-VIServer -Server $viserver -User $user -Password $password -Verbose -Force -ErrorAction Stop #Подключение к серверу vCenter с использованием полученных учетных данных.
}
catch {
"$(Date) $($_.exception.message)"
Break
}$VMs = get-vm #Получение списка всех виртуальных машин.
$eventTYpes = 'VmCreatedEvent', 'VmClonedEvent', 'VmDeployedEvent', 'VmRegisteredEvent' #Определение типов событий для фильтрации.
$NewVmList = $vms | Where-Object { $_.extensiondata.config.createDate -ge (Get-Date).AddDays(-7) } | Select-Object Name, @{n = "createdate"; e = { $_.extensiondata.config.createDate}} #Фильтрация виртуальных машин, созданных за последнюю неделю, и выбор имени и даты создания.$NewVM = @() #Создание пустого массива для новых виртуальных машин.
foreach ($vm in $NewVmList) #Цикл по новым виртуальным машинам для выполнения дальнейших действий.
{
$vm = Get-VM -Name $vm.name #Создание пустого массива для новых виртуальных машин.
$emptyCustomFields = ($vm.CustomFields | ? value -eq "").key #Определение пустых пользовательских полей виртуальной машины.
$vm | ForEach-Object -Process {
Get-VIEvent -Entity $_ -MaxSamples ([int]::MaxValue) | where { $eventTYpes -contains $_.GetType().Name } | Sort-Object -Property CreatedTime -Descending | Select -First 1 |
ForEach-Object -Process {
$NewVM += New-Object PSObject -Property ([ordered]@{
VMName = $_.VM.Name
CreatedTime = $_.CreatedTime
User = $_.UserName
EventType = $_.GetType().Name
EmptyCustomFields = $emptyCustomFields -join ", "
})
$Creator = $_.UserName
}
}if ($vm.CustomFields['Creator'] -eq '')
{
$vm | Set-Annotation -CustomAttribute "Creator" -Value $Creator
}
}# Данные для подключения к почтовому серверу
if ($NewVM.Length -gt 0)
{
$from = "tech_notify@mail.pyatilistnik.org"
$to ="admins@pyatilistnik.org" # "sem@pyatilistnik.org" #
$Subject = "Новые VM, созданные за последнюю неделю"
$smtpserver = "mail.pyatilistnik.org"
$secure = $true
$port = 587 # TLS, for SSL use 465
$username = "tech_notify"
$password = 'P@ssw0rd'# Создание и отправка электронного письма с информацией о новых виртуальных машинах.
$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@
$body = $null
$body += "<p>Проверьте новые VM. Заполните пропущенные customFields"$body += $NewVM | sort CreatedTime | select "VMName", "CreatedTime" ,"User", "EventType", "EmptyCustomFields" | ConvertTo-Html -Head $Header
$body += "<p>Generated on $($env:COMPUTERNAME + "." + $((Get-WmiObject Win32_ComputerSystem).Domain))"###
$message = New-Object System.Net.Mail.MailMessage
$message.From = $from
$message.To.Add($to)
$message.Subject = $Subject
$message.Body = $body
$message.IsBodyHtml = $true$smtp = New-Object Net.Mail.SmtpClient($smtpserver, $port)
$smtp.EnableSsl = $secure
$smtp.Credentials = New-Object System.Net.NetworkCredential($username, $password)"$(Date) Trying to send e-mail notification" | Tee-Object $log -Append
try {
$smtp.Send($message)
}
catch {
"$(Date) $($_.exception.message)"
}
}
Еще не забудьте файл XML с учетными данными для подключения положить в папку со скриптом.
<?xml version="1.0" encoding="UTF-8"?>
<viCredentials>
<version>2.0</version>
<passwordEntry>
<host>vcenter.root.pyatilistnik.org</host>
<username>root\sem</username>
<password>зашифрованный пароль==</password>
</passwordEntry>
</viCredentials>
Осталось только это сохранить в виде скрипта PowerShell в формате ps1 и создать для него задание в планировщике. На этом у меня все, с вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.