Powershell – monitorování běžících služeb
Zadání
Potřebujeme pravidelně monitorovat běžící služby na několika strojích a informace ukládat pro pozdější analýzu.
Kam ukládat
Jako úložiště jsem zvolil Microsoft Access. Můžete samozřejmě použít i jinou databázi, popřípadě Excel, ale Access je podle mě rozumný kompromis mezi SQL serverem a Excelem. Databáze má dvě tabulky. Jedna tabulka obsahuje seznam serverů, které chceme sledovat, druhá tabulka pak obsahuje sledované informace, v našem případě běžící služby. Vzorová databáze, i s hotovým skriptem, je k dispozici ke stažení na konci článku včetně krátkého screencastu, jak si vytvořit vlastní databázi.
Jak získat seznam běžících služeb
Seznam služeb na cílovém počítači získáme pomocí Windows Management Instrumentation (WMI). Samozřejmě tato služba musí být povolena na cílovém počítači a uživatel, pod kterým je skript spuštěn, musí mít příslušná oprávnění. Pokud je toto splněno, nic nám nebrání příslušné informace získat pomocí cmdletu Get-WmiObject. Základní použití:
Get-WmiObject [typ informace] -ComputerName [jméno počítače]
Jak načíst informace z databáze
Pro komunikaci s databází Access využijeme ADODB což je jeden z možných způsobů komunikace s databází. Pro nás bude důležité ADODB.Connection, které nám vytvoří spojení s databází a ADODB.Recordset, který slouží k manipulaci s obsahem databáze. Aby bylo možné vytvořit spojení s databází, je potřeba mít přístup k souboru databáze a mít nainstalovaný ovladač pro Microsoft Access, který je součástí instalace Microsoft Office. Pokud budete chtít obsah databáze zpřístupnit i uživatelům, kteří Microsoft Access nemají, můžete použít Microsoft Access Runtime nebo Access Services pro Sharepoint 2010.
Skript
POZOR! Tento skript je funkční jen v 32-bitovém režimu kvůli ADO ovladači.
# Výpis na obrazovku
Write-Host 'START'
# Vytvoření COM objektu, pokud byste chtěli vytvořit .NET objekt, neuvedete přepínač -ComObject
$objConnection = New-Object -ComObject ADODB.Connection
$objRecordSet = New-Object -ComObject ADODB.Recordset
# Práce s objekty, pomocí znaku . (tečka) se dostanete k metodám a vlastnostem objektu
# Otevření databáze
$objConnection.Open('Provider=Microsoft.ACE.OLEDB.12.0;Data Source=[cesta k databázi]')
# Získání seznamu počítačů
$objRecordSet.Open('SELECT ID, ComputerName FROM Computers WHERE Active = true', $objConnection, 3, 3)
# Vytvoření proměnné, zde konkrétně asociativního pole (hastable)
$computerList = @{}
# Jeden z podporovaných cyklů
while( !$objRecordSet.EOF)
{
# Pomocí hranatých závorek se přistupuje k položkám pole nebo asociativního pole
$computerList[$objRecordSet.Fields.Item('ID').Value] = $objRecordSet.Fields.Item('ComputerName').Value
$objRecordSet.MoveNext()
}
# Uzavření přístupu k seznamu počítačů
$objRecordSet.Close()
# Otevření tabulky, kam budeme zapisovat seznam služeb
$objRecordSet.Open('SELECT ID, TimeStamp, ServiceName, State, Status, StartMode, ComputerName FROM Services', $objConnection, 3, 3)
# Další z podporovaných cyklů, zde konkrétně procházíme kolekci klíčů asociativního pole
foreach($computerID in $computerList.Keys)
{
# Vypsání informace na obrazovku
$computerList[$computerID]
# CMDlet Get-WmiObject zpřístupňje WMI, na cílových počítačích musí být povolen vzdálený přístup k WMI
$services = Get-WmiObject win32_service -ComputerName $computerList[$computerID]
foreach($service in $services)
{
# Nový záznam
$objRecordSet.AddNew()
# Vyplnění informací
$objRecordSet.Fields.Item("TimeStamp").Value = Get-Date
$objRecordSet.Fields.Item("ServiceName").Value = $service.Name
$objRecordSet.Fields.Item("State").Value = $service.State
$objRecordSet.Fields.Item("Status").Value = $service.Status
$objRecordSet.Fields.Item("StartMode").Value = $service.StartMode
$objRecordSet.Fields.Item("ComputerName").Value = $computerID
# Uložení do databáze
$objRecordSet.Update()
}
}
# Zavřeme, co bylo otevřeno
$objRecordSet.Close()
$objConnection.Close()
Write-Host 'END'
Štěpán