Rozdział 7 — Praca z usługą WMI

WMI i CIM

Program Windows PowerShell jest domyślnie dostarczany z poleceniami cmdlet do pracy z innymi technologiami, takimi jak Instrumentacja zarządzania Windows (WMI). Polecenia cmdlet usługi WMI są przestarzałe i nie są dostępne w programie PowerShell 6 lub nowszym, ale są tu omówione, ponieważ mogą wystąpić w starszych skryptach uruchomionych w programie Windows PowerShell. W przypadku nowego programowania należy zamiast tego użyć poleceń cmdlet modelu CIM.

Istnieje kilka natywnych poleceń cmdlet usługi WMI, które istnieją w programie PowerShell bez konieczności instalowania dodatkowego oprogramowania lub modułów. Get-Command umożliwia określenie, jakie polecenia cmdlet usługi WMI istnieją w programie Windows PowerShell. Poniższe wyniki pochodzą z komputera środowiska laboratoryjnego systemu Windows 10 z uruchomionym programem PowerShell w wersji 5.1. Wyniki mogą się różnić w zależności od używanej wersji programu PowerShell.

Get-Command -Noun WMI*
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Get-WmiObject                                      3.1.0.0    Microsof...
Cmdlet          Invoke-WmiMethod                                   3.1.0.0    Microsof...
Cmdlet          Register-WmiEvent                                  3.1.0.0    Microsof...
Cmdlet          Remove-WmiObject                                   3.1.0.0    Microsof...
Cmdlet          Set-WmiInstance                                    3.1.0.0    Microsof...

Polecenia cmdlet modelu wspólnych informacji (CIM) zostały wprowadzone w programie PowerShell w wersji 3.0. Polecenia cmdlet modelu ciM zostały zaprojektowane tak, aby mogły być używane zarówno na maszynach z systemem Windows, jak i innych niż Windows.

Polecenia cmdlet modelu CIM są zawarte w module. Aby uzyskać listę poleceń cmdlet modelu CIM, użyj parametru Get-Commandmodule , jak pokazano w poniższym przykładzie.

Get-Command -Module CimCmdlets
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Export-BinaryMiLog                                 1.0.0.0    CimCmdlets
Cmdlet          Get-CimAssociatedInstance                          1.0.0.0    CimCmdlets
Cmdlet          Get-CimClass                                       1.0.0.0    CimCmdlets
Cmdlet          Get-CimInstance                                    1.0.0.0    CimCmdlets
Cmdlet          Get-CimSession                                     1.0.0.0    CimCmdlets
Cmdlet          Import-BinaryMiLog                                 1.0.0.0    CimCmdlets
Cmdlet          Invoke-CimMethod                                   1.0.0.0    CimCmdlets
Cmdlet          New-CimInstance                                    1.0.0.0    CimCmdlets
Cmdlet          New-CimSession                                     1.0.0.0    CimCmdlets
Cmdlet          New-CimSessionOption                               1.0.0.0    CimCmdlets
Cmdlet          Register-CimIndicationEvent                        1.0.0.0    CimCmdlets
Cmdlet          Remove-CimInstance                                 1.0.0.0    CimCmdlets
Cmdlet          Remove-CimSession                                  1.0.0.0    CimCmdlets
Cmdlet          Set-CimInstance                                    1.0.0.0    CimCmdlets

Polecenia cmdlet modelu CIM nadal umożliwiają pracę z usługą WMI, więc nie należy mylić, gdy ktoś składa instrukcję "Kiedy wysyłam zapytanie do usługi WMI za pomocą poleceń cmdlet CIM programu PowerShell..."

Jak wspomniano wcześniej, usługa WMI jest oddzielną technologią programu PowerShell i używasz poleceń cmdlet modelu CIM do uzyskiwania dostępu do usługi WMI. Możesz znaleźć stary skrypt VBScript, który używa języka WMI Query Language (WQL) do wykonywania zapytań w usłudze WMI, takich jak w poniższym przykładzie.

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colBIOS = objWMIService.ExecQuery _
    ("Select * from Win32_BIOS")

For each objBIOS in colBIOS
    Wscript.Echo "Manufacturer: " & objBIOS.Manufacturer
    Wscript.Echo "Name: " & objBIOS.Name
    Wscript.Echo "Serial Number: " & objBIOS.SerialNumber
    Wscript.Echo "SMBIOS Version: " & objBIOS.SMBIOSBIOSVersion
    Wscript.Echo "Version: " & objBIOS.Version
Next

Możesz pobrać zapytanie WQL z tego skryptu VBScript i użyć go z Get-CimInstance poleceniem cmdlet bez żadnych modyfikacji.

Get-CimInstance -Query 'Select * from Win32_BIOS'
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 3810-1995-1654-4615-2295-2755-89
Version           : VRTUAL - 4001628

Nie w ten sposób zwykle wysyłam zapytania do usługi WMI przy użyciu programu PowerShell. Jednak działa i umożliwia łatwą migrację istniejących skryptów VBScript do programu PowerShell. Kiedy zaczynam pisać jeden wiersz do wykonywania zapytań w usłudze WMI, używam następującej składni.

Get-CimInstance -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 3810-1995-1654-4615-2295-2755-89
Version           : VRTUAL - 4001628

Jeśli chcę tylko numer seryjny, mogę przekazać dane wyjściowe do Select-Object i określić tylko właściwość SerialNumber .

Get-CimInstance -ClassName Win32_BIOS | Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89

Domyślnie istnieje kilka właściwości, które są pobierane w tle, które nigdy nie są używane. Wykonywanie zapytań w usłudze WMI na komputerze lokalnym może nie mieć znaczenia. Jednak po rozpoczęciu wykonywania zapytań dotyczących komputerów zdalnych nie tylko dodatkowy czas przetwarzania zwraca te informacje, ale także dodatkowe niepotrzebne informacje, które muszą być pobierane przez sieć. Get-CimInstancema parametr Property, który ogranicza pobierane informacje. Dzięki temu zapytanie do usługi WMI jest bardziej wydajne.

Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89

Poprzednie wyniki zwróciły obiekt. Aby zwrócić prosty ciąg, użyj parametru ExpandProperty .

Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -ExpandProperty SerialNumber
3810-1995-1654-4615-2295-2755-89

Możesz również użyć stylu kropkowanego składni, aby zwrócić prosty ciąg. Eliminuje to konieczność potoku do .Select-Object

(Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber).SerialNumber
3810-1995-1654-4615-2295-2755-89

Wykonywanie zapytań dotyczących komputerów zdalnych za pomocą poleceń cmdlet modelu CIM

Nadal używam programu PowerShell jako administrator lokalny, który jest użytkownikiem domeny. Podczas próby wykonywania zapytań dotyczących informacji z komputera zdalnego przy użyciu Get-CimInstance polecenia cmdlet otrzymuję komunikat o błędzie odmowy dostępu.

Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
Get-CimInstance : Access is denied.
At line:1 char:1
+ Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (root\cimv2:Win32_BIOS:String) [Get-CimI
   nstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infrastructure.Cim
   Cmdlets.GetCimInstanceCommand
    + PSComputerName        : dc01

Wiele osób ma obawy dotyczące zabezpieczeń, jeśli chodzi o program PowerShell, ale prawda jest taka, że masz dokładnie te same uprawnienia w programie PowerShell, co w graficznym interfejsie użytkownika. Dopasowanie jest dokładne. Problem w poprzednim przykładzie polega na tym, że użytkownik z uruchomionym programem PowerShell nie ma uprawnień do wykonywania zapytań dotyczących informacji usługi WMI z serwera DC01. Mogę ponownie użyć programu PowerShell jako administratora domeny, ponieważ Get-CimInstance nie ma parametru Credential . Ale zaufaj mi, że nie jest to dobry pomysł, ponieważ wtedy wszystko, co uruchamiam z programu PowerShell, będzie działać jako administrator domeny. Może to być niebezpieczne z punktu widzenia bezpieczeństwa w zależności od sytuacji.

Używając zasady najniższych uprawnień, podnieśę poziom do konta administratora domeny na podstawie polecenia przy użyciu parametru Credential , jeśli polecenie ma jeden. Get-CimInstance nie ma parametru Credential , więc rozwiązanie w tym scenariuszu polega na utworzeniu najpierw cimSession . Następnie używam cimSession zamiast nazwy komputera do wykonywania zapytań WMI na komputerze zdalnym.

$CimSession = New-CimSession -ComputerName dc01 -Credential (Get-Credential)
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential

Sesja modelu CIM była przechowywana w zmiennej o nazwie $CimSession. Zwróć uwagę, że określono Get-Credential również polecenie cmdlet w nawiasach, tak aby było wykonywane najpierw, monitując mnie o alternatywne poświadczenia przed utworzeniem nowej sesji. Pokażę ci kolejny bardziej wydajny sposób określania alternatywnych poświadczeń w dalszej części tego rozdziału, ale ważne jest, aby zrozumieć tę podstawową koncepcję przed jej bardziej skomplikowanym rozwiązaniem.

Sesja modelu CIM utworzona w poprzednim przykładzie może być teraz używana z Get-CimInstance poleceniem cmdlet do wykonywania zapytań dotyczących informacji systemu BIOS z usługi WMI na komputerze zdalnym.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 0986-6980-3916-0512-6608-8243-13
Version           : VRTUAL - 4001628
PSComputerName    : dc01

Istnieje kilka dodatkowych korzyści związanych z używaniem sesji modelu CIM zamiast po prostu określania nazwy komputera. W przypadku uruchamiania wielu zapytań na tym samym komputerze użycie sesji ciągłej integracji jest bardziej wydajne niż użycie nazwy komputera dla każdego zapytania. Utworzenie sesji modelu ciM powoduje skonfigurowanie połączenia tylko raz. Następnie wiele zapytań używa tej samej sesji do pobierania informacji. Użycie nazwy komputera wymaga, aby polecenia cmdlet skonfigurować i usunąć połączenie z poszczególnymi zapytaniami.

Polecenie Get-CimInstance cmdlet domyślnie używa protokołu WSMan, co oznacza, że do nawiązania połączenia komputer zdalny wymaga programu PowerShell w wersji 3.0 lub nowszej. W rzeczywistości nie jest to wersja programu PowerShell, która ma znaczenie, jest to wersja stosu. Wersję stosu Test-WSMan można określić za pomocą polecenia cmdlet . Musi być w wersji 3.0. Jest to wersja programu PowerShell w wersji 3.0 lub nowszej.

Test-WSMan -ComputerName dc01
wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

Starsze polecenia cmdlet usługi WMI używają protokołu DCOM, który jest zgodny ze starszymi wersjami systemu Windows. Jednak model DCOM jest zwykle blokowany przez zaporę w nowszych wersjach systemu Windows. Polecenie New-CimSessionOption cmdlet umożliwia utworzenie połączenia protokołu DCOM do użycia z New-CimSessionprogramem . Get-CimInstance Dzięki temu polecenie cmdlet może być używane do komunikowania się z wersjami systemu Windows tak starym jak Windows Server 2000. Oznacza to również, że program PowerShell nie jest wymagany na komputerze zdalnym podczas korzystania z Get-CimInstance polecenia cmdlet z cimSession skonfigurowanym do korzystania z protokołu DCOM.

Utwórz opcję protokołu DCOM przy użyciu New-CimSessionOption polecenia cmdlet i zapisz go w zmiennej.

$DCOM = New-CimSessionOption -Protocol Dcom

W celu zwiększenia wydajności można przechowywać poświadczeń administratora domeny lub poświadczeń z podwyższonym poziomem uprawnień w zmiennej, aby nie trzeba było stale wprowadzać ich dla każdego polecenia.

$Cred = Get-Credential
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential

Mam serwer o nazwie SQL03 z systemem Windows Server 2008 (inne niż R2). Jest to najnowszy system operacyjny Windows Server, który domyślnie nie ma zainstalowanego programu PowerShell.

Utwórz cimSession do usługi SQL03 przy użyciu protokołu DCOM.

$CimSession = New-CimSession -ComputerName sql03 -SessionOption $DCOM -Credential $Cred

Zwróć uwagę, że w poprzednim poleceniu tym razem określono zmienną o nazwie $Cred jako wartość parametru Credential zamiast wprowadzać je ręcznie.

Dane wyjściowe zapytania są takie same niezależnie od używanego protokołu bazowego.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 7237-7483-8873-8926-7271-5004-86
Version           : VRTUAL - 4001628
PSComputerName    : sql03

Polecenie Get-CimSession cmdlet służy do sprawdzenia, jakie są obecnie połączone cimSessions i jakich protokołów używają.

Get-CimSession
Id           : 1
Name         : CimSession1
InstanceId   : 80742787-e38e-41b1-a7d7-fa1369cf1402
ComputerName : dc01
Protocol     : WSMAN

Id           : 2
Name         : CimSession2
InstanceId   : 8fcabd81-43cf-4682-bd53-ccce1e24aecb
ComputerName : sql03
Protocol     : DCOM

Pobierz i zapisz oba utworzone wcześniej cimSessions w zmiennej o nazwie $CimSession.

$CimSession = Get-CimSession

Wykonaj zapytanie względem obu komputerów za pomocą jednego polecenia, jedno przy użyciu protokołu WSMan i drugiego z dcOM.

Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 0986-6980-3916-0512-6608-8243-13
Version           : VRTUAL - 4001628
PSComputerName    : dc01

SMBIOSBIOSVersion : 090006
Manufacturer      : American Megatrends Inc.
Name              : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber      : 7237-7483-8873-8926-7271-5004-86
Version           : VRTUAL - 4001628
PSComputerName    : sql03

Napisałem wiele artykułów w blogu dotyczących poleceń cmdlet WMI i CIM. Jedną z najbardziej przydatnych jest funkcja, która została utworzona w celu automatycznego określenia, czy WSMan lub DCOM powinny być używane i konfigurować sesję modelu CIM automatycznie bez konieczności ustalenia, który z nich ręcznie. Ten artykuł w blogu jest zatytułowany PowerShell Function to Create CimSessions to Remote Computers with Fallback to Dcom (Funkcja programu PowerShell do tworzenia cimSessions na komputerach zdalnych z rezerwą do dcom).

Po zakończeniu pracy z sesjami modelu CIM należy je usunąć za pomocą Remove-CimSession polecenia cmdlet . Aby usunąć wszystkie sesje modelu CIM, wystarczy przekazać potok Get-CimSession do Remove-CimSessionelementu .

Get-CimSession | Remove-CimSession

Podsumowanie

W tym rozdziale przedstawiono sposób korzystania z programu PowerShell do pracy z usługą WMI na komputerach lokalnych i zdalnych. Wiesz również, jak używać poleceń cmdlet modelu CIM do pracy z komputerami zdalnymi z protokołem WSMan lub DCOM.

Wykonaj przegląd

  1. Jaka jest różnica w poleceniach cmdlet WMI i CIM?
  2. Domyślnie jakiego protokołu Get-CimInstance używa polecenie cmdlet?
  3. Jakie są niektóre korzyści wynikające z używania sesji modelu ciM zamiast określania nazwy komputera za pomocą Get-CimInstancepolecenia ?
  4. Jak określić alternatywny protokół inny niż domyślny do użycia z Get-CimInstanceprogramem ?
  5. Jak zamknąć lub usunąć sesje modelu CIM?