W cyklu opisującym WMI dziś ostatni tekst Daniela Stefaniaka dotyczący plików MOF. Omówiony wcześniej język WQL nie wspiera modyfikacji definicji klas ani też nie umożliwia tworzenia ich instancji. Aby wypełnić lukę po DML-owych i DDL-owych częściach SQL92 można posłużyć się WMI CIM Studio, lub skorzystać z plików MOF.
Pliki Managed Object Format (MOF)
Omówiony wcześniej język WQL niestety nie wspiera modyfikacji definicji klas ani też tworzenia ich instancji. Aby wypełnić lukę po DML-owych i DDL-owych częściach SQL92 można posłużyć się WMI CIM Studio, lub skorzystać z plików MOF. Składnia Managed Object Format została zdefiniowana przez DMTF, więc wyeksportowane z WMI definicje i instancje klas powinny teoretycznie bez problemu zostać zaimportowane na innych implementacjach standardów WBEM i/lub CIM.
Przykładem praktycznego zastosowania MOF jest rozszerzanie Hardware Innventory w System Center Configuration Manager 2007/2007 R2 (i w starszych wersjach System Management Server 1.2/2.0/2003).
1. Budowa
Każdy plik MOF, który zawiera jakiekolwiek informacje, może zaczynać się od jednej lub kilku dyrektyw #pragma. Mają one na celu przekazać kompilatorowi, w jaki sposób ma on obsłużyć dany plik. Jednym z podstawowych zastosowań #pragma jest wskazanie przestrzeni nazw, na jakiej mają zostać przeprowadzone działania poniżej:
#pragma namespace("\\\\.\\Root\\CIMV2")
W przypadku ogólnym składnia jest następująca:
W szczególności polecenia mogą być :
|
Polecenie
|
Opis
|
|
amendment
|
Informuje kompilator, ze zostaną mu dostarczone informacje o zlokalizowanych klasach
Przykład: #pragma amendment ("MS_409")
|
|
autorecover
|
Dodaje dany plik MOF, do plików kompilowanych w trakcie odzyskiwania repozytorium
|
|
classflags
|
Kontroluje sposób tworzenia lub modyfikacji klas poprzez użycie odpowiednich przełączników:
- createonly – zakazuje kompilatorowi przeprowadzanie zmian w repozytorium, jeśli którakolwiek klas sprecyzowanych w pliku istnieje
- forceupdate – wymusza aktualizacje klas nawet, jeśli zmieniana definicja klasy istnieje; jeśli zmieniana klasa ma konfliktujące klasy dziedziczące, to ich definicja zostanie także zmodyfikowana; jeśli kasa dziedzicząca ma instancje, to kompilacja się nie uda
- safeupdate – pozwala modyfikować klasy w przypadku, gdy mają one klasy dziedziczące, ale tylko, gdy nie spowoduje to konfliktów; jeśli kasa dziedzicząca ma instancje, to kompilacja się nie uda
- updateonly – instruuje kompilator, aby nie tworzył nowych klas; definicja nowej klasy powoduje przerwanie działania kompilatora
Przykład: #pragma classflags ("updateonly", "forceupdate")
|
|
deleteclass
|
Usuwa z repozytorium klasę sprecyzowaną jako jeden z przełączników dyrektywy. Dodatkowo określa zachowanie kompilatora w przypadku nieudanej operacji:
- FAIL – zwraca błąd, jeśli dana klasa nie istnieje
- NOFAIL – kontynuuje niezależnie od wyniku operacji kasowania klasy
Przykład: #pragma deleteclass("MyClass1",FAIL)
|
|
deleteinstacne
|
Usuwa instancję klasy z repozytorium. Przyjmuje zawsze dwa argumenty: identyfikator obiektu (wartość pola klucza) oraz flagę precyzującą zachowanie preprocesora w przypadku niepowodzenia operacji (podobnie jak w przypadku deleteclass)
Przykład: #pragma deleteinstance ("klasa.klucz='wartosc1'", NOFAIL)
|
|
instaceflags
|
Kontroluje, czy instancje klas są aktualizowane, czy też tworzone na nowo w repozytorium za pomocą odpowiedniej flagi:
- createonly – pozwala jedynie tworzyć nowe instancje
- updateonly – pozwala jedynie aktualizować instancje
Przykład: #pragma instanceflags("createonly")
|
|
namespace
|
Określa przestrzeń nazw, na której operuje dany plik lub jego fragment
Przykład: #pragma namespace ("\\\\.\\Root\\test")
|
Tabela. Polecenia stosowane w połączeniu z dyrektywą prerpocesora #pragma
Po przekazaniu dyrektyw do kompilatora można przejść do definiowania klas. Podstawowym słowem kluczowym używanym w tym przypadku jest class. Dodatkowo można je poprzedzić listą kwalifikatorów w nawiasach kwadratowych. Poniższy przykład:
|
[Abstract]
class Osoba
{
[key] uint16 ID;
String Imie;
String Nazwisko;
};
class Pracownik : Osoba
{
Sint16 nrPracownika;
}
|
Listing. Przykładowa definicja dwóch klas w MOF
Jest zaimplementowaną wewnątrz MOF następującą parą klas:

Rysunek 18. Przykładowy fragment diagramu klas
W powyższym przypadku mamy do czynienia z klasą Osoba, która jest klasą abstrakcyjną, o następujących atrybutach: ID (wartość kluczowa), Imie oraz Nazwisko. Dziedziczy po niej klasa Pracownik posiadająca dodatkowy atrybut nrPracownika. Jak widać kwalifikatory mogą dotyczyć nie tylko definicji klas, ale także atrybutów, metod, parametrów metod oraz asocjacji. Na potrzeby tej pracy używana jest nieznaczna ich część. Resztę można znaleźć na stronach MSDN.
|
Kwalifikator
|
Opis
|
|
Associacion
|
Definiuje daną klasę, jako klasę asocjacyjną
Stosowane do: klasy
|
|
Abstract
|
Definiuje daną klasę jako klasę abstrakcyjną.
Stosowane do: klasy, asocjacje
|
|
ArrayType
|
Definiuje rodzaj tablicy dla typów tablicowych. Dopuszczalne wartości to: bag, indexed, ordered
Stosowane do: atrybuty, parametry
|
|
Description
|
Definiuje słowny opis danego fragmentu schematu
Stosowane do: wszystko
|
|
Key
|
Definiuje dany atrybut jako klucz lub jego część (dla klucza złożonego)
Stosowane do: atrybuty, referencje
|
|
Required
|
Definiuje, czy dana właściwość jest wymagana (nie dopuszcza wartości null).
Stosowane do: atrybuty
|
|
DisplayName
|
Definiuje nazwę wyświetlaną w interfejsie zamiast nazwy właściwej elementu
Stosowane do: wszystko
|
|
SupportsCreate SupportsDelete
SupportsUpdate
|
Definiują, czy dana klasa wspiera odpowiednio operacje tworzenia, kasowania i aktualizacji instancji
Stosowane do: klasy
|
|
Terminal
|
Definiuje kasę jako terminalną, czyli taką, której nie można rozszerzać:
Stosowane do: klasy
|
Tabela. Opisy kwalifikatorów obiektów
Szczególnym rodzajem kwalifikatorów są smaki (ang. flavor), które precyzują, czy i jak dany kwalifikator w klasie klasie ma być przenoszony na klasy ją dziedziczące. Ich lista prezentuje się następująco:
|
Smak
|
Opis
|
|
Amended
|
Kwalifikator nie jest wymagany i może zostać zlokalizowany
|
|
DisableOverride
|
Kwalifikator nie może zostać zmieniony ani w klasie dziedziczącej, ani w żadnej instancji
|
|
EnableOverride
|
Kwalifikator przekazany do klasy dziedziczącej lub może zostać nadpisany. Jest to ustawienie domyślne
|
|
NotToInstance
|
Kwalifikator nie jest propagowany do instancji klas
|
|
NotToSubClass
|
Kwalifikator nie jest propagowany do klas dziedziczących
|
|
Restricted
|
Kwalifikator nie jest propagowany do klas rozszerzających i instancji
|
|
ToInstance
|
Kwalifikator jest propagowany do instancji klas
|
|
ToSubClass
|
Kwalifikator jest propagowany do klas dziedziczących. Ten mak można stosować jedynie na poziomie klas, a nie instancji.
|
Tabela. Lista smakow kwalifikatorów
5.2. Zastosowanie
Stosując powyższe informacje można łatwo zaimplementować poniższy diagram UML wewnątrz przestrzeni nazw PJWSTK.

Rysunek 19. Diagram UML PJWSTK
W pierwszej kolejności należy przekazać polecenia do kompilatora i jeśli wymusić stworzenie instancji przestrzeni nazw PJWSTK
|
//wymuszenie aktualizacji
#pragma classflags("forceupdate")
//stworzenie przestrzeni nazw w głównej gałęzi
#pragma namespace ("\\\\.\\Root")
instance of __Namespace
{
Name = "PJWSTK";
};
|
Listing. Przykładowy MOF - cześć pierwsza
W następnej kolejności należy zdefiniować klasy z uwagą na umieszczenie klas dziedziczących pod definicją klasy rozszerzanej.
|
//użycie przestrzeni nazw PJWSTK
#pragma namespace("\\\\.\\ROOT\\PJWSTK")
//definicja klasy abstrakcujnej Osoba
[abstract: ToInstance ToSubClass]
class Osoba
{
string Imie;
string Nazwisko;
[key] string PESEL;
};
//definicja klasy Wykladowca rozszerzającej Osoba
[abstract(FALSE): ToInstance ToSubClass]
class Wykladowca : Osoba
{
string Login;
};
//definicja klasy Student rozszerzającej Osoba
[abstract(FALSE): ToInstance ToSubClass]
class Student : Osoba
{
string NrIndeksu;
};
//Definicja klasy asocjacyjnej łączącej Studenta i wykładowcę
[Association: ToInstance ToSubClass]
class Uczestnictwo
{
[key] Wykladowca ref Ascendant;
[key] Student ref Dependant;
string Zajecia;
};
|
Listing. Przykładowy MOF - część druga
I wreszcie pozostaje stworzenie instancji klas:
|
//stworzenie obiektów klasy Wykladowca
instance of Wykladowca
{
Imie = "Jozef";
Login = "JN";
Nazwisko = "Nowak";
PESEL = "999888";
};
instance of Wykladowca
{
Imie = "Daniel";
Login = "d0m3l";
Nazwisko = "Stefaniak";
PESEL = "888000";
};
//stworzenie obiektów klasy Student
instance of Student
{
Imie = "Michal";
Nazwisko = "Igrekowski";
NrIndeksu = "2222";
PESEL = "2222";
};
instance of Student
{
Imie = "Kuba";
Nazwisko = "Iksinski";
NrIndeksu = "1111";
PESEL = "1111";
};
//stworzenie powiązania pomiędzy wykładowcą a studentem
instance of Uczestnictwo
{
Ascendant = "\\\\FREYA\\ROOT\\PJWSTK:Wykladowca.PESEL=\"999888\"";
Dependant = "\\\\FREYA\\ROOT\\PJWSTK:Student.PESEL=\"2222\"";
Zajecia = "RBD";
};
|
Listing. Przykładowy MOF - część trzecia
Po połączeniu trzech części w jeden plik można go skompilować. Jednym ze sposobów jest użycie konsolowego polecenia mofcomp.exe. Wynik powinien być następujący:

Rysunek. Wynik kompilacji pliku MOF
Dodatkowo można zaobserwować nowe obiekty za pomocą CIM Studio.

Narzędzia
Warto zwrócić uwagę, że poza CIM Studio w rozwoju MOF czy typowych zastosowań jak rozszerzanie WMI lub ConfigMgr-a można wspierać się także narzędziami nie pochodzącymi z Microsoft:
Warto również zapoznać się z dotępnymi materiałami dotyczącymi wykorzystania MOF w System Center Configuration Manager: myITForum Wiki: SCCM 2007 Inventory.
Patrz też
WMI jako obiektowa baza danych: Wprowadzenie (1/6)
WMI jako obiektowa baza danych: Budowa WMI (2/6)
WMI jako obiektowa baza danych: narzędzia dostępu do danych (3/6)
WMI jako obiektowa baza danych: WQL (4/5) (publikacja 14. czerwca 2011)
WMI jako obiektowa baza danych: praktyczne zastosowanie WMI (5/6) (publikacja 16. czerwca 2011)
WMI jako obiektowa baza danych: pliki MOF (6/6) (publikacja 21. czerwca 2011)
Autor:
Daniel Stefaniak
(MVP, MCT, MCITP, MCTS, MCSA, MCP, CCNA)
Administrator, trener i inżynier systemowy. Członek SEClub oraz jeden z liderów Polskiej Grupy System Center. Aktywnie pisze na blogach http://www.w-files.pl oraz http://blogs.technet.com/plsc/.
MVP w kategorii Management Infrastructure