Storage Capacity Report - Statystyki dysków na klastrze Hyper-v w PowerShell
25o EHLO
Raporty to podstawa zarówno w rozmowie z biznesem, planowaniu rozbudowy srodowiska, proaktywnemu dzialaniu czy po prostu dobremu zarzadzaniu. Przy wiekszych srodowiskach dosc duzym problemem staje sie zarzadzanie przestrzenia - wiadomo, takie zabawki troche kosztuja i póki jest duzy zapas nie trzeba sie troszczyc o lokacje maszyn. kiedy jednak z jednej strony srodowisko sie rozrasta, a biznes zaciska pasa i kolejnej pólki dyskowej nie bardzo chce dostawic, zaczyna sie coraz intensywniejsze wykorzystywanie 'Storage Migration' i 'ukladanie' maszyn tak, aby wszedzie zostala odpowiednia ilosc miejsca. Scenariuszy, w których raportowanie bylo niezbedne, spotkalem wiele. Przykladowe:
- Sa CSV utworzone na róznych typach RAID. Czy lokalizacja maszyn i dysków jest optymalna? glównie chodzi oczywiscie o wszelkiego rodzaju bazy danych.
- Jakis n00b wymyslil tragiczny sposób tworzenia CSV - jest wiele drobnych dysków powodujacych spora fragmentacje przestrzeni. Jak ulokowac maszyny, zeby zoptymalizowac przestrzen?
- Trzeba kupic nowa pólke za *dziesiat-tysiecy-€?? A co jest nie tak z obecna? [a na drugi dzien: prosze dla dzialu DEV przygotowac 5 nowych wirtualek do projektu.. (; ]
- Podczas tworzenia backpów proces zaczyna blokowac CSV i staja uslugi krytyczne. Póki sie tego nie naprawi trzeba tak poustawiac maszyny, zeby oddzielic je pod wzgledem kalendarza backpów i krytycznosci.
Do raportowania, jak zreszta do wiekszosci operacji, najlepszy jest PowerShell (: Jest oczywiscie wiele mozliwosci i narzedzi ale... nie ma to jak przygotowac sobie samemu i móc dynamicznie wykorzystac do nowego scenariusza.
Jest kilka poziomów, z których mozemy wykonywac zapytania - mozna odpytywac sie systemów operacyjnych, klastra, SC VMM, Hyper-v ... i do tego wykorzystywac rózne mechanizmy - czy to natywne commandlety czy dziargac w WMI. Srodowisko, dla którego beda ponizsze opisy, sklada sie z systemów Windows Server 2o12 lub nowszych oraz System Center Virtual Machine Manager 2o12 lub nowszy. Niektóre skrypty trzeba bedzie troche pozmieniac, zeby dzialaly dla w2k8R2.
Czesc pierwsza: Ogólne statystyki CSV
W przypadku CSV najszybsza metoda bedzie odpytanie klastra - w koncu przechowuje on wszystkie te informacje, a skoro widac je w interfejsie, to znaczy, ze da sie je latwo wydobyc. Dosc szybko mozna odnalezc commandlet, który pokazuje informacje o CSV - get-ClusterSharedVolume. Wyniki jednak sa zaskakujaco ubogie:
C:\scriptz:))o- Get-ClusterSharedVolume -Cluster CLUSTERNAME | fl *
Name : CSV_01_SAS_RAID5
State : Online
OwnerNode : HOST01
SharedVolumeInfo : {C:\ClusterStorage\Volume5}
Id : b4034f2-0ae0-4744-a598-12017f692c08
Name : CSV_02_NSAS_RAID10
State : Online
OwnerNode : HOST2
SharedVolumeInfo : {C:\ClusterStorage\Volume4}
Id : 234ee105-4a10-4535-8312-ca634bfaaa5d
[...]
Jednym z najbardziej pomocnych polecen w PS jest get-Member. Kiedy nie wiadomo z jakim obiektem ma sie do czynienia, szybko mozna dowiedziec sie, co sie da z niego wycisnac. Ma jednak jedna podstawowa wade, która wychodzi w przypadkach takich jak ten:
C:\scriptz:))o- Get-ClusterSharedVolume -Cluster CLUSTERNAME | gm
TypeName: Microsoft.FailoverClusters.PowerShell.ClusterSharedVolume
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Update Method void Update()
Id Property string Id {get;}
Name Property string Name {get;set;}
OwnerNode Property Microsoft.FailoverClusters.PowerShell.ClusterNode OwnerNode {get;}
SharedVolumeInfo Property System.Collections.Generic.ICollection[Microsoft.FailoverClusters.PowerShell.ClusterShar...
State Property Microsoft.FailoverClusters.PowerShell.ClusterResourceState State {get;}
Co prawda widac, ze sa rózne wlasciwosci, ale nie jest takie oczywiste co z tym dalej zrobic. Na pewno warto zwrócic uwage, ze jedna z nich jest kolekcja - a wiec mozna odpytywac sie dalej o wlasciwosci tejze kolekcji. Tak jednak znajdziemy kolejne parametry bedace kolekcja i zabawa zaczyna byc nudna. A jest prostszy sposób, który wyswietli od razu caly obiekt wraz rozwinieciem kolekcji potomnych. Sluzy do tego format-custom:
C:\scriptz:))o- Get-ClusterSharedVolume -Cluster CLUSTERNAME | fc *
class ClusterSharedVolume
{
Name = CSV_01_SAS_RAID5
State = Online
OwnerNode =
class ClusterNode
{
Name = HOST1
Id = 1
State = Up
}
SharedVolumeInfo =
[
class ClusterSharedVolumeInfo
{
FaultState = NoFaults
FriendlyVolumeName = C:\ClusterStorage\Volume5
Partition =
class ClusterDiskPartitionInfo
{
Name = \\?\Volume{90d9c83a-656c-4b04-bc1c-16768219a28c}\
DriveLetter =
DriveLetterMask = 0
FileSystem = CSVFS
FreeSpace = 458293813248
MountPoints =
[
]
PartitionNumber = 1
PercentFree = 44,75537
Size = 1023997374464
UsedSpace = 565703561216
HasDriveLetter = False
IsCompressed = False
IsDirty = Unknown
IsFormatted = True
IsNtfs = False
IsPartitionNumberValid = True
IsPartitionSizeValid = True
}
PartitionNumber = 1
VolumeOffset = 1048576
MaintenanceMode = False
RedirectedAccess = False
}
]
Id = b4034f2-0ae0-4744-a598-12017f692c08
}
[...]
Tutaj widac juz pelne rozwiniecie otrzymywanego obiektu, co mozna z nim zrobic i jak nazywaja sie poszczególne kolekcje. Trzeba zwrócic uwage na "SharedVolumeInfo =" a dalej wewnatrz na "Partition =" poniewaz wewnatrz Partition jest juz smietanka - dane, które nas interesuja. I tak mozna szybko skleic:
Get-ClusterSharedVolume -Cluster atmcluster|%{$_.sharedVolumeInfo.partition}
Od razu jednak rzuca sie w oczy problem - widac wielkosci partycji, ale nie widac na których sa CSV. Aby uzyskac wszystkie informacje, trzeba bedzie niestety odpytac kolejne kolekcje. Moze sie to wydawac zagmatwane, ale proponuje popatrzec na wydruk z przykladu z format-custom. Widac tam hierarchie, która odzwierciedlona jest zapytaniem w glab:
[show-CSVsInfo.ps1]
$CSVs=Get-ClusterSharedVolume -Cluster CLUSTERNAME
foreach($csv in $CSVs) {
$SVI=$csv.sharedVolumeInfo
foreach($vol in $SVI) {
$partitions=$vol.partition
foreach($part in $partitions) {
write-host "$($csv.name),$($csv.ownernode.name),$($SVI.FriendlyVolumeName),$(([math]::Round($part.FreeSpace/1GB,2)).toString()+'GB'),$($part.percentFree),$(([math]::Round($part.FreeSpace/1GB,2)).toString()+'GB')"
}
}
}
Od razu napisze, ze to bardzo marny skrypt - co prawa widac to, co nas interesuje ale jest sprzeczny z idea PowerShell - nie zwraca obiektu, a co za tym idzie nie da sie tego dalej przeformatowac, dynamicznie cos zmienic czy w np. zrzucic tego ladnie do CSV. trzeba by to wszystko samemu oprogramowac. W tej postaci skrypt nadaje sie do 'wyswietlenia na ekran' ale porzadnego raportu, czyli takiego, który bedzie mozna otworzyc w arkuszu kalkulacyjnym i cos z tymi danymi dalej zrobic - nie za bardzo.
Jednym z najwiekszych misteriów w PowerShell jest dla mnie fakt, ze pomimo, iz w PS wszystko jest obiektowe i wszystko wokól obiektów sie kreci, to w zasadzie nie ma klas (beda w PS5). Tworzenie obiektów i operowanie nimi jest troche kulawe. Ale to jedyny sposób aby osiagnac pozadany wynik:
[show-CSVsInfo.ps1]
$CSVs=Get-ClusterSharedVolume -Cluster CLUSTERNAME
foreach($csv in $CSVs) {
$volInfo = New-Object PSObject
Add-Member -InputObject $volInfo -MemberType NoteProperty -Name CSVname -value $csv.name -Force
Add-Member -InputObject $volInfo -MemberType NoteProperty -Name CSVowner -value $csv.OwnerNode.Name -force
$SVI=$csv.sharedVolumeInfo
Add-Member -InputObject $volInfo -MemberType NoteProperty -Name CSVFriendlyName -value $SVI.FriendlyVolumeName -force
foreach($vol in $SVI) {
$partitions=$vol.partition
foreach($part in $partitions) {
Add-Member -InputObject $volInfo -MemberType NoteProperty -Name CSVFreeSpace -value $([math]::Round($part.FreeSpace/1GB,2)) -force
Add-Member -InputObject $volInfo -MemberType NoteProperty -Name CSVPercentFree -value $part.percentFree -force
Add-Member -InputObject $volInfo -MemberType NoteProperty -Name CSVSize -value $([math]::Round($part.size/1GB,2)) -Force
$volInfo
}
}
}
Calosc jest nieco kulawa, poniewaz kazda partycja, dla kazdego SVI dla kazdego CSV to oddzielny obiekt. Stad parametr '-force' który nadpisuje poprzednie wartosci. Ale tak przygotowany skrypt mozna juz spokojnie przekierowac np. na Export-CSV, wykorzystac Select czy cokolwiek innego [po zapisaniu do pliku show-CSVsInfo.ps1]:
C:\scriptz:))o- .\show-CSVsInfo.ps1 | Export-Csv -delimiter ';' -noTypeInformation -path csvstats.csv
EOF
Na koniec jeszcze dwa niuanse:
- w skrypcie przygotowanym do exportu nie dodaje 'GB' przy rozmiarach. Formatowanie w PS mozna zrobic przy pomocy select a po otwarciu w Excel lepiej miec od razu jako wartosci liczbowe, zeby mozna bylo dokonac obróbki.
- równiez z powodu Excela delimiter ustawiony jest jako srednik a nie przecinek. To odwieczna tajemnica aka w-files - czemu Excel pliki Comma-Separated-Value tworzy i interpretuje tylko jesli sa oddzielone srednikiem?
W nastepnej czesci zamieszcze opis skryptu do odpytania o szczególy dotyczace wielkosci dysków maszyn wirtualnych.
eN.
author: nExoR
Comments
- Anonymous
October 20, 2014
25o EHLO
W poprzednim wpisie pokazane zostało, jak można pobawić się danymi z dysków Cluster