Tatitra isan'andro momba ny fahasalaman'ny milina virtoaly mampiasa R sy PowerShell

Tatitra isan'andro momba ny fahasalaman'ny milina virtoaly mampiasa R sy PowerShell

teny

Salama. Nandritra ny antsasa-taona izao dia nanao script izahay (na andian-tsoratra) izay mamoaka tatitra momba ny satan'ny milina virtoaly (fa tsy izany ihany). Nanapa-kevitra ny hizara ny traikefako momba ny famoronana sy ny code mihitsy aho. Manantena ny fanakianana aho ary mety hahasoa olona iray ity fitaovana ity.

Famoronana filana

Manana milina virtoaly be dia be izahay (eo amin'ny 1500 eo ho eo no zaraina amin'ny vCenters 3). Noforonina ny vaovao ary voafafa matetika ny taloha. Mba hitazomana ny filaminana, dia nisy saha maromaro nampidirina tao amin'ny vCenter mba hizarana ny VM ho Subsystems, hanondro raha fitsapana izy ireo, ary avy amin'iza ary oviana no namoronana azy. Ny anton'ny maha-olombelona dia nahatonga ny zava-misy fa mihoatra ny antsasaky ny milina no tavela amin'ny saha tsy misy dikany, izay nanasarotra ny asa. Indray mandeha isaky ny enim-bolana dia nisy olona nikoropaka ary nanomboka niasa tamin'ny fanavaozana ity angon-drakitra ity, saingy nitsahatra ny vokatra taorian'ny herinandro sy tapany.
Hazavaiko avy hatrany fa azon'ny rehetra atao fa tsy maintsy misy ny fangatahana amin'ny famoronana milina, dingana amin'ny famoronana azy, sns. sy ny sisa. Ary miaraka amin'izay koa, manaraka an-tsakany sy an-davany an'io dingana io ny rehetra ary milamina ny zava-drehetra. Mampalahelo fa tsy izany no zava-misy eto, fa tsy ity no lohahevitry ny lahatsoratra :)

Amin'ny ankapobeny, nanapa-kevitra ny hanao automatique ny fanamarinana ny fahamarinan'ny famenoana ny saha.
Nanapa-kevitra izahay fa ny taratasy isan'andro miaraka amin'ny lisitry ny milina diso feno ho an'ny injeniera tompon'andraikitra rehetra sy ny lehibeny dia ho fanombohana tsara.

Amin'izao fotoana izao, ny iray amin'ireo mpiara-miasa amiko dia efa nametraka script ao amin'ny PowerShell, izay isan'andro, araka ny fandaharam-potoana, dia nanangona vaovao momba ny milina rehetra an'ny vCenters rehetra ary niteraka antontan-taratasy csv 3 (samy ho an'ny vCenter azy manokana), izay nampidirina tao disk mahazatra. Tapa-kevitra ny handray ity script ity ho fototra ary hanampy azy amin'ny fanamarinana amin'ny fampiasana ny fiteny R, izay nanananay traikefa.

Ao amin'ny dingan'ny famaranana, ny vahaolana dia nahazo vaovao tamin'ny alàlan'ny mailaka, angon-drakitra misy latabatra lehibe sy ara-tantara (mihoatra izany aoriana), ary koa ny famakafakana ny vSphere log mba hahitana ny tena mpamorona ny vm sy ny fotoana namoronana azy.

IDE RStudio Desktop sy PowerShell ISE dia nampiasaina ho an'ny fampandrosoana.

Ny script dia natomboka tamin'ny milina virtoaly Windows mahazatra.

Famaritana ny lojika ankapobeny.

Ny lojika ankapoben'ny soratra dia toy izao manaraka izao.

  • Manangona angona amin'ny milina virtoaly mampiasa script PowerShell, izay antsointsika amin'ny alalan'ny R, ary manambatra ny valiny ho csv iray. Toy izany koa ny fifampiraharahana mifamadika eo amin'ny samy fiteny. (azo atao ny mitondra angon-drakitra mivantana avy amin'ny R mankany PowerShell amin'ny endrika varimbazaha, saingy sarotra izany, ary ny fananana csvs intermediate dia manamora ny fanadiovana sy ny fizarana valiny manelanelana amin'ny olona iray).
  • Amin'ny fampiasana R, dia mamorona masontsivana manan-kery ho an'ny saha misy ny soatoavina hojerentsika. - Mamorona antontan-taratasy misy teny izay ahitana ny soatoavin'ireo saha ireo izahay mba hampidirana ao amin'ny taratasy fampahalalana, izay ho valin'ny fanontanian'ny mpiara-miasa "Tsia, fa ahoana no hamenoana an'io?"
  • Mametraka angona ho an'ny VM rehetra avy amin'ny csv mampiasa R izahay, mamorona rafitra angon-drakitra, manala saha tsy ilaina ary mamorona antontan-taratasy xlsx fampahafantarana izay ahitana fampahalalana famintinana ho an'ny VM rehetra, izay ampidirinay any amin'ny loharano iraisana.
  • Mampihatra ny fanamarinana rehetra momba ny fahamarinan'ny famenoana ny saha amin'ny rafitra angon-drakitra ho an'ny VM rehetra izahay ary mamorona latabatra tsy misy afa-tsy VM misy saha diso feno (ary ireo saha ireo ihany).
  • Alefanay any amin'ny script PowerShell hafa ny lisitry ny VM, izay hijery ny diarin'ny vCenter ho an'ny hetsika famoronana VM, izay ahafahantsika manondro ny fotoana tombanana amin'ny famoronana ny VM sy ny mpamorona nokasaina. Izany no mitranga rehefa tsy misy manaiky ny fiaran'iza. Tsy mandeha haingana ity script ity, indrindra raha be dia be ny logs, noho izany dia tsy mijery afa-tsy ny herinandro 2 farany izahay, ary mampiasa fomba fiasa izay ahafahanao mikaroka fampahalalana momba ny VM maromaro miaraka. Ny script ohatra dia misy fanehoan-kevitra amin'ny antsipiriany momba ity mekanika ity. Ampidirinay ao anaty csv ny valiny, izay averinay ao amin'ny R.
  • Mamorona antontan-taratasy xlsx tsara endrika izahay izay hasongadina mena ny saha diso feno, hampiharina amin'ny tsanganana sasany ny sivana, ary haseho ny tsanganana fanampiny misy ireo mpamorona nokasaina sy ny fotoana namoronana ny VM.
  • Mamorona mailaka izahay, izay ametrahanay antontan-taratasy mamaritra ny sandan'ny saha manan-kery, ary koa latabatra misy saha tsy feno. Ao amin'ny lahatsoratra dia manondro ny isan'ny VM diso noforonina izahay, rohy mankany amin'ny loharano iraisana ary sary mandrisika. Raha tsy misy VM diso feno dia mandefa taratasy hafa misy sary mandrisika faly kokoa izahay.
  • Raketinay ny angon-drakitra ho an'ny VM rehetra ao amin'ny angon-drakitra SQL Server, amin'ny fiheverana ny mekanika nampiharina amin'ny tabilao ara-tantara (mekanika tena mahaliana - momba izay bebe kokoa any aoriana)

Raha ny marina, scripts

File kaody R lehibe

# Путь к рабочей директории (нужно для корректной работы через виндовый планировщик заданий)
setwd("C:ScriptsgetVm")
#### Подгружаем необходимые пакеты ####
library(tidyverse)
library(xlsx)
library(mailR)
library(rmarkdown)
##### Определяем пути к исходным файлам и другие переменные #####
source(file = "const.R", local = T, encoding = "utf-8")
# Проверяем существование файла со всеми ВМ и удаляем, если есть.
if (file.exists(filenameVmCreationRules)) {file.remove(filenameVmCreationRules)}
#### Создаём вордовский документ с допустимыми полями
render("VM_name_rules.Rmd",
output_format = word_document(),
output_file = filenameVmCreationRules)
# Проверяем существование файла со всеми ВМ и удаляем, если есть
if (file.exists(allVmXlsxPath)) {file.remove(allVmXlsxPath)}
#### Забираем данные по всем машинам через PowerShell скрипт. На выходе получим csv.
system(paste0("powershell -File ", getVmPsPath))
# Полный df
fullXslx_df <- allVmXlsxPath %>% 
read.csv2(stringsAsFactors = FALSE)
# Проверяем корректность заполненных полей
full_df <- fullXslx_df %>%
mutate(
# Сначала убираем все лишние пробелы и табуляции, потом учитываем разделитель запятую, потом проверяем вхождение в допустимые значения,
isSubsystemCorrect = Subsystem %>% 
gsub("[[:space:]]", "", .) %>% 
str_split(., ",") %>% 
map(function(x) (all(x %in% AllowedValues$Subsystem))) %>%
as.logical(),
isOwnerCorrect = Owner %in% AllowedValues$Owner,
isCategoryCorrect = Category %in% AllowedValues$Category,
isCreatorCorrect = (!is.na(Creator) & Creator != ''),
isCreation.DateCorrect = map(Creation.Date, IsDate)
)
# Проверяем существование файла со всеми ВМ и удаляем, если есть.
if (file.exists(filenameAll)) {file.remove(filenameAll)}
#### Формируем xslx файл с отчётом ####
# Общие данные на отдельный лист
full_df %>% write.xlsx(file=filenameAll,
sheetName=names[1],
col.names=TRUE,
row.names=FALSE,
append=FALSE)
#### Формируем xslx файл с неправильно заполненными полями ####
# Формируем df
incorrect_df <- full_df %>%
select(VM.Name, 
IP.s, 
Owner,
Subsystem,
Creator,
Category,
Creation.Date,
isOwnerCorrect, 
isSubsystemCorrect, 
isCategoryCorrect,
isCreatorCorrect,
vCenter.Name) %>%
filter(isSubsystemCorrect == F | 
isOwnerCorrect == F |
isCategoryCorrect == F |
isCreatorCorrect == F)
# Проверяем существование файла со всеми ВМ и удаляем, если есть.
if (file.exists(filenameIncVM)) {file.remove(filenameIncVM)}
# Сохраняем список VM с незаполненными полями в csv
incorrect_df %>%
select(VM.Name) %>%
write_csv2(path = filenameIncVM, append = FALSE)
# Фильтруем для вставки в почту
incorrect_df_filtered <- incorrect_df %>% 
select(VM.Name, 
IP.s, 
Owner, 
Subsystem, 
Category,
Creator,
vCenter.Name,
Creation.Date
)
# Считаем количество строк
numberOfRows <- nrow(incorrect_df)
#### Начало условия ####
# Дальше либо у нас есть неправильно заполненные поля, либо нет.
# Если есть - запускаем ещё один скрипт
if (numberOfRows > 0) {
# Проверяем существование файла с создателями и удаляем, если есть.
if (file.exists(creatorsFilePath)) {file.remove(creatorsFilePath)}
# Запускаем PowerShell скрипт, который найдёт создателей найденных VM. На выходе получим csv.
system(paste0("powershell -File ", getCreatorsPath))
# Читаем файл с создателями
creators_df <- creatorsFilePath %>%
read.csv2(stringsAsFactors = FALSE)
# Фильтруем для вставки в почту, добавляем данные из таблицы с создателями
incorrect_df_filtered <- incorrect_df_filtered %>% 
select(VM.Name, 
IP.s, 
Owner, 
Subsystem, 
Category,
Creator,
vCenter.Name,
Creation.Date
) %>% 
left_join(creators_df, by = "VM.Name") %>% 
rename(`Предполагаемый создатель` = CreatedBy, 
`Предполагаемая дата создания` = CreatedOn)  
# Формируем тело письма
emailBody <- paste0(
'<html>
<h3>Добрый день, уважаемые коллеги.</h3>
<p>Полную актуальную информацию по виртуальным машинам вы можете посмотреть на диске H: вот тут:<p>
<p>\server.ruVM', sourceFileFormat, '</p>
<p>Также во вложении список ВМ с <strong>некорректно заполненными</strong> полями. Всего их <strong>', numberOfRows,'</strong>.</p>
<p>В таблице появилось 2 дополнительные колонки. <strong>Предполагаемый создатель</strong> и <strong>Предполагаемая дата создания</strong>, которые достаются из логов vCenter за последние 2 недели</p>
<p>Просьба создателей машин уточнить данные и заполнить поля корректно. Правила заполнения полей также во вложении</p>
<p><img src="data/meme.jpg"></p>
</html>'
)
# Проверяем существование файла
if (file.exists(filenameIncorrect)) {file.remove(filenameIncorrect)}
# Формируем красивую таблицу с форматами и т.д.
source(file = "email.R", local = T, encoding = "utf-8")
#### Формируем письмо с плохо подписанными машинами ####
send.mail(from = emailParams$from,
to = emailParams$to,
subject = "ВМ с некорректно заполненными полями",
body = emailBody,
encoding = "utf-8",
html = TRUE,
inline = TRUE,
smtp = emailParams$smtpParams,
authenticate = TRUE,
send = TRUE,
attach.files = c(filenameIncorrect, filenameVmCreationRules),
debug = FALSE)
#### Дальше пойдёт блок, если нет проблем с ВМ ####
} else {
# Формируем тело письма
emailBody <- paste0(
'<html>
<h3>Добрый день, уважаемые коллеги</h3>
<p>Полную актуальную информацию по виртуальным машинам вы можете посмотреть на диске H: вот тут:<p>
<p>\server.ruVM', sourceFileFormat, '</p>
<p>Также, на текущий момент, все поля ВМ корректно заполнены</p>
<p><img src="data/meme_correct.jpg"></p>
</html>'
)
#### Формируем письмо без плохо заполненных VM ####
send.mail(from = emailParams$from,
to = emailParams$to,
subject = "Сводная информация",
body = emailBody,
encoding = "utf-8",
html = TRUE,
inline = TRUE,
smtp = emailParams$smtpParams,
authenticate = TRUE,
send = TRUE,
debug = FALSE)
}
####### Записываем данные в БД #####
source(file = "DB.R", local = T, encoding = "utf-8")

Script hahazoana lisitry ny vm ao amin'ny PowerShell

# Данные для подключения и другие переменные
$vCenterNames = @(
"vcenter01", 
"vcenter02", 
"vcenter03"
)
$vCenterUsername = "myusername"
$vCenterPassword = "mypassword"
$filename = "C:ScriptsgetVmdataallvmall-vm-$(get-date -f yyyy-MM-dd).csv"
$destinationSMB = "server.rumyfolder$vm"
$IP0=""
$IP1=""
$IP2=""
$IP3=""
$IP4=""
$IP5=""
# Подключение ко всем vCenter, что содержатся в переменной. Будет работать, если логин и пароль одинаковые (например, доменные)
Connect-VIServer -Server $vCenterNames -User $vCenterUsername -Password $vCenterPassword
write-host ""
# Создаём функцию с циклом по всем vCenter-ам
function Get-VMinventory {
# В этой переменной будет списко всех ВМ, как объектов
$AllVM = Get-VM | Sort Name
$cnt = $AllVM.Count
$count = 1
# Начинаем цикл по всем ВМ и собираем необходимые параметры каждого объекта
foreach ($vm in $AllVM) {
$StartTime = $(get-date)
$IP0 = $vm.Guest.IPAddress[0]
$IP1 = $vm.Guest.IPAddress[1]
$IP2 = $vm.Guest.IPAddress[2]
$IP3 = $vm.Guest.IPAddress[3]
$IP4 = $vm.Guest.IPAddress[4]
$IP5 = $vm.Guest.IPAddress[5]
If ($IP0 -ne $null) {If ($IP0.Contains(":") -ne 0) {$IP0=""}}
If ($IP1 -ne $null) {If ($IP1.Contains(":") -ne 0) {$IP1=""}}
If ($IP2 -ne $null) {If ($IP2.Contains(":") -ne 0) {$IP2=""}}
If ($IP3 -ne $null) {If ($IP3.Contains(":") -ne 0) {$IP3=""}}
If ($IP4 -ne $null) {If ($IP4.Contains(":") -ne 0) {$IP4=""}}
If ($IP5 -ne $null) {If ($IP5.Contains(":") -ne 0) {$IP5=""}}
$cluster = $vm | Get-Cluster | Select-Object -ExpandProperty name  
$Bootime = $vm.ExtensionData.Runtime.BootTime
$TotalHDDs = $vm.ProvisionedSpaceGB -as [int]
$CreationDate = $vm.CustomFields.Item("CreationDate") -as [string]
$Creator = $vm.CustomFields.Item("Creator") -as [string]
$Category = $vm.CustomFields.Item("Category") -as [string]
$Owner = $vm.CustomFields.Item("Owner") -as [string]
$Subsystem = $vm.CustomFields.Item("Subsystem") -as [string]
$IPS = $vm.CustomFields.Item("IP") -as [string]
$vCPU = $vm.NumCpu
$CorePerSocket = $vm.ExtensionData.config.hardware.NumCoresPerSocket
$Sockets = $vCPU/$CorePerSocket
$Id = $vm.Id.Split('-')[2] -as [int]
# Собираем все параметры в один объект
$Vmresult = New-Object PSObject
$Vmresult | add-member -MemberType NoteProperty -Name "Id" -Value $Id   
$Vmresult | add-member -MemberType NoteProperty -Name "VM Name" -Value $vm.Name  
$Vmresult | add-member -MemberType NoteProperty -Name "Cluster" -Value $cluster  
$Vmresult | add-member -MemberType NoteProperty -Name "Esxi Host" -Value $VM.VMHost  
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 1" -Value $IP0
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 2" -Value $IP1
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 3" -Value $IP2
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 4" -Value $IP3
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 5" -Value $IP4
$Vmresult | add-member -MemberType NoteProperty -Name "IP Address 6" -Value $IP5
$Vmresult | add-member -MemberType NoteProperty -Name "vCPU" -Value $vCPU
$Vmresult | Add-Member -MemberType NoteProperty -Name "CPU Sockets" -Value $Sockets
$Vmresult | Add-Member -MemberType NoteProperty -Name "Core per Socket" -Value $CorePerSocket
$Vmresult | add-member -MemberType NoteProperty -Name "RAM (GB)" -Value $vm.MemoryGB
$Vmresult | add-member -MemberType NoteProperty -Name "Total-HDD (GB)" -Value $TotalHDDs
$Vmresult | add-member -MemberType NoteProperty -Name "Power State" -Value $vm.PowerState
$Vmresult | add-member -MemberType NoteProperty -Name "OS" -Value $VM.ExtensionData.summary.config.guestfullname  
$Vmresult | Add-Member -MemberType NoteProperty -Name "Boot Time" -Value $Bootime
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Status" -Value $vm.ExtensionData.Guest.ToolsStatus  
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Version" -Value $vm.ExtensionData.Guest.ToolsVersion  
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Version Status" -Value $vm.ExtensionData.Guest.ToolsVersionStatus  
$Vmresult | add-member -MemberType NoteProperty -Name "VMTools Running Status" -Value $vm.ExtensionData.Guest.ToolsRunningStatus  
$Vmresult | add-member -MemberType NoteProperty -Name "Creation Date" -Value $CreationDate
$Vmresult | add-member -MemberType NoteProperty -Name "Creator" -Value $Creator
$Vmresult | add-member -MemberType NoteProperty -Name "Category" -Value $Category
$Vmresult | add-member -MemberType NoteProperty -Name "Owner" -Value $Owner
$Vmresult | add-member -MemberType NoteProperty -Name "Subsystem" -Value $Subsystem
$Vmresult | add-member -MemberType NoteProperty -Name "IP's" -Value $IPS
$Vmresult | add-member -MemberType NoteProperty -Name "vCenter Name" -Value $vm.Uid.Split('@')[1].Split(':')[0]  
# Считаем общее и оставшееся время выполнения и выводим на экран результаты. Использовалось для тестирования, но по факту оказалось очень удобно.
$elapsedTime = $(get-date) - $StartTime
$totalTime = "{0:HH:mm:ss}" -f ([datetime]($elapsedTime.Ticks*($cnt - $count)))
clear-host
Write-Host "Processing" $count "from" $cnt 
Write-host "Progress:" ([math]::Round($count/$cnt*100, 2)) "%" 
Write-host "You have about " $totalTime "for cofee"
Write-host ""
$count++
# Выводим результат, чтобы цикл "знал" что является результатом выполнения одного прохода
$Vmresult
}
}
# Вызываем получившуюся функцию и сразу выгружаем результат в csv
$allVm = Get-VMinventory | Export-CSV -Path $filename -NoTypeInformation -UseCulture -Force
# Пытаемся выложить полученный файл в нужное нам место и, в случае ошибки, пишем лог.
try
{
Copy-Item $filename -Destination $destinationSMB -Force -ErrorAction SilentlyContinue
}
catch
{
$error | Export-CSV -Path $filename".error" -NoTypeInformation -UseCulture -Force
}

Script PowerShell izay maka avy amin'ny diary ny mpamorona ny milina virtoaly sy ny daty namoronana azy

# Путь к файлу, из которого будем доставать список VM
$VMfilePath = "C:ScriptsgetVmcreators_VMcreators_VM_$(get-date -f yyyy-MM-dd).csv"
# Путь к файлу, в который будем записывать результат
$filePath = "C:ScriptsgetVmdatacreatorscreators-$(get-date -f yyyy-MM-dd).csv"
# Создаём вокрфлоу
Workflow GetCreators-Wf
{
# Параметры, которые можно будет передать при вызове скрипта
param([string[]]$VMfilePath)
# Параметры, которые доступны только внутри workflow
$vCenterUsername = "myusername"
$vCenterPassword = "mypassword"
$daysToLook = 14
$start = (get-date).AddDays(-$daysToLook)
$finish = get-date
# Значения, которые будут вписаны в csv для машин, по которым не будет ничего найдено
$UnknownUser = "UNKNOWN"
$UnknownCreatedTime = "0000-00-00"
# Определяем параметры подключения и выводной файл, которые будут доступны во всём скрипте.
$vCenterNames = @(
"vcenter01", 
"vcenter02", 
"vcenter03"
)
# Получаем список VM из csv и загружаем соответствующие объекты
$list = Import-Csv $VMfilePath -UseCulture | select -ExpandProperty VM.Name
# Цикл, который будет выполняться параллельно (по 5 машин за раз)
foreach -parallel ($row in $list)
{
# Это скрипт, который видит только свои переменные и те, которые ему переданы через $Using
InlineScript {
# Время начала выполнения отдельного блока
$StartTime = $(get-date)
Write-Host ""
Write-Host "Processing $Using:row started at $StartTime"
Write-Host ""
# Подключение оборачиваем в переменную, чтобы информация о нём не мешалась в консоли
$con = Connect-VIServer -Server $Using:vCenterNames -User $Using:vCenterUsername -Password $Using:vCenterPassword
# Получаем объект vm
$vm = Get-VM -Name $Using:row
# Ниже 2 одинаковые команды. Одна с фильтром по времени, вторая - без. Можно пользоваться тем,
$Event = $vm | Get-VIEvent -Start $Using:start -Finish $Using:finish -Types Info | Where { $_.Gettype().Name -eq "VmBeingDeployedEvent" -or $_.Gettype().Name -eq "VmCreatedEvent" -or $_.Gettype().Name -eq "VmRegisteredEvent" -or $_.Gettype().Name -eq "VmClonedEvent"}
# $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"}
# Заполняем параметры в зависимости от того, удалось ли в логах найти что-то
If (($Event | Measure-Object).Count -eq 0){
$User = $Using:UnknownUser
$Created = $Using:UnknownCreatedTime
$CreatedFormat = $Using:UnknownCreatedTime
} Else {
If ($Event.Username -eq "" -or $Event.Username -eq $null) {
$User = $Using:UnknownUser
} Else {
$User = $Event.Username
} # Else
$CreatedFormat = $Event.CreatedTime
# Один из коллег отдельно просил, чтобы время было в таком формате, поэтому дублируем его. А в БД пойдёт нормальный формат.
$Created = $Event.CreatedTime.ToString('yyyy-MM-dd')
} # Else
Write-Host "Creator for $vm is $User. Creating object."
# Создаём объект. Добавляем параметры.
$Vmresult = New-Object PSObject
$Vmresult | add-member -MemberType NoteProperty -Name "VM Name" -Value $vm.Name  
$Vmresult | add-member -MemberType NoteProperty -Name "CreatedBy" -Value $User
$Vmresult | add-member -MemberType NoteProperty -Name "CreatedOn" -Value $CreatedFormat
$Vmresult | add-member -MemberType NoteProperty -Name "CreatedOnFormat" -Value $Created           
# Выводим результаты
$Vmresult
} # Inline
} # ForEach
}
$Creators = GetCreators-Wf $VMfilePath
# Записываем результат в файл
$Creators | select 'VM Name', CreatedBy, CreatedOn | Export-Csv -Path $filePath -NoTypeInformation -UseCulture -Force
Write-Host "CSV generetion finisghed at $(get-date). PROFIT"

Mendrika hojerena manokana ny tranomboky xlsx, izay nahafahana nanao ny fametahana ny taratasy ho endrika mazava (araka ny tian'ny fitantanana), fa tsy latabatra CSV fotsiny.

Mamorona antontan-taratasy xlsx tsara tarehy misy lisitry ny milina tsy feno

# Создаём новую книгу
# Возможные значения : "xls" и "xlsx"
wb<-createWorkbook(type="xlsx")
# Стили для имён рядов и колонок в таблицах
TABLE_ROWNAMES_STYLE <- CellStyle(wb) + Font(wb, isBold=TRUE)
TABLE_COLNAMES_STYLE <- CellStyle(wb) + Font(wb, isBold=TRUE) +
Alignment(wrapText=TRUE, horizontal="ALIGN_CENTER") +
Border(color="black", position=c("TOP", "BOTTOM"), 
pen=c("BORDER_THIN", "BORDER_THICK"))
# Создаём новый лист
sheet <- createSheet(wb, sheetName = names[2])
# Добавляем таблицу
addDataFrame(incorrect_df_filtered, 
sheet, startRow=1, startColumn=1,  row.names=FALSE, byrow=FALSE,
colnamesStyle = TABLE_COLNAMES_STYLE,
rownamesStyle = TABLE_ROWNAMES_STYLE)
# Меняем ширину, чтобы форматирование было автоматическим
autoSizeColumn(sheet = sheet, colIndex=c(1:ncol(incorrect_df)))
# Добавляем фильтры
addAutoFilter(sheet, cellRange = "C1:G1")
# Определяем стиль
fo2 <- Fill(foregroundColor="red")
cs2 <- CellStyle(wb, 
fill = fo2, 
dataFormat = DataFormat("@"))
# Находим ряды с неверно заполненным полем Владельца и применяем к ним определённый стиль
rowsOwner <- getRows(sheet, rowIndex = (which(!incorrect_df$isOwnerCorrect) + 1))
cellsOwner <- getCells(rowsOwner, colIndex = which( colnames(incorrect_df_filtered) == "Owner" )) 
lapply(names(cellsOwner), function(x) setCellStyle(cellsOwner[[x]], cs2))
# Находим ряды с неверно заполненным полем Подсистемы и применяем к ним определённый стиль
rowsSubsystem <- getRows(sheet, rowIndex = (which(!incorrect_df$isSubsystemCorrect) + 1))
cellsSubsystem <- getCells(rowsSubsystem, colIndex = which( colnames(incorrect_df_filtered) == "Subsystem" )) 
lapply(names(cellsSubsystem), function(x) setCellStyle(cellsSubsystem[[x]], cs2))
# Аналогично по Категории
rowsCategory <- getRows(sheet, rowIndex = (which(!incorrect_df$isCategoryCorrect) + 1))
cellsCategory <- getCells(rowsCategory, colIndex = which( colnames(incorrect_df_filtered) == "Category" )) 
lapply(names(cellsCategory), function(x) setCellStyle(cellsCategory[[x]], cs2))
# Создатель
rowsCreator <- getRows(sheet, rowIndex = (which(!incorrect_df$isCreatorCorrect) + 1))
cellsCreator <- getCells(rowsCreator, colIndex = which( colnames(incorrect_df_filtered) == "Creator" )) 
lapply(names(cellsCreator), function(x) setCellStyle(cellsCreator[[x]], cs2))
# Сохраняем файл
saveWorkbook(wb, filenameIncorrect)

Ny vokatra dia toy izao manaraka izao:

Tatitra isan'andro momba ny fahasalaman'ny milina virtoaly mampiasa R sy PowerShell

Nisy ihany koa ny nuance mahaliana momba ny fametrahana ny Windows scheduler. Tsy afaka nahita ny zo sy ny toe-javatra mety mba hanombohan'ny zava-drehetra araka ny tokony ho izy. Vokatr'izany dia hita ny tranomboky R, izay mamorona asa hananganana script R ary tsy manadino akory ny rakitra log. Avy eo dia azonao atao ny manitsy ny asa amin'ny tanana.

Sombin'ny kaody R misy ohatra roa izay mamorona asa ao amin'ny Windows Scheduler

library(taskscheduleR)
myscript <- file.path(getwd(), "all_vm.R")
## запускаем скрипт через 62 секунды
taskscheduler_create(taskname = "getAllVm", rscript = myscript, 
schedule = "ONCE", starttime = format(Sys.time() + 62, "%H:%M"))
## запускаем скрипт каждый день в 09:10
taskscheduler_create(taskname = "getAllVmDaily", rscript = myscript, 
schedule = "WEEKLY", 
days = c("MON", "TUE", "WED", "THU", "FRI"),
starttime = "02:00")
## удаляем задачи
taskscheduler_delete(taskname = "getAllVm")
taskscheduler_delete(taskname = "getAllVmDaily")
# Смотрим логи (последние 4 строчки)
tail(readLines("all_vm.log"), sep ="n", n = 4)

Misaraka momba ny angon-drakitra

Taorian'ny fametrahana ny script dia nanomboka niseho ireo olana hafa. Ohatra, te hahita ny daty voafafa ny VM aho, fa ny logs ao amin'ny vCenter dia efa simba. Koa satria ny script dia mametraka rakitra ao anaty lahatahiry iray isan'andro ary tsy manadio azy (manadio azy amin'ny tananay izahay rehefa mahatsiaro), dia azonao atao ny mijery ny rakitra taloha ary mahita ny rakitra voalohany tsy misy an'io VM io. Saingy tsy mahafinaritra izany.

Te hamorona angon-drakitra ara-tantara aho.

Ny fiasan'ny MS SQL SERVER - latabatra ara-potoana misy rafitra - dia tonga nanavotra. Matetika izy io no adika ho tabilao vonjimaika (tsy vonjimaika).

Azonao atao ny mamaky amin'ny antsipiriany ao amin'ny antontan-taratasy ofisialy Microsoft.

Raha fintinina dia mamorona latabatra izahay, lazao fa hanana izany miaraka amin'ny versioning izahay, ary ny SQL Server dia mamorona tsanganana daty 2 fanampiny amin'ity latabatra ity (ny daty namoronana ny rakitra sy ny daty lany daty) ary ny latabatra fanampiny izay miova. hosoratana. Vokatr'izany dia mahazo vaovao farany izahay ary, amin'ny alàlan'ny fanontaniana tsotra, ohatra omena ao amin'ny antontan-taratasy, dia afaka mahita na ny tsingerin'ny fiainan'ny milina virtoaly manokana, na ny toetry ny VM rehetra amin'ny fotoana iray. ara-potoana.

Raha jerena amin'ny fomba fijery ny zava-bita dia tsy ho vita ny fifampiraharahana fanoratana amin'ny tabilao lehibe raha tsy vita ny fifampiraharahana fanoratana amin'ny latabatra vonjimaika. Ireo. eo amin'ny latabatra misy asa fanoratana marobe, ity fiasa ity dia tokony hampiharina amim-pitandremana, fa amin'ny tranga misy antsika dia zavatra tena mahafinaritra izany.

Mba hahafahan'ny mekanika miasa tsara dia tsy maintsy nampiana kaody kely amin'ny R aho izay hampitaha ny latabatra vaovao miaraka amin'ny angona ho an'ny VM rehetra miaraka amin'ilay voatahiry ao anaty tahiry ary manoratra andalana niova ho azy fotsiny. Ny kaody dia tsy tena marani-tsaina; mampiasa ny tranomboky compareDF, fa hasehoko eto ambany ihany koa.

R code mba hanoratana angona amin'ny angona

# Подцепляем пакеты
library(odbc)
library(compareDF)
# Формируем коннект
con <- dbConnect(odbc(),
Driver = "ODBC Driver 13 for SQL Server",
Server = DBParams$server,
Database = DBParams$database,
UID = DBParams$UID,
PWD = DBParams$PWD,
Port = 1433)
#### Проверяем есть ли таблица. Если нет - создаём. ####
if (!dbExistsTable(con, DBParams$TblName)) {
#### Создаём таблицу ####
create <- dbSendStatement(
con,
paste0(
'CREATE TABLE ',
DBParams$TblName,
'(
[Id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[VM.Name] [varchar](255) NULL,
[Cluster] [varchar](255) NULL,
[Esxi.Host] [varchar](255) NULL,
[IP.Address.1] [varchar](255) NULL,
[IP.Address.2] [varchar](255) NULL,
[IP.Address.3] [varchar](255) NULL,
[IP.Address.4] [varchar](255) NULL,
[IP.Address.5] [varchar](255) NULL,
[IP.Address.6] [varchar](255) NULL,
[vCPU] [int] NULL,
[CPU.Sockets] [int] NULL,
[Core.per.Socket] [int] NULL,
[RAM..GB.] [int] NULL,
[Total.HDD..GB.] [int] NULL,
[Power.State] [varchar](255) NULL,
[OS] [varchar](255) NULL,
[Boot.Time] [varchar](255) NULL,
[VMTools.Status] [varchar](255) NULL,
[VMTools.Version] [int] NULL,
[VMTools.Version.Status] [varchar](255) NULL,
[VMTools.Running.Status] [varchar](255) NULL,
[Creation.Date] [varchar](255) NULL,
[Creator] [varchar](255) NULL,
[Category] [varchar](255) NULL,
[Owner] [varchar](255) NULL,
[Subsystem] [varchar](255) NULL,
[IP.s] [varchar](255) NULL,
[vCenter.Name] [varchar](255) NULL,
DateFrom datetime2 GENERATED ALWAYS AS ROW START NOT NULL,
DateTo datetime2 GENERATED ALWAYS AS ROW END NOT NULL,
PERIOD FOR SYSTEM_TIME (DateFrom, DateTo)
) ON [PRIMARY]
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = ', DBParams$TblHistName,'));'
)
)
# Отправляем подготовленный запрос
dbClearResult(create)
} # if
#### Начало работы с таблицей ####
# Обозначаем таблицу, с которой будем работать
allVM_db_con <- tbl(con, DBParams$TblName) 
#### Сравниваем таблицы ####
# Собираем данные с таблицы (убираем служебные временные поля)
allVM_db <- allVM_db_con %>% 
select(c(-"DateTo", -"DateFrom")) %>% 
collect()
# Создаём таблицу со сравнением объектов. Сравниваем по Id
# Удалённые объекты там будут помечены через -, созданные через +, изменённые через - и +
ctable_VM <- fullXslx_df %>% 
compare_df(allVM_db, 
c("Id"))
#### Удаление строк ####
# Выдираем Id виртуалок, записи о которых надо удалить 
remove_Id <- ctable_VM$comparison_df %>% 
filter(chng_type == "-") %>%
select(Id)
# Проверяем, что есть записи (если записей нет - и удалять ничего не нужно)
if (remove_Id %>% nrow() > 0) {
# Конструируем шаблон для запроса на удаление данных
delete <- dbSendStatement(con, 
paste0('
DELETE 
FROM ',
DBParams$TblName,
' WHERE "Id"=?
') # paste
) # send
# Создаём запрос на удаление данных
dbBind(delete, remove_Id)
# Отправляем подготовленный запрос
dbClearResult(delete)
} # if
#### Добавление строк ####
# Выделяем таблицу, содержащую строки, которые нужно добавить.
allVM_add <- ctable_VM$comparison_df %>% 
filter(chng_type == "+") %>% 
select(-chng_type)
# Проверяем, есть ли строки, которые нужно добавить и добавляем (если нет - не добавляем)
if (allVM_add %>% nrow() > 0) {
# Пишем таблицу со всеми необходимыми данными
dbWriteTable(con,
DBParams$TblName,
allVM_add,
overwrite = FALSE,
append = TRUE)
} # if
#### Не забываем сделать дисконнект ####
dbDisconnect(con)

Итого

Vokatry ny fampiharana ny script dia naverina tamin'ny laoniny ny filaminana ary voatazona tao anatin'ny volana vitsivitsy. Indraindray dia miseho ny VM diso feno, fa ny script dia natao ho fampahatsiahivana tsara ary misy VM tsy fahita firy miditra ao anaty lisitra mandritra ny 2 andro misesy.

Natao ihany koa ny famakafakana ny angona ara-tantara.

Mazava fa ny ankamaroan'izany dia azo ampiharina tsy amin'ny lohalika, fa amin'ny rindrambaiko manokana, saingy mahaliana ny asa ary, mety hisy hilaza, tsy voatery.

Nasehon'i R indray fa fiteny iray tena tsara ho an'ny rehetra, izay tonga lafatra tsy amin'ny famahana olana ara-statistika fotsiny, fa miasa ho toy ny “sosona” tsara indrindra eo amin'ireo loharano angon-drakitra hafa.

Tatitra isan'andro momba ny fahasalaman'ny milina virtoaly mampiasa R sy PowerShell

Source: www.habr.com

Add a comment