C# और PowerShell से WMI/CIM का उपयोग — हार्डवेयर जानकारी, प्रोसेस निगरानी और रिमोट क्वेरी की व्यावहारिक मार्गदर्शिका
· Go Komura · Windows, C#, .NET, PowerShell, WMI, CIM, व्यावसायिक ऐप, Windows विकास
«PC का सीरियल नंबर और मॉडल नाम व्यावसायिक ऐप की स्क्रीन पर दिखाना है।» «सर्वर के डिस्क खाली स्थान की निगरानी कर चेतावनी देनी है।» «किसी खास प्रोसेस के शुरू होने का पता लगाना है।» «दूर बैठे PC की अवस्था एक जगह क्वेरी करनी है।» — Windows के व्यावसायिक ऐप और प्रबंधन उपकरणों के निर्माण में ये ज़रूरतें बार-बार आती हैं। और उनका आम उत्तर WMI (Windows Management Instrumentation) है, या मानक नाम से CIM (Common Information Model)।
flowchart TB
accTitle: आम ज़रूरतें और WMI/CIM
accDescr: सीरियल नंबर और मॉडल नाम दिखाना, डिस्क खाली स्थान की निगरानी, प्रोसेस शुरू होने का पता, रिमोट PC की क्वेरी जैसी व्यावसायिक ऐप की आम ज़रूरतों का आम उत्तर WMI है, और मानक नाम से CIM
r1["सीरियल नंबर・मॉडल नाम"] --> ans["WMI(मानक नाम CIM)"]
r2["डिस्क खाली स्थान की निगरानी"] --> ans
r3["प्रोसेस शुरू होने का पता"] --> ans
r4["रिमोट PC की क्वेरी"] --> ans
चित्र 1: व्यावसायिक ऐप की चार आम ज़रूरतों का आम उत्तर WMI/CIM है।
कठिनाई यह है कि WMI की जानकारी पुरानी और नई मिली-जुली है। खोजें तो Get-WmiObject वाले दस वर्ष पुराने लेख Get-CimInstance वाले लेखों के साथ बैठे मिलते हैं, और C# पक्ष पर System.Management तथा Microsoft.Management.Infrastructure दो वंश हैं। कौन वर्तमान लिखने का तरीका है और कौन «अभी चलता है पर नए कोड के लिए नहीं चुनना» — यह साफ नहीं। वास्तव में Get-WmiObject PowerShell 7 में है ही नहीं, और 5.1 के लिए लिखा आंतरिक स्क्रिप्ट माइग्रेट करते यह अचानक सतह पर आता है।
यह लेख उन C#/PowerShell डेवलपरों के लिए है जो व्यावसायिक ऐप में हार्डवेयर जानकारी प्राप्ति, प्रोसेस निगरानी और रिमोट PC क्वेरी लागू करते हैं। WMI/CIM की संरचना की न्यूनतम समझ से PowerShell के CIM कमांडलेट, C# के दो API, अक्सर काम आने वाली रेसिपी, प्रदर्शन・अधिकार・64bit के जाल, और अंत में «जहाँ WMI उपयोग नहीं करना चाहिए» का निर्णय — अगस्त 2026 तक के प्राथमिक स्रोतों पर व्यवस्थित है।
1. पहले निष्कर्ष
- CIM DMTF का प्रबंधन जानकारी का उद्योग मानक है, और WMI उसका Microsoft कार्यान्वयन। PowerShell और C# के CIM-परिवार API इस मानक के वर्तमान पीढ़ी के API हैं, और जुड़ते वही अंतर्निहित WMI से हैं।1
- PowerShell में वर्तमान पीढ़ी CIM कमांडलेट हैं (Get-CimInstance / Invoke-CimMethod / Register-CimIndicationEvent)। पुराने WMI कमांडलेट (Get-WmiObject और चार अन्य) PowerShell 6 से हटा दिए गए हैं और PowerShell 7 में नहीं चलते।2
- डिफ़ॉल्ट नेमस्पेस root/CIMV2 है, और रोज़ की क्वेरी मूलतः वहाँ की Win32_* क्लास को WQL से छानना है।3
- रिमोट क्वेरी का डिफ़ॉल्ट WSMan (WinRM) है।
-ComputerNameदेने से अस्थायी WSMan सत्र बनता है। उसी लक्ष्य पर बार-बार क्वेरी करें तो CIM सत्र (New-CimSession) का पुनः उपयोग प्रदर्शन का स्थापित तरीका है, और पुराने लक्ष्य जहाँ WinRM कॉन्फ़िगर न हो वहाँ DCOM प्रोटोकॉल विकल्प है।34 - C# में दो वंश हैं: System.Management (ManagementObjectSearcher) और Microsoft.Management.Infrastructure (CimSession)। दोनों केवल Windows हैं, और वर्तमान .NET पर NuGet से आते हैं। रिमोट क्वेरी या निगरानी को उत्पाद में जोड़ रहे हों तो CIM कमांडलेट जैसा प्रकार तंत्र रखने वाला MI API बेहतर बैठता है।56
- प्रोसेस शुरू होने का पता इवेंट सदस्यता से लगाएँ, पोलिंग से नहीं।
Win32_ProcessStartTraceकी सदस्यता व्यवस्थापक अधिकार से चलानी होती है।78 SELECT *आदत से न लिखें।-Filter/-Property/-KeyOnlyसे स्थानांतरित डेटा छानना WMI के प्रदर्शन मुद्दों का लगभग आधा रोकता है।3- WMI सार्वभौमिक हल नहीं। उच्च-आवृत्ति प्रदर्शन निगरानी, अपने ऐप की सेटिंग पढ़ना-लिखना, या एकमुश्त OS फ़ंक्शन कॉल के लिए प्रदर्शन काउंटर, रजिस्ट्री, Win32 API, या समर्पित कमांडलेट बेहतर बैठते हैं (अध्याय 8 की निर्णय तालिका)।
2. WMI/CIM क्या है — मानक बनाम कार्यान्वयन, नेमस्पेस, क्लास और WQL
पहले शब्दावली एक बार साफ कर लें।
| शब्द | वह क्या है |
|---|---|
| CIM (Common Information Model) | सिस्टम, ऐप, नेटवर्क और डिवाइस जैसे प्रबंधन लक्ष्यों को व्यक्त करने वाला उद्योग-मानक मॉडल। DMTF (Distributed Management Task Force) तय और रखता है1 |
| WBEM (Web-Based Enterprise Management) | उद्यम परिवेश में प्रबंधन जानकारी तक पहुँच की मानक तकनीक बनाने की उद्योग पहल1 |
| WMI | WBEM का Microsoft कार्यान्वयन। CIM मानक से प्रबंधन लक्ष्य व्यक्त करता है और Windows में बना होता है1 |
| MI (Windows Management Infrastructure) | WMI की अगली पीढ़ी। पुराने WMI से पूर्ण संगत, और नए प्रदाता अधिकतर MI में लिखे जाते हैं1 |
flowchart TB
accTitle: CIM मानक और WMI कार्यान्वयन का संबंध
accDescr: DMTF तय और रखे CIM मानक को WBEM पहल के ढाँचे में उपयोग करते हैं, उसका Microsoft कार्यान्वयन WMI है, अगली पीढ़ी MI पुराने WMI से पूर्ण संगत है, और CIM-परिवार API उसी WMI आधार से जुड़ते हैं
dmtf["DMTF तय और रखता है"] --> cim["CIM(उद्योग मानक मॉडल)"]
wbem["WBEM(उद्योग पहल)"] --> wmi["WMI(Microsoft कार्यान्वयन)"]
cim --> wmi
wmi -.-> mi["MI(अगली पीढ़ी・पूर्ण संगत)"]
api["CIM-परिवार API(PowerShell / C#)"] --> wmi
चित्र 2: CIM विनिर्देश है, WMI Windows पर कार्यान्वयन। CIM-परिवार API उसी WMI आधार से जुड़ते हैं।
डेवलपर के रूप में चार संरचनात्मक टुकड़े समझने लायक हैं।
- नेमस्पेस (namespace): क्लास बाँधने वाला पदानुक्रम। रोज़ की क्वेरी में लगभग हमेशा root/CIMV2 उपयोग होता है, और CIM कमांडलेट का डिफ़ॉल्ट भी यही है।3 अन्य में
root\default(रजिस्ट्री प्रदाता आदि) है। - क्लास: प्रबंधन लक्ष्य का प्रकार, जैसे
Win32_ComputerSystem(कंप्यूटर स्वयं),Win32_LogicalDisk(तार्किक ड्राइव), याWin32_Process(प्रोसेस)। CIM-मानक क्लास (CIM_LogicalDiskआदि) से विरासत लेने वाली Windows-विशिष्ट क्लासWin32_उपसर्ग रखती हैं।9 - प्रदाता: वह घटक जो क्लास का पदार्थ देता है। क्वेरी करने पर प्रदाता वहीं OS से पूछकर मान बनाता है।
- WQL: SQL-जैसी क्वेरी भाषा।
SELECT Name, State FROM Win32_Service WHERE StartMode = 'Auto'की तरह क्लास को तालिका मानकर छानती है। CIM कमांडलेट की डिफ़ॉल्ट क्वेरी भाषा भी WQL है।3
«OS और हार्डवेयर की जानकारी एक समान क्लास और क्वेरी भाषा से पढ़ना» — यही WMI का मूल्य है। उलटा, लिखना और संचालन उन कुछ क्लास तक सीमित है जिनके मेथड Invoke-CimMethod से बुलाए जा सकें; यह ऐसा तंत्र नहीं जो सब कुछ कर सके।
flowchart TB
accTitle: WMI क्वेरी की संरचना
accDescr: WQL क्वेरी नेमस्पेस root/CIMV2 की Win32_* क्लास की ओर जाती है, क्लास का पदार्थ देने वाला प्रदाता वहीं OS से पूछकर मान बनाता है, और परिणाम लौटता है
wql["WQL से क्वेरी"] --> ns["नेमस्पेस root/CIMV2"]
ns --> cls["Win32_* क्लास"]
cls --> prov["प्रदाता"]
prov --> osq["वहीं OS से पूछता है"]
osq --> res["परिणाम लौटाता है"]
चित्र 3: क्वेरी नेमस्पेस, क्लास, प्रदाता के क्रम से चलती है, और मान वहीं बनते हैं।
3. PowerShell से उपयोग — CIM कमांडलेट वर्तमान हैं, WMI कमांडलेट हटाए गए हैं
3.1. मूल बात: Get-CimInstance
# क्लास नाम से (डिफ़ॉल्ट नेमस्पेस root/CIMV2)
Get-CimInstance -ClassName Win32_OperatingSystem
# WHERE खंड की सामग्री ही -Filter में लिखें (WHERE शब्द स्वयं न लिखें)
Get-CimInstance -ClassName Win32_Service -Filter "StartMode = 'Auto' AND State <> 'Running'"
# केवल आवश्यक गुण लेकर स्थानांतरित मात्रा घटाएँ
Get-CimInstance -ClassName Win32_Process -Property Name, ProcessId, CreationDate
# कच्चा WQL लिखना हो तो -Query
Get-CimInstance -Query "SELECT * FROM Win32_Process WHERE Name LIKE 'p%'"
-Filter ठीक WQL का WHERE खंड है, और -Property प्राप्त स्तंभ सीमित करता है।3 लौटा मान CimInstance ऑब्जेक्ट है, और तिथि गुण (CreationDate या LastBootUpTime आदि) पहले से DateTime में परिवर्तित लौटते हैं। पुराने Get-WmiObject से भिन्न, प्राप्त ऑब्जेक्ट पर मेथड सीधे नहीं होते, इसलिए मेथड कॉल Invoke-CimMethod को पाइप करके करते हैं।
flowchart TB
accTitle: CimInstance पर मेथड कॉल
accDescr: Get-CimInstance का CimInstance तिथि गुण DateTime में परिवर्तित लौटाता है पर मेथड सीधे नहीं रखता, इसलिए मेथड कॉल इंस्टेंस को Invoke-CimMethod को देकर करते हैं
gci["Get-CimInstance"] --> inst["CimInstance ऑब्जेक्ट"]
inst -.-> dt["तिथियाँ DateTime में परिवर्तित"]
inst -.-> nom["मेथड सीधे नहीं होते"]
inst --> icm["Invoke-CimMethod को दें"]
icm --> call["मेथड कॉल"]
चित्र 4: CimInstance पर मेथड सीधे नहीं होते, इसलिए मेथड कॉल Invoke-CimMethod को देकर करते हैं।
# इंस्टेंस के मेथड बुलाना: प्रत्येक प्रोसेस का स्वामी प्राप्त करें
Get-CimInstance -ClassName Win32_Process -Filter "Name = 'notepad.exe'" |
Invoke-CimMethod -MethodName GetOwner
# क्लास का स्थैतिक मेथड बुलाना: प्रोसेस शुरू करें
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = 'notepad.exe' }
# क्लास परिभाषा जाँचें (गुण और मेथड)
Get-CimClass -ClassName Win32_Process
3.2. पुराने WMI कमांडलेट से माइग्रेशन तालिका
PowerShell 6 से आगे (वर्तमान PowerShell 7 सहित) निम्न WMI v1 कमांडलेट हटा दिए गए हैं। वही कार्य CimCmdlets मॉड्यूल (WMI v2) देता है।2
| पुराना (Windows PowerShell 5.1 तक) | वर्तमान (CIM कमांडलेट) | नोट |
|---|---|---|
Get-WmiObject |
Get-CimInstance |
-Filter / -Query की अवधारणा वही है |
Get-WmiObject -List |
Get-CimClass |
क्लास परिभाषा खोजना और जाँचना |
Invoke-WmiMethod |
Invoke-CimMethod |
तर्क -Arguments @{ } हैशटेबल से दिए जाते हैं |
Register-WmiEvent |
Register-CimIndicationEvent |
इवेंट सदस्यता (अध्याय 6.3) |
Set-WmiInstance |
Set-CimInstance |
लिखने योग्य गुण बदलना |
Remove-WmiObject |
Remove-CimInstance |
इंस्टेंस हटाना |
Windows PowerShell 5.1 पर भी CIM कमांडलेट चलते हैं, इसलिए अब जो लिखें, 5.1 पर चलाना हो तब भी CIM पक्ष पर लिखें — इससे माइग्रेशन लागत पीछे नहीं रहती। 5.1 और 7 के सह-अस्तित्व व माइग्रेशन का पूरा चित्र «Windows PowerShell 5.1 और PowerShell 7 के अंतर» में है।
flowchart TB
accTitle: नया स्क्रिप्ट CIM में लिखने का कारण
accDescr: WMI कमांडलेट से लिखा स्क्रिप्ट 5.1 पर चलता है पर PowerShell 6 से हटाया जा चुका है इसलिए माइग्रेशन पर दोबारा लिखना पड़ता है, CIM कमांडलेट 5.1 पर भी चलते हैं इसलिए नया CIM पक्ष पर लिखें तो माइग्रेशन लागत नहीं रहती
new["नया स्क्रिप्ट लिख रहे हैं"] --> q1{"किसमें लिखें?"}
q1 -->|WMI कमांडलेट| old["5.1 पर चलता है"]
q1 -->|CIM कमांडलेट| cur["5.1 पर भी चलता है"]
old --> del["PowerShell 7 में हटाए गए"]
del --> rew["माइग्रेशन पर दोबारा लिखना"]
cur --> norew["माइग्रेशन लागत नहीं रहती"]
चित्र 5: नया CIM कमांडलेट से लिखें तो PowerShell 7 माइग्रेशन पर दोबारा लिखना नहीं पड़ता।
4. रिमोट क्वेरी — CIM सत्र (डिफ़ॉल्ट WSMan) और DCOM विकल्प
CIM कमांडलेट, लक्ष्य न दें तो स्थानीय WMI से COM पर जुड़ते हैं; -ComputerName दें तो WSMan (WinRM) प्रोटोकॉल पर अस्थायी सत्र बनाकर जुड़ते हैं। उसी कंप्यूटर पर कई ऑपरेशन करने हों तो CIM सत्र बनाकर उसका पुनः उपयोग प्रदर्शन के लिए बेहतर है।3
flowchart TB
accTitle: CIM कनेक्शन तरीके का चुनाव
accDescr: निर्दिष्ट न हो तो स्थानीय WMI से COM कनेक्शन, ComputerName देने पर हर क्वेरी पर WSMan अस्थायी सत्र बनता है, उसी लक्ष्य पर कई ऑपरेशन के लिए New-CimSession का पुनः उपयोग प्रदर्शन में लाभदायक है, और WinRM बिना लक्ष्य के लिए DCOM प्रोटोकॉल विकल्प है
exec["CIM कमांडलेट चलाएँ"] --> q1{"ComputerName दिया?"}
q1 -->|नहीं| local["स्थानीय WMI से COM कनेक्शन"]
q1 -->|हाँ| q2{"उसी लक्ष्य पर कई ऑपरेशन?"}
q2 -->|एक बार| temp["WSMan अस्थायी सत्र"]
q2 -->|कई| sess["New-CimSession पुनः उपयोग"]
temp -.-> cost["हर क्वेरी पर बनता है"]
nowinrm["WinRM बिना लक्ष्य"] -.-> dcom["DCOM प्रोटोकॉल विकल्प"]
चित्र 6: रिमोट क्वेरी का डिफ़ॉल्ट WSMan है, और उसी लक्ष्य पर कई ऑपरेशन के लिए CIM सत्र का पुनः उपयोग स्थापित तरीका है।
# एक बार की क्वेरी के लिए -ComputerName (हर बार अस्थायी सत्र बनता है)
Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName Server01, Server02
# बार-बार क्वेरी हो तो CIM सत्र पुनः उपयोग करें
$session = New-CimSession -ComputerName Server01
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $session
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = 3" -CimSession $session
Remove-CimSession $session
जिन लक्ष्यों तक WSMan से न पहुँच सकें — जैसे पुरानी मशीन जहाँ WinRM कॉन्फ़िगर न हो — वहाँ DCOM प्रोटोकॉल चुन सकते हैं।4
$dcom = New-CimSessionOption -Protocol Dcom
$session = New-CimSession -ComputerName OldServer -SessionOption $dcom
रिमोट क्वेरी की पूर्वापेक्षाएँ निम्न हैं।
- लक्ष्य पर WinRM कॉन्फ़िगर होना चाहिए।
winrm quickconfigसेवा को स्वतः स्टार्ट करता है, HTTP लिस्नर (डिफ़ॉल्ट पोर्ट 5985) बनाता है, और फ़ायरवॉल अपवाद पंजीकृत करता है — सब एक साथ।10 HTTPS (डिफ़ॉल्ट पोर्ट 5986) से जुड़ना हो तो अकेले यह काफी नहीं — सर्वर प्रमाणपत्र तैयार करwinrm quickconfig -transport:httpsजैसे से HTTPS लिस्नर अलग कॉन्फ़िगर करना पड़ता है।10 - मार्ग के फ़ायरवॉल पर संबंधित पोर्ट खुले हों। इनबाउंड नियम डिज़ाइन और पंजीकृत करने का व्यावहारिक काम «Windows फ़ायरवॉल और व्यावसायिक ऐप» लेख में है।
- प्रमाणीकरण। डोमेन परिवेश में Kerberos पारस्परिक प्रमाणीकरण देता है। वर्कग्रुप में Kerberos नहीं होता, इसलिए क्लाइंट की
TrustedHostsसूची में लक्ष्य पंजीकृत करना पड़ सकता है। वह सूची यथासंभव संकीर्ण रखें।10 - अधिकार। डिफ़ॉल्ट कॉन्फ़िगरेशन में रिमोट WMI क्वेरी और ऑपरेशन मूलतः लक्ष्य के व्यवस्थापक समूह वाले खाते से होते हैं। सामान्य उपयोगकर्ताओं के लिए खोलना हो तो WinRM और WMI नेमस्पेस दोनों पर पहुँच अनुमति कॉन्फ़िगर करनी पड़ती है।10
- ध्यान दें कि DCOM का कोई स्थिर प्रतीक्षा पोर्ट नहीं (RPC के गतिशील पोर्ट उपयोग होते हैं), इसलिए फ़ायरवॉल पार डिज़ाइन कठिन हो जाता है। अब जो तंत्र बनाएँ उसके लिए WSMan को डिफ़ॉल्ट मानना सुरक्षित है।
flowchart TB
accTitle: रिमोट क्वेरी की पूर्वापेक्षा जाँचना
accDescr: लक्ष्य पर winrm quickconfig सेवा स्वतः स्टार्ट, HTTP लिस्नर बनाना और फ़ायरवॉल अपवाद पंजीकरण एक साथ करता है, HTTPS लिस्नर प्रमाणपत्र तैयार कर अलग कॉन्फ़िगर होता है, और वर्कग्रुप में TrustedHosts पंजीकरण आवश्यक हो सकता है
qc["winrm quickconfig"] --> svc["सेवा स्वतः स्टार्ट"]
qc --> lis["HTTP लिस्नर बनाना(5985)"]
qc --> fw["फ़ायरवॉल अपवाद"]
lis ~~~ https["HTTPS लिस्नर(5986)"]
https -.-> cert["प्रमाणपत्र तैयार कर अलग कॉन्फ़िगर"]
fw ~~~ wg["वर्कग्रुप परिवेश"]
wg -.-> th["TrustedHosts में पंजीकरण"]
चित्र 7: winrm quickconfig डिफ़ॉल्ट कॉन्फ़िगरेशन एक साथ करता है, HTTPS लिस्नर और वर्कग्रुप प्रमाणीकरण अलग सँभालने पड़ते हैं।
5. C# से उपयोग — System.Management और Microsoft.Management.Infrastructure
C# से WMI के API दो वंश हैं। दोनों केवल Windows हैं।
| System.Management | Microsoft.Management.Infrastructure (MI API) | |
|---|---|---|
| लाना | .NET Framework में डिफ़ॉल्ट। वर्तमान .NET पर NuGet पैकेज System.Management5 | NuGet पैकेज Microsoft.Management.Infrastructure6 |
| प्रवेश क्लास | ManagementObjectSearcher (WQL देकर क्वेरी)5 |
CimSession (Create → QueryInstances / InvokeMethod / Subscribe)6 |
| प्रकार तंत्र | ManagementObject / ManagementEventWatcher11 |
CimInstance / CimSession — CIM कमांडलेट जैसे ही प्रकार3 |
| रिमोट पहुँच | DCOM-आधारित | WSMan (CIM सत्र) आधारित। अतुल्यकालिक रूप (*Async) उपलब्ध6 |
| सबसे उपयुक्त | स्थानीय जानकारी प्राप्ति। मौजूदा कोड संपत्ति बनाए रखना | रिमोट क्वेरी और निगरानी जोड़ना। PowerShell के साथ डिज़ाइन |
5.1. System.Management: ManagementObjectSearcher की मूल बातें
WQL स्ट्रिंग के रूप में देते हैं और Get() से परिणाम संग्रह पाते हैं।5
// NuGet: System.Management (केवल Windows)
using System.Management;
using var searcher = new ManagementObjectSearcher(
@"root\cimv2",
"SELECT DeviceID, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType = 3");
foreach (ManagementObject disk in searcher.Get())
{
var freeGb = (ulong)disk["FreeSpace"] / 1024.0 / 1024.0 / 1024.0;
var sizeGb = (ulong)disk["Size"] / 1024.0 / 1024.0 / 1024.0;
Console.WriteLine($"{disk["DeviceID"]} खाली {freeGb:F1} GB / कुल {sizeGb:F1} GB");
}
गुण इंडेक्सर से object के रूप में लौटते हैं, इसलिए क्लास दस्तावेज़ में CIM प्रकार जाँचें (इस उदाहरण में FreeSpace / Size uint64 हैं9) और तदनुसार कास्ट करें। इसे int मानकर कास्ट करना, जिससे InvalidCastException आए, यहाँ का क्लासिक पहला ठोकर है।
flowchart TB
accTitle: गुण प्राप्ति और कास्ट का जाल
accDescr: System.Management के गुण इंडेक्सर से object के रूप में लौटते हैं इसलिए क्लास दस्तावेज़ में CIM प्रकार जाँचकर कास्ट करना पड़ता है, int मानकर कास्ट करें तो InvalidCastException आता है
idx["इंडेक्सर से प्राप्त"] --> obj["object के रूप में लौटता है"]
obj --> chk["दस्तावेज़ में CIM प्रकार जाँचें"]
chk --> cast["सही प्रकार में कास्ट"]
obj -.-> wrong["int मानकर कास्ट"]
wrong -.-> ex["InvalidCastException"]
चित्र 8: गुण object के रूप में लौटते हैं, इसलिए कास्ट से पहले CIM प्रकार जाँचें।
5.2. MI API: CimSession की मूल बातें
CimSession स्थानीय और रिमोट पहुँच एक ही आकार में सँभालता है। गणना, क्वेरी, मेथड कॉल, इवेंट सदस्यता और अतुल्यकालिक रूप सब एक जगह हैं।6
// NuGet: Microsoft.Management.Infrastructure (केवल Windows)
using Microsoft.Management.Infrastructure;
// स्थानीय के लिए CimSession.Create(null), रिमोट के लिए कंप्यूटर नाम दें
using CimSession session = CimSession.Create(null);
IEnumerable<CimInstance> disks = session.QueryInstances(
@"root\cimv2", "WQL",
"SELECT DeviceID, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType = 3");
foreach (CimInstance disk in disks)
{
var deviceId = (string)disk.CimInstanceProperties["DeviceID"].Value;
var free = (ulong)disk.CimInstanceProperties["FreeSpace"].Value;
Console.WriteLine($"{deviceId} खाली {free / 1024.0 / 1024 / 1024:F1} GB");
}
क्योंकि यह वही CimInstance सँभालता है जो PowerShell के CIM कमांडलेट लौटाते हैं, «पहले PowerShell में आज़माएँ, फिर C# में उतारें» वाला विकास प्रवाह सहज जुड़ता है। C# और PowerShell के एकीकरण को स्वयं डिज़ाइन कर रहे हों तो «C# (CSharp) से PowerShell चलाकर परिणाम ऑब्जेक्ट के रूप में पाना» भी देखें।
flowchart TB
accTitle: PowerShell में आज़माकर C# में उतारने का प्रवाह
accDescr: PowerShell के CIM कमांडलेट और C# का MI API वही CimInstance प्रकार सँभालते हैं, इसलिए PowerShell में प्रोटोटाइप कर C# में उतारने का विकास प्रवाह सहज जुड़ता है
trial["PowerShell में प्रोटोटाइप"] --> gci["CIM कमांडलेट"]
impl["C# में वास्तविक कार्यान्वयन"] --> mi["MI API"]
gci --> ci["वही CimInstance प्रकार"]
mi --> ci
ci -.-> flow["उतारना सहज जुड़ता है"]
चित्र 9: CIM कमांडलेट और MI API वही CimInstance प्रकार सँभालते हैं, इसलिए प्रोटोटाइप से वास्तविक कार्यान्वयन तक जुड़ता है।
6. अक्सर काम आने वाली रेसिपी
6.1. आम क्लास की त्वरित तालिका
| चाहिए जानकारी | क्लास | मुख्य गुण |
|---|---|---|
| निर्माता / मॉडल नाम | Win32_ComputerSystem |
Manufacturer, Model |
| चेसिस सीरियल नंबर | Win32_BIOS |
SerialNumber |
| OS संस्करण / बूट समय | Win32_OperatingSystem |
Caption, Version, LastBootUpTime |
| डिस्क खाली स्थान | Win32_LogicalDisk |
DeviceID, FreeSpace, Size, DriveType9 |
| सेवा अवस्था | Win32_Service |
Name, State, StartMode |
| प्रोसेस सूची | Win32_Process |
Name, ProcessId, CommandLine |
6.2. संपत्ति प्रबंधन का आम काम: सीरियल नंबर, मॉडल नाम और डिस्क खाली स्थान
# मॉडल जानकारी और सीरियल नंबर (PC संपत्ति बही से मिलान के लिए)
$cs = Get-CimInstance -ClassName Win32_ComputerSystem -Property Manufacturer, Model
$bios = Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber
[pscustomobject]@{
Manufacturer = $cs.Manufacturer
Model = $cs.Model
Serial = $bios.SerialNumber
}
# स्थानीय डिस्क (DriveType = 3) का खाली स्थान
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = 3" |
Select-Object DeviceID,
@{ Name = 'FreeGB'; Expression = { [math]::Round($_.FreeSpace / 1GB, 1) } },
@{ Name = 'SizeGB'; Expression = { [math]::Round($_.Size / 1GB, 1) } }
DriveType = 3 «स्थानीय डिस्क» का मान है, और रिमूवेबल (2), नेटवर्क ड्राइव (4), तथा CD (5) हटाता है।9 निगरानी के लिए यही स्क्रिप्ट CIM सत्र से प्रत्येक सर्वर पर घुमाना एजेंट-रहित डिस्क निगरानी की नींव देता है।
flowchart TB
accTitle: एजेंट-रहित डिस्क निगरानी की नींव
accDescr: DriveType 3 से छानकर रिमूवेबल, नेटवर्क ड्राइव और CD हटा स्थानीय डिस्क ही लक्ष्य बनाते हैं, और वही स्क्रिप्ट CIM सत्र से प्रत्येक सर्वर पर घुमाने से एजेंट-रहित डिस्क निगरानी की नींव बनती है
scr["खाली स्थान प्राप्ति स्क्रिप्ट"] --> flt["DriveType = 3 से छानें"]
flt -.-> exc["रिमूवेबल आदि हटाएँ"]
scr --> ses["CIM सत्र के ज़रिए"]
ses --> srvs["प्रत्येक सर्वर पर घुमाएँ"]
srvs --> mon["एजेंट-रहित निगरानी"]
चित्र 10: स्थानीय डिस्क तक छानी स्क्रिप्ट CIM सत्र से प्रत्येक सर्वर पर घुमाना निगरानी की नींव है।
6.3. प्रोसेस शुरू होने का पता — इवेंट सदस्यता
«पोलिंग से Win32_Process समय-समय पर लाकर अंतर देखना» के बजाय इवेंट सदस्यता लें। प्रोसेस शुरू पकड़ने का सरल तरीका Win32_ProcessStartTrace की सदस्यता है (कर्नेल ट्रेस प्रदाता की इवेंट क्लास, गुण ProcessName / ProcessID / ParentProcessID आदि8)।
# व्यवस्थापक (elevated) PowerShell सत्र से चलाएँ
$action = {
$name = $Event.SourceEventArgs.NewEvent.ProcessName
$id = $Event.SourceEventArgs.NewEvent.ProcessID
Write-Host "प्रोसेस शुरू: $name (PID=$id)"
}
Register-CimIndicationEvent -ClassName Win32_ProcessStartTrace `
-SourceIdentifier ProcessStarted -Action $action
सदस्यता उस PowerShell सत्र के जीवित रहने तक चालू रहती है जिसने उसे पंजीकृत किया, और हर प्रोसेस शुरू पर -Action चलता है। सदस्यता-हटाने का आदेश इसके तुरंत बाद उसी बैच में न चलाएँ — ऐसा करने से निगरानी शुरू होने से पहले सदस्यता गायब हो जाती है। हटाना निगरानी समाप्त करते समय चलाएँ।
# निगरानी समाप्त करते समय: सदस्यता हटाएँ
Unregister-Event -SourceIdentifier ProcessStarted
Register-CimIndicationEvent क्लास नाम या WQL इवेंट क्वेरी से सदस्यता पंजीकृत करता है, और -Action स्क्रिप्ट ब्लॉक हर आगमन पर चलता है।7 इस क्लास की सदस्यता के लिए व्यवस्थापक अधिकार आवश्यक हैं।7 इवेंट कौन प्राप्त कर सकता है यह इवेंट क्लास के सुरक्षा वर्णनकर्ता से नियंत्रित है, और बिना ऊँचे अधिकार के सामान्य उपयोगकर्ता को पहुँच अस्वीकृत होती है।8
sequenceDiagram
accTitle: प्रोसेस-शुरू इवेंट सदस्यता का प्रवाह
accDescr: व्यवस्थापक अधिकार वाले PowerShell सत्र में Register-CimIndicationEvent सदस्यता पंजीकृत करता है, हर प्रोसेस शुरू पर इवेंट आता है और Action चलता है, निगरानी समाप्त करते Unregister-Event से हटाते हैं
participant ps as PowerShell सत्र
participant wmi as WMI
ps->>wmi: Register-CimIndicationEvent से सदस्यता पंजीकरण
Note over ps: व्यवस्थापक अधिकार से चलाएँ
wmi-->>ps: हर प्रोसेस शुरू पर इवेंट आता है
ps->>ps: -Action चलाएँ
ps->>wmi: Unregister-Event से हटाएँ(निगरानी समाप्त पर)
चित्र 11: सदस्यता पंजीकृत सत्र के जीवित रहने तक चालू रहती है, और हटाना निगरानी समाप्त करते समय करते हैं।
दूसरा तरीका किसी भी क्लास पर चलने वाला सामान्य इंस्टेंस-निर्माण इवेंट (__InstanceCreationEvent) है। यहाँ WMI WITHIN से दिया अंतराल पर पोलिंग कर अंतर को इवेंट बनाता है, इसलिए पता लगाने के अंतराल और भार का समझौता स्वयं तय करना पड़ता है।
flowchart TB
accTitle: प्रोसेस शुरू पकड़ने के दो सदस्यता तरीके
accDescr: Win32_ProcessStartTrace कर्नेल ट्रेस प्रदाता की इवेंट क्लास की सदस्यता है, सामान्य __InstanceCreationEvent में WMI WITHIN दिए अंतराल पर पोलिंग कर अंतर को इवेंट बनाता है इसलिए पता अंतराल और भार का समझौता स्वयं तय करते हैं
goal["प्रोसेस शुरू होने का पता"] --> t1["Win32_ProcessStartTrace"]
goal --> t2["__InstanceCreationEvent"]
t1 -.-> k1["कर्नेल ट्रेस की सदस्यता"]
t2 -.-> w1["WITHIN अंतराल पर पोलिंग"]
w1 -.-> tr["अंतराल और भार का समझौता"]
चित्र 12: समर्पित इवेंट क्लास की सदस्यता लें, या पोलिंग अंतराल सहित सामान्य इंस्टेंस-निर्माण इवेंट उपयोग करें।
# 5 सेकंड अंतराल की पोलिंग से Win32_Process के नए इंस्टेंस की निगरानी
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'"
Register-CimIndicationEvent -Query $query -SourceIdentifier ProcPoll -Action {
Write-Host "शुरू: $($Event.SourceEventArgs.NewEvent.TargetInstance.Name)"
}
C# (System.Management) में ManagementEventWatcher वही भूमिका निभाता है।11
using System.Management;
// व्यवस्थापक के रूप में चल रहे प्रोसेस में
var watcher = new ManagementEventWatcher(
new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
watcher.EventArrived += (_, e) =>
{
var name = (string)e.NewEvent["ProcessName"];
var pid = (uint)e.NewEvent["ProcessID"];
Console.WriteLine($"प्रोसेस शुरू: {name} (PID={pid})");
};
watcher.Start();
// निगरानी समाप्त पर watcher.Stop() और Dispose न भूलें
स्थायी निगरानी में जोड़ते समय, सदस्यता टूटने पर पुनः पंजीकरण (सेवा पुनः स्टार्ट पर・त्रुटि पर) तक डिज़ाइन में शामिल करें। डिवाइस निगरानी सहित «अवस्था जाँचना और दिखाना» का डिज़ाइन «बाहरी उपकरणों की अवस्था जाँचने और दिखाने की सर्वोत्तम प्रथाएँ» में है।
stateDiagram-v2
accTitle: स्थायी निगरानी की सदस्यता जीवनचक्र
accDescr: स्थायी निगरानी में सदस्यता चालू अवस्था सेवा पुनः स्टार्ट या त्रुटि से टूट सकती है, इसलिए टूटना पकड़कर पुनः पंजीकरण कर सदस्यता चालू पर लौटाने तक डिज़ाइन में शामिल करें
s1: सदस्यता चालू
s2: सदस्यता टूटी अवस्था
s3: पुनः पंजीकरण
[*] --> s1
s1 --> s2: सेवा पुनः स्टार्ट・त्रुटि
s2 --> s3
s3 --> s1
चित्र 13: स्थायी निगरानी में, सदस्यता टूटने पर पुनः पंजीकरण कर सदस्यता चालू पर लौटाने तक डिज़ाइन शामिल करें।
7. जाल — प्रदर्शन, अधिकार, 64bit, रिपॉज़िटरी और तिथियाँ
7.1. SELECT * और पोलिंग की अधिकता
WMI क्वेरी «प्रदाता वहीं मान बनाता है» वाला काम है — मुफ़्त नहीं। दो क्लासिक एंटी-पैटर्न हैं।
SELECT *की आदत।Win32_Processके हर गुण की हर पंक्ति लें तो प्रदाता का काम और नेटवर्क स्थानांतरण (रिमोट पर) उसी अनुपात में बढ़ता है। पंक्तियाँ-Filterसे, स्तंभ-Propertyसे छानें, और आगे के ऑपरेशन के लिए केवल कुंजी चाहिए तो-KeyOnlyउपयोग करें। ये सभी «ऑब्जेक्ट आकार और नेटवर्क ट्रैफ़िक घटाने» के आधिकारिक साधन हैं।3- कम अंतराल पोलिंग। «हर सेकंड
Get-CimInstance Win32_Process» जैसा डिज़ाइन अध्याय 6.3 की इवेंट सदस्यता से बदलें। पोलिंग रूप (WITHIN) लेना ही पड़े तो अंतराल आवश्यकता के लिए यथेष्ट तक बढ़ाएँ।
साथ ही, रिमोट पर एक-एक लक्ष्य -ComputerName से दोहराना भी बहुत व्यर्थ है। हर क्वेरी पर अस्थायी सत्र बनता है, इसलिए कई ऑपरेशन CIM सत्र के पुनः उपयोग पर ले जाएँ।3
flowchart TB
accTitle: प्रदर्शन एंटी-पैटर्न और उनके स्थान
accDescr: SELECT तारांकन की आदत Filter और Property से पंक्ति और स्तंभ छानकर केवल कुंजी हो तो KeyOnly से बदलें, कम अंतराल पोलिंग इवेंट सदस्यता से, एक-एक ComputerName दोहराना CIM सत्र पुनः उपयोग से बदलें
a1["SELECT * की आदत"] --> f1["Filter और Property से छानें"]
f1 -.-> f2["केवल कुंजी हो तो KeyOnly"]
a2["कम अंतराल पोलिंग"] --> f3["इवेंट सदस्यता से बदलें"]
a3["एक-एक ComputerName"] --> f4["CIM सत्र पुनः उपयोग"]
चित्र 14: पंक्ति・स्तंभ・कुंजी छानना और इवेंट सदस्यता पर जाना WMI के प्रदर्शन मुद्दों का लगभग आधा रोकता है।
7.2. इवेंट सदस्यता के अधिकार
अध्याय 6.3 के अनुसार, Win32_ProcessStartTrace परिवार की सदस्यता व्यवस्थापक अधिकार मानती है।7 «विकास मशीन (व्यवस्थापक से चला) पर चला, पर ग्राहक के सामान्य-उपयोगकर्ता परिवेश में निगरानी नहीं चलती» फ़ायरवॉल सूचना संवाद के साथ क्लासिक दुर्घटना है। सामान्य उपयोगकर्ता से चलने वाले व्यावसायिक ऐप में निगरानी जोड़ें तो निगरानी भाग Windows सेवा (LocalSystem आदि) में अलग करें, और ऐप मुख्य भाग से अंतर-प्रोसेस संचार से जोड़ने का ढाँचा सोचें।
flowchart TB
accTitle: सामान्य-उपयोगकर्ता परिवेश में निगरानी ढाँचा
accDescr: व्यवस्थापक अधिकार वाली सदस्यता सामान्य उपयोगकर्ता से चलने वाले ऐप मुख्य भाग से काटें, निगरानी LocalSystem आदि से चलने वाली Windows सेवा में अलग करें, और ऐप मुख्य भाग से अंतर-प्रोसेस संचार से जोड़ें
svcm["निगरानी Windows सेवा"] --> subm["स्टार्ट ट्रेस की सदस्यता"]
svcm -.-> lsm["LocalSystem आदि से चलाएँ"]
appm["ऐप मुख्य भाग(सामान्य उपयोगकर्ता)"] ---|अंतर-प्रोसेस संचार| svcm
चित्र 15: व्यवस्थापक अधिकार वाली सदस्यता सेवा पक्ष पर अलग करें, और ऐप मुख्य भाग से अंतर-प्रोसेस संचार से जोड़ें।
7.3. 32bit/64bit और प्रदाता
64bit Windows पर कुछ प्रदाता 32bit और 64bit दोनों रूप में साथ रहते हैं, और डिफ़ॉल्ट से कॉलर ऐप की बिट संख्या से मेल खाने वाला पक्ष उत्तर देता है।12 क्लासिक उदाहरण root\default का रजिस्ट्री प्रदाता (StdRegProv) है: 32bit ऐप से पढ़ने पर Wow6432Node पक्ष (32bit दृश्य) के मान लौटते हैं।12 «WMI से पढ़ा रजिस्ट्री मान regedit में दिखे मान से भिन्न है» हो तो पहले यही संदेह करें। दूसरा दृश्य चाहिए तो कनेक्शन संदर्भ में __ProviderArchitecture (और बाध्य करना हो तो __RequiredArchitecture) देकर स्पष्ट माँग सकते हैं।12 बिट-संख्या समस्या का पूरा चित्र «C# से Win32 API सुरक्षित बुलाना — P/Invoke व्यावहारिक मार्गदर्शिका» में भी है।
flowchart TB
accTitle: 64bit परिवेश में प्रदाता चुनाव
accDescr: डिफ़ॉल्ट से कॉलर ऐप की बिट संख्या से मेल खाने वाला प्रदाता उत्तर देता है, 32bit ऐप की रजिस्ट्री क्वेरी Wow6432Node पक्ष का मान पाती है, पर __ProviderArchitecture से उलटा दृश्य स्पष्ट माँग सकते हैं
q1{"कॉलर की बिट संख्या?"} -->|32bit| p32["32bit प्रदाता उत्तर देता है"]
q1 -->|64bit| p64["64bit प्रदाता उत्तर देता है"]
p32 -.-> wow["रजिस्ट्री Wow6432Node पक्ष का मान"]
ctx["__ProviderArchitecture निर्दिष्ट"] -.-> ov["उलटा दृश्य स्पष्ट माँगें"]
चित्र 16: डिफ़ॉल्ट से कॉलर की बिट संख्या से मेल खाने वाला पक्ष उत्तर देता है, इसलिए 32bit ऐप Wow6432Node पक्ष पढ़ता है।
7.4. WMI रिपॉज़िटरी क्षति के लक्षण और उपाय
WMI की क्लास परिभाषाएँ रिपॉज़िटरी में संग्रहीत हैं (एक फ़ाइल नहीं — Repository फ़ोल्डर की फ़ाइलें मिलकर डेटाबेस का काम करती हैं13)। असंगति हो तो «जो क्लास होनी चाहिए वह नहीं मिलती» या «नेमस्पेस अमान्य है» जैसी त्रुटियाँ ऐप पक्ष कुछ बदले बिना शुरू हो जाती हैं। निदान और मरम्मत के लिए winmgmt.exe उपयोग करें।13
rem संगतता जाँच (परिणाम inconsistent हो तो असंगति है)
winmgmt /verifyrepository
rem संगतता जाँच + असंगति हो तो पुनर्निर्माण (पढ़ने योग्य सामग्री मर्ज होती है)
winmgmt /salvagerepository
ध्यान यह है कि रिपॉज़िटरी हटाना या आरंभ करना पहला कदम न बनाएँ। WMI से आने वाली त्रुटि OS के अन्य भाग से भी हो सकती है, और Microsoft स्पष्ट कहता है कि रिपॉज़िटरी हटाना पहला उपाय बनाने से «सिस्टम या स्थापित ऐप को क्षति पहुँच सकती है»।13 क्रम रखें: /verifyrepository से जाँच → /salvagerepository से मरम्मत।
flowchart TB
accTitle: WMI रिपॉज़िटरी असंगति छाँटने की प्रक्रिया
accDescr: क्लास नहीं मिलती जैसी त्रुटि आए तो winmgmt के verifyrepository से संगतता जाँचें, असंगति हो तो salvagerepository से पुनर्निर्माण करें, और रिपॉज़िटरी हटाना या आरंभ करना पहला कदम न बनाएँ
sym["क्लास नहीं मिलती आदि त्रुटि"] --> verify["winmgmt /verifyrepository"]
verify --> q1{"परिणाम inconsistent?"}
q1 -->|हाँ| salvage["winmgmt /salvagerepository"]
q1 -->|नहीं| other["OS के अन्य भाग का कारण सोचें"]
salvage -.-> merge["पढ़ने योग्य सामग्री मर्ज होती है"]
del["रिपॉज़िटरी हटाना・आरंभ करना"] -.-> ng["पहला कदम न बनाएँ"]
चित्र 17: verify से जाँचकर salvage से मरम्मत का क्रम रखें, हटाना पहला कदम न बनाएँ।
7.5. DMTF तिथि रूप का रूपांतरण
WMI तिथियाँ CIM विनिर्देश के DMTF रूप yyyymmddHHMMSS.mmmmmm±UUU (अंत UTC से मिनटों में ऑफ़सेट। उदाहरण: 20260801100000.000000+540) की स्ट्रिंग में संग्रहीत हैं। कच्चे मान को स्ट्रिंग प्रसंस्करण से काट-छाँटना बंद करें; रूपांतरण API उपयोग करें।
- C# (System.Management):
ManagementDateTimeConverterDMTF रूप औरDateTime/TimeSpanका पारस्परिक रूपांतरण देता है।11 - CIM-परिवार API (Get-CimInstance / MI API): तिथि गुण पहले से
DateTimeमें परिवर्तित लौटते हैं, इसलिए यह समस्या उठती ही नहीं।(Get-CimInstance Win32_OperatingSystem).LastBootUpTimeसीधेDateTimeके रूप में गणना में उपयोग हो सकता है।
flowchart TB
accTitle: DMTF तिथि रूप का व्यवहार
accDescr: WMI तिथियाँ DMTF रूप की स्ट्रिंग में संग्रहीत हैं, System.Management से कच्चा मान पढ़ें तो ManagementDateTimeConverter से रूपांतरित करें, CIM-परिवार API DateTime में पहले से परिवर्तित लौटाता है, इसलिए खुद स्ट्रिंग काट-छाँट न करें
dmtf["DMTF रूप की स्ट्रिंग"] --> q1{"किस API से प्राप्त?"}
q1 -->|System.Management| conv["ManagementDateTimeConverter"]
q1 -->|CIM-परिवार API| done["DateTime में पहले से परिवर्तित"]
conv --> dtv["DateTime / TimeSpan में रूपांतरण"]
cut["खुद स्ट्रिंग काट-छाँट"] -.-> ng["उपयोग न करें"]
चित्र 18: DMTF स्ट्रिंग का रूपांतरण रूपांतरण API पर छोड़ें, CIM-परिवार API हो तो परिवर्तित DateTime ज्यों का त्यों उपयोग करें।
8. जहाँ WMI उपयोग नहीं करना चाहिए — साधन की निर्णय तालिका
WMI «एक समान पढ़ने का मुख» के रूप में उत्तम है, पर हमेशा सर्वोत्तम हल नहीं। व्यावहारिक चुनाव का अनुमान यह है।
| करना क्या है | उपयुक्त साधन | WMI न चुनने का कारण |
|---|---|---|
| हार्डवेयर जानकारी・OS कॉन्फ़िगरेशन प्राप्ति, एजेंट-रहित रिमोट क्वेरी | WMI/CIM | यही WMI का घर है — समर्पित API एक-एक कर बुलाने से अधिक एकरूप |
| अपने ऐप की सेटिंग पढ़ना-लिखना | रजिस्ट्री सीधा पढ़ना (Microsoft.Win32.Registry)・कॉन्फ़िगरेशन फ़ाइल |
WMI से रजिस्ट्री संचालन घुमावदार है, और अध्याय 7.3 की बिट-संख्या समस्या भी साथ आती है |
| CPU उपयोग जैसी उच्च-आवृत्ति, निरंतर प्रदर्शन निगरानी | प्रदर्शन काउंटर (System.Diagnostics.PerformanceCounter आदि) |
काउंटर ठीक इसी के लिए हैं। WMI की कम अंतराल पोलिंग भार और सटीकता दोनों में पिछड़ती है |
| एकमुश्त OS फ़ंक्शन कॉल・कम विलंबता चाहिए वाला प्रसंस्करण | Win32 API (P/Invoke) | WMI COM/प्रदाता से गुज़रने का ओवरहेड रखता है |
| अपने प्रोसेस अधिकार पर्याप्त हों तो स्थानीय प्रोसेस गणना・संचालन | System.Diagnostics.Process |
मानक लाइब्रेरी में पूरा होता है, निर्भरता घटती है |
| फ़ायरवॉल・नेटवर्क जैसी Windows प्रबंधन सुविधाएँ कॉन्फ़िगर करना | Get-NetFirewallRule जैसे समर्पित CIM-आधारित कमांडलेट |
कच्चे WMI क्लास खोजने से, उपयोग के अनुसार बने कमांडलेट समूह अधिक सटीक और सुरक्षित हैं |
| फ़ाइल・फ़ोल्डर परिवर्तन का पता | FileSystemWatcher |
जहाँ समर्पित API है वहाँ WMI न लाएँ |
निर्णय की धुरी सरल है: «जहाँ समर्पित तंत्र है वहाँ समर्पित तंत्र उपयोग करें, क्रॉस-कटिंग क्वेरी और रिमोट क्वेरी के लिए WMI/CIM रखें»। अंतिम पंक्ति का Get-NetFirewallRule आदि आंतरिक रूप से CIM पर बने कमांडलेट समूह हैं — «WMI/CIM को सीधे छुए बिना केवल उसका लाभ लेना» वाला रूप।
flowchart TB
accTitle: साधन निर्णय की धुरी
accDescr: जहाँ समर्पित तंत्र है वहाँ समर्पित तंत्र उपयोग करें, जहाँ नहीं वहाँ क्रॉस-कटिंग क्वेरी और रिमोट क्वेरी के लिए WMI और CIM उपयोग करना निर्णय की धुरी है, और समर्पित CIM-आधारित कमांडलेट WMI और CIM को सीधे छुए बिना केवल लाभ लेने का रूप हैं
q1{"समर्पित तंत्र है?"} -->|है| ded["समर्पित तंत्र उपयोग करें"]
q1 -->|नहीं| wmi["WMI / CIM उपयोग करें"]
wmi -.-> use["क्रॉस-कटिंग क्वेरी・रिमोट क्वेरी"]
cmd["समर्पित CIM-आधारित कमांडलेट"] -.-> ben["केवल लाभ लेने का रूप"]
चित्र 19: जहाँ समर्पित तंत्र है वहाँ समर्पित उपयोग करें, क्रॉस-कटिंग क्वेरी और रिमोट क्वेरी के लिए WMI/CIM रखें।
9. सारांश
- CIM DMTF का उद्योग मानक है, WMI उसका Microsoft कार्यान्वयन। PowerShell के CIM कमांडलेट और C# का MI API दोनों इस मानक के वर्तमान पीढ़ी के प्रवेश हैं।
- PowerShell में Get-CimInstance / Invoke-CimMethod / Register-CimIndicationEvent वर्तमान हैं। Get-WmiObject जैसे WMI कमांडलेट PowerShell 7 में नहीं हैं, इसलिए नया स्क्रिप्ट 5.1 के लिए हो तब भी CIM पक्ष पर लिखें।
- रिमोट क्वेरी का डिफ़ॉल्ट WSMan (WinRM) है, और कई ऑपरेशन CIM सत्र का पुनः उपयोग करें। WinRM बिना लक्ष्य के लिए DCOM विकल्प बच निकलने का मार्ग है।
- C# में System.Management (सहज, स्थानीय-उन्मुख) और Microsoft.Management.Infrastructure (रिमोट・निगरानी-उन्मुख, CIM कमांडलेट जैसा प्रकार तंत्र) में से चुनें। दोनों केवल-Windows NuGet पैकेज हैं।
- प्रोसेस निगरानी पोलिंग नहीं, इवेंट सदस्यता से। Win32_ProcessStartTrace की सदस्यता के लिए व्यवस्थापक अधिकार आवश्यक हैं।
- SELECT * और कम अंतराल पोलिंग से बचें, -Filter / -Property / -KeyOnly से छानें। 32bit प्रोसेस की क्वेरी 32bit प्रदाता की ओर जाती है, DMTF तिथि रूपांतरण API से बदलें, रिपॉज़िटरी क्षति हटाने से नहीं verify → salvage के क्रम से सँभालें — यह याद रखें।
- जहाँ समर्पित तंत्र है (सेटिंग, प्रदर्शन काउंटर, एकमुश्त API कॉल) वहाँ WMI न लाएँ, क्रॉस-कटिंग क्वेरी और रिमोट क्वेरी के लिए WMI/CIM उपयोग करें — यही उपयोग की एक पंक्ति है।
संबंधित लेख
- C# (CSharp) से PowerShell चलाकर परिणाम ऑब्जेक्ट के रूप में पाना
- PowerShell व्यावहारिक कमांड रेसिपी — रोज़ के छोटे औज़ार बढ़ाना
- Windows PowerShell 5.1 और PowerShell 7 के अंतर — आंतरिक स्क्रिप्ट माइग्रेशन की व्यावहारिक मार्गदर्शिका
- बाहरी उपकरणों की अवस्था जाँचने और दिखाने की सर्वोत्तम प्रथाएँ - केवल «कनेक्टेड» पर न रुकने वाला डिज़ाइन
- C# से Win32 API सुरक्षित बुलाना — P/Invoke व्यावहारिक मार्गदर्शिका (DllImport / LibraryImport / CsWin32)
- Windows में TPM क्या है — «कुंजी बाहर न निकलने वाला तिजोरी» और मापित बूट का चित्रण
संबंधित परामर्श क्षेत्र
KomuraSoft LLC WMI/CIM से हार्डवेयर जानकारी प्राप्ति, प्रोसेस निगरानी और रिमोट PC क्वेरी को व्यावसायिक ऐप में जोड़ने, Get-WmiObject पर आधारित आंतरिक स्क्रिप्ट को CIM कमांडलेट पर माइग्रेट करने, और «विकास मशीन पर चलता है पर ग्राहक स्थल पर अधिकार त्रुटि आती है» जैसी समस्याओं की जाँच सँभालता है। PowerShell में प्रोटोटाइप से C# में वास्तविक कार्यान्वयन तक एक ही धारा में परामर्श ले सकते हैं।
संदर्भ लिंक
-
Microsoft Learn, About WMI. इस पर कि WMI WBEM (उद्यम परिवेश में प्रबंधन जानकारी तक पहुँच की मानक तकनीक विकसित करने की उद्योग पहल) का Microsoft कार्यान्वयन है; प्रबंधन लक्ष्यों को CIM (Common Information Model) उद्योग मानक से व्यक्त करता है, जिसे DMTF (Distributed Management Task Force) विकसित और रखता है; अगली पीढ़ी MI (Windows Management Infrastructure) पुराने WMI से पूर्ण संगत है; और रिमोट WMI कनेक्शन DCOM से होते हैं, विकल्प के रूप में WS-Management-आधारित WinRM है। ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Differences between Windows PowerShell 5.1 and PowerShell 7.x. इस पर कि WMI v1 कमांडलेट (Register-WmiEvent / Set-WmiInstance / Invoke-WmiMethod / Get-WmiObject / Remove-WmiObject) PowerShell से हटा दिए गए हैं, और CimCmdlets मॉड्यूल (WMI v2) के कमांडलेट वही कार्य नई सुविधाओं और पुनर्डिज़ाइन किए वाक्यविन्यास के साथ देते हैं। ↩ ↩2
-
Microsoft Learn, Get-CimInstance (CimCmdlets). इस पर कि न ComputerName न CimSession दें तो स्थानीय WMI से COM सत्र पर जुड़ता है, और -ComputerName देने पर WsMan प्रोटोकॉल का अस्थायी सत्र बनता है; उसी कंप्यूटर पर कई ऑपरेशन के लिए CIM सत्र से जुड़ना प्रदर्शन के लिए अनुशंसित है; -Filter WHERE शब्द रहित WQL/CQL where खंड है; -Property और -KeyOnly ऑब्जेक्ट आकार और नेटवर्क ट्रैफ़िक घटाते हैं; डिफ़ॉल्ट नेमस्पेस root/CIMV2 और डिफ़ॉल्ट क्वेरी भाषा (-QueryDialect) WQL है; आउटपुट Microsoft.Management.Infrastructure.CimInstance है; Invoke-CimMethod के साथ GetOwner बुलाने का उदाहरण; और कमांडलेट केवल Windows है। ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
-
Microsoft Learn, New-CimSessionOption (CimCmdlets). इस पर कि CIM सत्र विकल्प के दो पैरामीटर सेट हैं, WsMan और DCOM के लिए; -Protocol Dcom / Default / Wsman ले सकता है; New-CimSessionOption -Protocol Dcom से बना विकल्प New-CimSession के -SessionOption में देकर DCOM CIM सत्र बनाने का उदाहरण; और DCOM सत्र का डिफ़ॉल्ट impersonation स्तर Impersonate है। ↩ ↩2
-
Microsoft Learn, ManagementObjectSearcher Class (System.Management). इस पर कि यह निर्दिष्ट WQL क्वेरी के आधार पर प्रबंधन ऑब्जेक्ट का संग्रह प्राप्त करने वाला, प्रबंधन जानकारी प्राप्ति का सबसे आम प्रवेश क्लास है; ObjectQuery और ManagementScope (WMI नेमस्पेस) लेकर Get() से ManagementObjectCollection लौटाता है; और System.Management.dll NuGet पैकेज System.Management के रूप में दिया जाता है। ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, CimSession Class (Microsoft.Management.Infrastructure). इस पर कि Microsoft.Management.Infrastructure.dll NuGet पैकेज Microsoft.Management.Infrastructure के रूप में दिया जाता है; Create(computerName) से सत्र बनाना; QueryInstances(namespace, queryDialect, query) से क्वेरी चलाना; और EnumerateInstances / GetInstance / InvokeMethod / Subscribe तथा प्रत्येक के अतुल्यकालिक (*Async) रूप, IDisposable लागू करते हुए। ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Register-CimIndicationEvent (CimCmdlets). इस पर कि क्लास नाम या क्वेरी व्यंजक से इंडिकेशन (इवेंट) की सदस्यता लेते हैं और -SourceIdentifier से सदस्यता नाम देते हैं; Win32_ProcessStartTrace सदस्यता का उदाहरण और PowerShell व्यवस्थापक के रूप में चलाने की आवश्यकता का नोट; -Action स्क्रिप्ट ब्लॉक में $Event.SourceEventArgs.NewEvent से ProcessName / ProcessId संदर्भ का उदाहरण; -ComputerName देने पर WsMan अस्थायी सत्र, न देने पर स्थानीय COM कनेक्शन; और सदस्यता हटाने के लिए Unregister-Event। ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Win32_ProcessStartTrace class. इस पर कि यह नए प्रोसेस के शुरू को दर्शाने वाली इवेंट क्लास है, गुणों में ProcessName / ProcessID / ParentProcessID / SessionID / Sid आदि; SECURITY_DESCRIPTOR गुण वह वर्णनकर्ता है जिससे इवेंट प्रदाता तय करता है कौन से उपयोगकर्ता इवेंट प्राप्त कर सकते हैं; और नेमस्पेस Root\CIMV2 है, कर्नेल ट्रेस प्रदाता (Krnlprov.dll) देता है। ↩ ↩2 ↩3
-
Microsoft Learn, Win32_LogicalDisk class. इस पर कि Win32_LogicalDisk CIM_LogicalDisk से व्युत्पन्न स्थानीय स्टोरेज डिवाइस की क्लास है; DriveType के मान (2 = रिमूवेबल, 3 = स्थानीय डिस्क, 4 = नेटवर्क ड्राइव, 5 = CD आदि); FreeSpace / Size uint64 बाइट मान हैं; DeviceID कुंजी है; और DriveType = 3 से छानने वाले VBScript / C# क्वेरी उदाहरण। ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Installation and configuration for Windows Remote Management. इस पर कि डिफ़ॉल्ट से WinRM लिस्नर कॉन्फ़िगर नहीं होता इसलिए WS-Management संदेश भेजे-प्राप्त नहीं हो सकते; winrm quickconfig सेवा स्वतः स्टार्ट, HTTP/HTTPS लिस्नर कॉन्फ़िगर, और फ़ायरवॉल अपवाद पंजीकृत करता है; WinRM 2.0 के डिफ़ॉल्ट पोर्ट HTTP 5985 / HTTPS 5986 हैं; वर्कग्रुप आदि में पारस्परिक प्रमाणीकरण (Kerberos) न स्थापित हो तो TrustedHosts यथासंभव सीमित रखें; और लिस्नर की रिमोट पहुँच नियंत्रित करने वाला डिफ़ॉल्ट सुरक्षा वर्णनकर्ता (RootSDDL), तथा गैर-व्यवस्थापक उपयोगकर्ताओं को WMI प्लग-इन उपयोग की अनुमति देने का अतिरिक्त कॉन्फ़िगरेशन। ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, System.Management Namespace. इस पर कि यह नेमस्पेस WMI आधार की क्वेरी ManagementObjectSearcher परिवार से, और इवेंट सदस्यता ManagementEventWatcher से करता है; WqlEventQuery WQL रूप की इवेंट क्वेरी व्यक्त करता है; और ManagementDateTimeConverter DMTF तिथि-समय तथा अंतराल और CLR के DateTime / TimeSpan का पारस्परिक रूपांतरण देता है। ↩ ↩2 ↩3
-
Microsoft Learn, Requesting WMI Data on a 64-bit Platform. इस पर कि प्रदाता 32bit और 64bit दोनों रूप में हो तो डिफ़ॉल्ट से 32bit ऐप (स्क्रिप्ट सहित) को 32bit प्रदाता, 64bit ऐप को 64bit प्रदाता उत्तर देता है; संदर्भ के __ProviderArchitecture (32 या 64) और __RequiredArchitecture से गैर-डिफ़ॉल्ट प्रदाता माँग या बाध्य कर सकते हैं (बाध्य करते संबंधित रूप न हो तो WBEM_E_PROVIDER_LOAD_FAILURE); और रजिस्ट्री-प्रदाता उदाहरण में 32bit क्लाइंट HKLM\SOFTWARE\Wow6432Node पक्ष का डेटा पाता है। ↩ ↩2 ↩3
-
Microsoft Learn, winmgmt. इस पर कि winmgmt.exe का /verifyrepository WMI रिपॉज़िटरी की संगतता जाँच करता है; /salvagerepository संगतता जाँच कर असंगति मिलने पर रिपॉज़िटरी पुनर्निर्माण करता है और पढ़ी जा सकी सामग्री मर्ज करता है; /resetrepository OS प्रारंभिक स्थापना की अवस्था पर लौटाता है; रिपॉज़िटरी Repository फ़ोल्डर की फ़ाइलों से बना डेटाबेस है; और WMI से आने वाली त्रुटि कभी OS के अन्य भाग से होती है, इसलिए पहला उपाय रिपॉज़िटरी हटाना नहीं करना चाहिए क्योंकि उससे सिस्टम या स्थापित ऐप को क्षति पहुँच सकती है। ↩ ↩2 ↩3
संबंधित लेख
निकटवर्ती विषयों में गहराई से जाने के लिए समान टैग वाले नवीनतम लेख।
व्यावहारिक मल्टीथ्रेडिंग सर्वोत्तम प्रथाएँ: .NET संस्करण — और थ्रेड जोड़ने से पहले क्या तय करें
मल्टीथ्रेडेड .NET/C# कोड को कभी-कभी क्रैश या हैंग होने से बचाने वाले डिज़ाइन नियमों का व्यावहारिक सार: थ्रेड स्वयं न बनाकर Task पर चलें, ...
Named Pipes व्यवहार में — डिज़ाइन से सुरक्षा तक, Windows की मानक IPC
Named pipes — Windows की मानक इंटर-प्रोसेस कम्युनिकेशन — की व्यावहारिक मार्गदर्शिका। यह लेख प्राथमिक स्रोतों से बाइट और मैसेज मोड का चुना...
स्लीप से रिज़्यूम पर टूटने वाले ऐप — Windows पावर इवेंट कैसे काम करते हैं और उनसे बचने वाले व्यावसायिक ऐप कैसे बनाएँ
लैपटॉप खोला और व्यावसायिक ऐप के कनेक्शन मर चुके थे — कारण वह डिज़ाइन है जिसने स्लीप का हिसाब ही नहीं रखा। यह लेख WM_POWERBROADCAST सूचना ...
Win32 Thread Pool API — CreateThreadpoolWork से थ्रेड बनाए बिना समवर्तिता
क्या आपके नेटिव कोड में CreateThread कॉल बिखरी पड़ी हैं? यह लेख Vista में पुनर्डिज़ाइन की गई Win32 थ्रेड पूल API — work, timer, wait और i...
DllMain और Loader Lock — DLL आरंभीकरण में "कुछ न करें" कहे जाने का वास्तविक कारण
DllMain से LoadLibrary क्यों न बुलाएँ या दूसरे थ्रेड से सिंक्रोनाइज़ न करें। प्राथमिक स्रोतों से यह लेख समझाता है कि लोडर लॉक हर DLL सूचन...
संबंधित विषय
ये पृष्ठ विषय को सेवाओं और निर्णयों के व्यापक संदर्भ में रखते हैं।
Windows के तकनीकी विषय
Windows विकास, बग जाँच और मौजूदा संपत्तियों के उपयोग का प्रवेश-द्वार।
इस विषय से जुड़ी सेवाएँ
यह लेख निम्नलिखित सेवाओं से सीधे जुड़ा है।
Windows ऐप विकास
व्यावसायिक ऐप, डिवाइस एकीकरण और संचार उपकरण, आवश्यकताओं से विकास तक।
अक्सर पूछे जाने वाले प्रश्न
इस लेख के विषय पर परामर्श में अक्सर पूछे जाने वाले प्रश्न।
- WMI और CIM में क्या अंतर है?
- CIM वह उद्योग-मानक मॉडल है जिससे सिस्टम और डिवाइस जैसे प्रबंधन लक्ष्यों को व्यक्त किया जाता है, और इसे DMTF (Distributed Management Task Force) तय और रखता है। WMI उस मानक का उपयोग करने वाली WBEM पहल का Microsoft कार्यान्वयन है, और वह Windows में बना होता है। अर्थात CIM विनिर्देश है, WMI Windows पर कार्यान्वयन। PowerShell का Get-CimInstance और C# का Microsoft.Management.Infrastructure स्वयं को CIM कहते हैं क्योंकि वे इस मानक के API हैं, पर जुड़ते वही अंतर्निहित WMI से हैं। रोज़ के विकास में इतना काफी है कि WMI क्लास (Win32_* आदि) को CIM-परिवार API से क्वेरी करते हैं।
- क्या Get-WmiObject अब उपयोग नहीं हो सकता?
- Windows PowerShell 5.1 में अभी चलता है, पर PowerShell 6 से आगे (वर्तमान PowerShell 7 सहित) WMI v1 कमांडलेट — Get-WmiObject, Invoke-WmiMethod, Register-WmiEvent, Set-WmiInstance, और Remove-WmiObject — हटा दिए गए हैं और चल नहीं सकते। वही कार्य CimCmdlets मॉड्यूल (Get-CimInstance / Invoke-CimMethod / Register-CimIndicationEvent आदि) देता है। नए स्क्रिप्ट लिखते समय, 5.1 पर चलाने हों तब भी CIM कमांडलेट से लिखना सुरक्षित है। ऐसा करने पर बाद में PowerShell 7 पर माइग्रेट करते WMI भाग दोबारा नहीं लिखना पड़ता।
- C# से WMI के लिए System.Management लें या Microsoft.Management.Infrastructure?
- दोनों केवल Windows हैं, और वर्तमान .NET से NuGet पैकेज के रूप में आते हैं। System.Management क्लासिक API है — ManagementObjectSearcher को WQL दे देना काफी है — और स्थानीय जानकारी लेना मुख्य काम हो तो अकेले पर्याप्त है। DMTF तिथियाँ बदलने वाला ManagementDateTimeConverter भी इसी में है। दूसरी ओर Microsoft.Management.Infrastructure (MI API) PowerShell के CIM कमांडलेट जैसा ही प्रकार तंत्र (CimSession / CimInstance) रखता है, और WSMan पर रिमोट क्वेरी, अतुल्यकालिक मेथड, और इवेंट सदस्यता (Subscribe) एक ही ढाँचे में सँभालता है। रिमोट PC क्वेरी और निगरानी को उत्पाद में सचमुच जोड़ रहे हों तो MI API चुनना तर्कसंगत है।
- Get-CimInstance रिमोट PC से जुड़ता नहीं। क्या जाँचें?
- पहले लक्ष्य मशीन पर WinRM कॉन्फ़िगर है या नहीं जाँचें। -ComputerName वाला CIM ऑपरेशन WSMan (WinRM) प्रोटोकॉल पर अस्थायी सत्र बनाता है, इसलिए लक्ष्य पर WinRM सेवा और लिस्नर चलना पूर्वापेक्षा है। winrm quickconfig डिफ़ॉल्ट कॉन्फ़िगरेशन (सेवा शुरू करना, लिस्नर बनाना, फ़ायरवॉल अपवाद) एक साथ करता है। डिफ़ॉल्ट पोर्ट HTTP 5985 और HTTPS 5986 हैं, इसलिए मार्ग के फ़ायरवॉल भी देखें। वर्कग्रुप में Kerberos से पारस्परिक प्रमाणीकरण नहीं होता, इसलिए क्लाइंट की TrustedHosts सूची में लक्ष्य पंजीकृत करना पड़ सकता है। जिस लक्ष्य पर WinRM बिलकुल कॉन्फ़िगर न कर सकें, वहाँ New-CimSessionOption -Protocol Dcom से बना विकल्प लेकर DCOM पर जुड़ सकते हैं।
- WMI तिथि 20260801100000.000000+540 जैसे रूप में क्यों लौटती है?
- WMI तिथियाँ DMTF CIM विनिर्देश की स्ट्रिंग रूप (yyyymmddHHMMSS.mmmmmm±UUU, अंत UTC से मिनटों में ऑफ़सेट) में संग्रहीत होती हैं। पुराने Get-WmiObject या System.Management से कच्चा मान पढ़ें तो यही स्ट्रिंग ज्यों की त्यों मिलती है। C# (System.Management) में ManagementDateTimeConverter DMTF रूप और DateTime / TimeSpan के बीच रूपांतरण देता है, इसलिए स्ट्रिंग खुद काट-छाँटने के बजाय उसे उपयोग करें। ध्यान दें कि Get-CimInstance जैसे CIM-परिवार API से लेने पर तिथि गुण पहले से DateTime में परिवर्तित लौटते हैं, इसलिए यह समस्या उठती ही नहीं।