Bagikan melalui


Bab 7 - Bekerja dengan WMI

WMI dan CIM

Windows PowerShell dikirim secara default dengan cmdlet untuk bekerja dengan teknologi lain, seperti Windows Management Instrumentation (WMI). Cmdlet WMI tidak digunakan lagi dan tidak tersedia di PowerShell 6+, tetapi dibahas di sini karena Anda mungkin menemukannya dalam skrip lama yang berjalan di Windows PowerShell. Untuk pengembangan baru, gunakan cmdlet CIM sebagai gantinya.

Beberapa cmdlet WMI asli ada di PowerShell tanpa Anda harus menginstal perangkat lunak atau modul lain. Get-Command dapat digunakan untuk menentukan cmdlet WMI apa yang ada di Windows PowerShell. Hasil berikut berasal dari sistem Windows 11 yang menjalankan PowerShell versi 5.1. Hasil Anda mungkin berbeda tergantung pada versi PowerShell yang Anda jalankan.

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

Cmdlet Common Information Model (CIM) diperkenalkan di PowerShell 3.0 dan dikelompokkan dalam modul khusus. Untuk mencantumkan semua cmdlet CIM yang tersedia, gunakan Get-Command cmdlet dengan parameter Modul , seperti yang ditunjukkan dalam contoh berikut.

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

Cmdlet CIM masih memungkinkan Anda untuk bekerja dengan WMI, jadi jangan bingung ketika seseorang menyatakan: "Ketika saya mengkueri WMI dengan cmdlet POWERShell CIM".

Seperti yang disebutkan sebelumnya, WMI adalah teknologi terpisah dari PowerShell, dan Anda hanya menggunakan cmdlet CIM untuk mengakses WMI. Anda mungkin menemukan VBScript lama yang menggunakan WMI Query Language (WQL) untuk mengkueri WMI, seperti dalam contoh berikut.

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

Anda dapat mengambil kueri WQL dari VBScript dan menggunakannya dengan Get-CimInstance cmdlet tanpa modifikasi apa pun.

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

Contoh sebelumnya bukan bagaimana saya biasanya mengkueri WMI dengan PowerShell. Tetapi ini berfungsi dan memungkinkan Anda untuk dengan mudah memigrasikan skrip Visual Basic yang ada ke PowerShell. Saat menulis satu baris untuk mengkueri WMI, saya menggunakan sintaks berikut.

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

Jika Anda hanya menginginkan nomor seri, pipa output ke Select-Object dan tentukan hanya properti SerialNumber .

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

Secara default, saat mengkueri WMI, beberapa properti yang tidak pernah digunakan diambil di belakang layar. Tidak masalah banyak saat mengkueri WMI di komputer lokal. Tetapi setelah Anda mulai menjalankan kueri terhadap komputer jarak jauh, bukan hanya waktu pemrosesan tambahan diperlukan untuk mengembalikan informasi tersebut, tetapi juga lebih banyak informasi yang kurang diperlukan untuk dikirim di seluruh jaringan. Get-CimInstance memiliki parameter Properti yang membatasi informasi yang diambil, membuat kueri WMI lebih efisien.

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

Hasil sebelumnya mengembalikan sebuah objek. Untuk mengembalikan string, gunakan parameter ExpandProperty .

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

Anda juga dapat menggunakan gaya sintaks titik-titik untuk mengembalikan string, menghilangkan kebutuhan untuk mengalirkan ke Select-Object.

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

Mengkueri Komputer Jarak Jauh dengan cmdlet CIM

Anda masih harus menjalankan PowerShell sebagai admin lokal dan pengguna domain. Ketika Anda mencoba mengkueri informasi dari komputer jarak jauh menggunakan Get-CimInstance cmdlet, Anda menerima pesan kesalahan akses ditolak.

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:Stri
   ng) [Get-CimInstance], CimException
    + FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infra
   structure.CimCmdlets.GetCimInstanceCommand
    + PSComputerName        : dc01

Banyak orang memiliki masalah keamanan mengenai PowerShell, tetapi Anda memiliki izin yang sama di PowerShell seperti di GUI. Tidak lebih dan tidak kurang. Masalah dalam contoh sebelumnya adalah bahwa pengguna yang menjalankan PowerShell tidak memiliki hak untuk mengkueri informasi WMI dari server DC01. Anda dapat merilis kembali PowerShell sebagai administrator domain karena Get-CimInstance tidak memiliki parameter Kredensial . Tetapi itu bukan ide yang baik karena apa pun yang Anda jalankan dari PowerShell akan berjalan sebagai admin domain. Tergantung pada situasinya, skenario itu bisa berbahaya dari sudut siaga keamanan.

Menggunakan prinsip hak istimewa paling sedikit, tingkatkan ke akun admin domain Anda berdasarkan per perintah menggunakan parameter Kredensial jika perintah memilikinya. Get-CimInstance tidak memiliki parameter Kredensial , sehingga solusi dalam skenario ini adalah membuat CimSession terlebih dahulu. Kemudian, gunakan CimSession alih-alih nama komputer untuk mengkueri WMI di komputer jarak jauh.

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

Sesi CIM disimpan dalam variabel bernama $CimSession. Perhatikan bahwa Anda juga menentukan Get-Credential cmdlet dalam tanda kurung sehingga dijalankan terlebih dahulu, meminta kredensial alternatif, sebelum membuat sesi baru. Saya menunjukkan cara lain yang lebih efisien untuk menentukan kredensial alternatif nanti dalam bab ini, tetapi penting untuk memahami konsep dasar ini sebelum membuatnya lebih rumit.

Anda sekarang dapat menggunakan sesi CIM yang dibuat dalam contoh sebelumnya dengan Get-CimInstance cmdlet untuk mengkueri informasi BIOS dari WMI di komputer jarak jauh.

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

Ada beberapa manfaat lain untuk menggunakan sesi CIM alih-alih hanya menentukan nama komputer. Saat Anda menjalankan beberapa kueri ke komputer yang sama, menggunakan sesi CIM lebih efisien daripada menggunakan nama komputer untuk setiap kueri. Membuat sesi CIM hanya membuat koneksi sekali. Kemudian, beberapa kueri menggunakan sesi yang sama untuk mengambil informasi. Menggunakan nama komputer memerlukan cmdlet untuk menyiapkan dan memutuskan koneksi dengan setiap kueri.

Get-CimInstance Cmdlet menggunakan protokol WSMan secara default, yang berarti komputer jarak jauh membutuhkan PowerShell versi 3.0 atau yang lebih tinggi untuk terhubung. Sebenarnya bukan versi PowerShell yang penting, ini adalah versi tumpukan. Versi stack dapat ditentukan menggunakan cmdlet Test-WSMan. Ini harus versi 3.0, yang Anda temukan dengan PowerShell versi 3.0 dan yang lebih tinggi.

Test-WSMan -ComputerName dc01
wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentit
                  y.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

Cmdlet WMI yang lebih lama menggunakan protokol DCOM, yang kompatibel dengan versi Windows yang lebih lama. Namun, firewall biasanya memblokir DCOM pada versi Windows yang lebih baru. New-CimSessionOption cmdlet memungkinkan Anda membuat koneksi protokol DCOM untuk digunakan dengan New-CimSession. Opsi ini memungkinkan Get-CimInstance cmdlet untuk berkomunikasi dengan versi Windows setingkat Windows Server 2000. Kemampuan ini juga berarti bahwa PowerShell tidak diperlukan di komputer jarak jauh saat menggunakan Get-CimInstance cmdlet dengan CimSession yang dikonfigurasi untuk menggunakan protokol DCOM.

Buat opsi protokol DCOM menggunakan New-CimSessionOption cmdlet dan simpan dalam variabel.

$DCOM = New-CimSessionOption -Protocol Dcom

Untuk efisiensi, Anda dapat menyimpan administrator domain atau kredensial yang ditinggikan dalam variabel sehingga Anda tidak perlu terus-menerus memasukkannya untuk setiap perintah.

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

Saya memiliki server bernama SQL03 yang menjalankan Windows Server 2008 (non-R2). Ini adalah sistem operasi Windows Server terbaru yang tidak menginstal PowerShell secara default.

Buat CimSession ke SQL03 menggunakan protokol DCOM.

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

Perhatikan di perintah sebelumnya bahwa Anda menentukan variabel bernama $Cred sebagai nilai untuk parameter Kredensial alih-alih memasukkan kredensial Anda lagi secara manual.

Hasil kueri sama terlepas dari protokol yang mendasar.

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

Cmdlet Get-CimSession digunakan untuk melihat CimSessions mana yang saat ini terhubung dan protokol apa yang digunakan.

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

Ambil dan simpan CimSessions yang dibuat sebelumnya dalam variabel bernama $CimSession.

$CimSession = Get-CimSession

Kueri kedua komputer dengan satu perintah, satu menggunakan protokol WSMan dan yang lainnya dengan 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

Salah satu artikel blog saya di cmdlet WMI dan CIM menampilkan fungsi PowerShell yang secara otomatis mendeteksi apakah akan menggunakan WSMan atau DCOM dan kemudian menyiapkan sesi CIM yang sesuai untuk Anda. Untuk informasi selengkapnya, lihat Fungsi PowerShell untuk Membuat CimSessions ke Komputer Jarak Jauh dengan Fallback ke DCOM.

Ketika Anda selesai dengan sesi CIM, hapus sesi tersebut menggunakan cmdlet Remove-CimSession. Untuk menghapus semua sesi CIM, arahkan Get-CimSession ke Remove-CimSession.

Get-CimSession | Remove-CimSession

Ringkasan

Dalam bab ini, Anda belajar tentang menggunakan PowerShell untuk bekerja dengan WMI di komputer lokal dan jarak jauh. Anda juga mempelajari cara menggunakan cmdlet CIM untuk bekerja dengan komputer jarak jauh menggunakan protokol WSMan dan DCOM.

Tinjauan

  1. Apa perbedaan dalam cmdlet WMI dan CIM?
  2. Cmdlet Get-CimInstance menggunakan protokol apa secara default?
  3. Apa saja manfaat menggunakan sesi CIM alih-alih menentukan nama komputer dengan Get-CimInstance?
  4. Bagaimana Anda menentukan protokol alternatif selain protokol default untuk digunakan dengan Get-CimInstance?
  5. Bagaimana Anda menutup atau menghapus sesi CIM?

Referensi