C Sharp'ta bir proje yazdığınızı düşünün. Her şey birer class'tan ibaret ve bu class'ların üsünde bir de namespace'ler var. Namespace'leri yazdığımız class'ları başka class'lar altında kullanabilmek için using anahtar kelimesi ile birlikte kullanırız. Burdaki hiyerarşik yapının aynısı aslında şuan odaklanacağımız konu içinde geçerlidir.
WMI yapıları hiyerarşik class'lardan oluşmaktadır. Eğer bir iş yapabilmek için class'ınızı ve namespace'inizi biliyorsanız çok kısa powershell komutları ile windows dünyasında mükemmel işler yapabilirsiniz. Diyelim ki class'ınızı ve namespace'inizi bilmiyorsunuz. Yapmak istediğiniz işlem ise bir process başlatmak olsun. İlerleyeceğimiz yol aşağıdaki gibidir.
İlk olarak powershell içerisinde şanslı bir arama yapalım ve wmi içeren cmdlet'leri elde edelim.
PS C:\Users\Administrator> Get-Help *wmi*
Name Category Module Synopsis
---- -------- ------ --------
gwmi Alias Get-WmiObject
iwmi Alias Invoke-WmiMethod
rwmi Alias Remove-WmiObject
swmi Alias Set-WmiInstance
Get-WmiObject Cmdlet Microsoft.PowerShell.M... ...
Invoke-WmiMethod Cmdlet Microsoft.PowerShell.M... ...
Register-WmiEvent Cmdlet Microsoft.PowerShell.M... ...
Remove-WmiObject Cmdlet Microsoft.PowerShell.M... ...
Set-WmiInstance Cmdlet Microsoft.PowerShell.M... ...
Get-WmiObject yapısı ile kullanmak istediğim class'ı keşfetmeyi deneyeceğim. help ile içerisinde okuma yaptığımda class ve namespace gibi parametreleri kullandığını gördüm.
Namespace'leri yazının başında basitçe anlatmıştık. Bir klasör gibi düşünebiliriz ve içerisinde class'larımız bulunmaktadır. Aynı zamanda namespace içerisinde namespace tanımlamasıda yapılabilir ve en yukarıdaki namespace'in adı root'tur.
Bilgisayarınızdaki bütün namespace'leri keşfetmek isterseniz aşağıdaki powershell kodunu çalıştırın.
PS C:\Users\sbi> # create a new queue
>> $namespaces = [System.Collections.Queue]::new()
>>
>> # add an initial namespace to the queue
>> # any namespace in the queue will later be processed
>> $namespaces.Enqueue('root')
>>
>> # process all elements on the queue until all are taken
>> While ($namespaces.Count -gt 0 -and ($current = $namespaces.Dequeue()))
>> {
>> # find child namespaces
>> Get-CimInstance -Namespace $current -ClassName __Namespace -ErrorAction Ignore |
>> # ignore localization namespaces
>> Where-Object Name -NotMatch '^ms_\d{2}' |
>> ForEach-Object {
>> # construct the full namespace name
>> $childnamespace = '{0}\{1}' -f $current, $_.Name
>> # add namespace to queue
>> $namespaces.Enqueue($childnamespace)
>> }
>>
>> # output current namespace
>> $current
>> }
Kod çıktısı bende aşağıdaki gibi bir cevap döndürmüştür.
root
root\subscription
root\DEFAULT
root\CIMV2
root\msdtc
root\Cli
root\SECURITY
root\HyperVCluster
root\SecurityCenter2
root\RSOP
root\PEH
root\StandardCimv2
root\WMI
root\directory
root\Policy
root\virtualization
root\Interop
root\Hardware
root\ServiceModel
root\SecurityCenter
root\Microsoft
root\aspnet
root\Appv
root\CIMV2\mdm
root\CIMV2\Security
root\CIMV2\power
root\CIMV2\TerminalServices
root\HyperVCluster\v2
root\RSOP\User
root\RSOP\Computer
root\StandardCimv2\embedded
root\directory\LDAP
root\virtualization\v2
root\Microsoft\SqlServer
root\Microsoft\HomeNet
root\Microsoft\protectionManagement
root\Microsoft\Windows
root\Microsoft\SecurityClient
root\Microsoft\Uev
root\CIMV2\mdm\dmmap
root\CIMV2\Security\MicrosoftTpm
root\CIMV2\Security\MicrosoftVolumeEncryption
root\Microsoft\SqlServer\ComputerManagement15
root\Microsoft\SqlServer\ServerEvents
root\Microsoft\Windows\RemoteAccess
root\Microsoft\Windows\Dns
root\Microsoft\Windows\Powershellv3
root\Microsoft\Windows\Hgs
root\Microsoft\Windows\WindowsUpdate
root\Microsoft\Windows\DeviceGuard
root\Microsoft\Windows\TaskScheduler
root\Microsoft\Windows\DesiredStateConfigurationProxy
root\Microsoft\Windows\SmbWitness
root\Microsoft\Windows\Wdac
root\Microsoft\Windows\winrm
root\Microsoft\Windows\AppBackgroundTask
root\Microsoft\Windows\PS_MMAgent
root\Microsoft\Windows\Storage
root\Microsoft\Windows\HardwareManagement
root\Microsoft\Windows\SMB
root\Microsoft\Windows\EventTracingManagement
root\Microsoft\Windows\DesiredStateConfiguration
root\Microsoft\Windows\Attestation
root\Microsoft\Windows\CI
root\Microsoft\Windows\Defender
root\Microsoft\SqlServer\ServerEvents\MSSQLSERVER
root\Microsoft\SqlServer\ServerEvents\SQLEXPRESS
root\Microsoft\Windows\RemoteAccess\Client
root\Microsoft\Windows\Storage\PT
root\Microsoft\Windows\Storage\Providers_v2
root\Microsoft\Windows\Storage\PT\Alt
Biz bu kadar namespace ile ilgilenmeyeceğiz ve recursive bir şekilde ilerlemeyeceğiz. Benzer bir çıktıya aşağıdaki powershell komutu ile elde etmekte mümkündür.
PS C:\Users\Administrator> Get-WmiObject -Namespace "root" -Class "__Namespace" | select name
name
----
subscription
DEFAULT
MicrosoftDfs
CIMV2
msdtc
Cli
MicrosoftActiveDirectory
SECURITY
RSOP
MicrosoftDNS
PEH
StandardCimv2
WMI
AccessLogging
directory
Policy
InventoryLogging
Interop
Hardware
ServiceModel
Microsoft
Appv
Windows'un default seçili olan namespace'i root/cimv2'dir. Bunu birazdan kendi kendimize kanıtlamış olacağız. Namespace'lerin bir klasör gibi olduğunu söylemiştik şimdi bu klasörün içeriğini görelim.
Get-WmiObject -Namespace "root/cimv2" -List
Bu komut çalıştırıldığında cimv2 altındaki class'lar listelenecektir. Şimdi şanslı bir arama yapaım ve listelenen class'lar arasında process kelimesi geçenleri bulalım.
PS C:\Users\Administrator> Get-WmiObject -Namespace "root/cimv2" -List | Where-Object {$_.Name -match "process"}
NameSpace: ROOT\cimv2
Name Methods Properties
---- ------- ----------
Win32_ProcessTrace {} {ParentProcessID, ProcessID, ProcessName, SECURITY_DESCRIPTOR...}
Win32_ProcessStartTrace {} {ParentProcessID, ProcessID, ProcessName, SECURITY_DESCRIPTOR...}
Win32_ProcessStopTrace {} {ExitStatus, ParentProcessID, ProcessID, ProcessName...}
CIM_Processor {SetPowerState, R... {AddressWidth, Availability, Caption, ConfigManagerErrorCode...}
Win32_Processor {SetPowerState, R... {AddressWidth, Architecture, AssetTag, Availability...}
CIM_Process {} {Caption, CreationClassName, CreationDate, CSCreationClassName...}
Win32_Process {Create, Terminat... {Caption, CommandLine, CreationClassName, CreationDate...}
Win32_NamedJobObjectProcess {} {Collection, Member}
Win32_ProcessStartup {} {CreateFlags, EnvironmentVariables, ErrorMode, FillAttribute...}
Win32_ComputerSystemProcessor {} {GroupComponent, PartComponent}
Win32_SystemProcesses {} {GroupComponent, PartComponent}
CIM_ProcessThread {} {GroupComponent, PartComponent}
CIM_OSProcess {} {GroupComponent, PartComponent}
CIM_ProcessExecutable {} {Antecedent, BaseAddress, Dependent, GlobalProcessCount...}
Win32_SessionProcess {} {Antecedent, Dependent}
CIM_AssociatedProcessorMemory {} {Antecedent, BusSpeed, Dependent}
Win32_AssociatedProcessorMemory {} {Antecedent, BusSpeed, Dependent}
Win32_PerfFormattedData_Counters... {} {BuildScatterGatherCyclesPersec, Caption, Description, Frequency_Object...}
Win32_PerfRawData_Counters_PerPr... {} {BuildScatterGatherCyclesPersec, Caption, Description, Frequency_Object...}
Win32_PerfFormattedData_Counters... {} {BuildScatterGatherListCallsPersec, Caption, Description, DPCsDeferredPersec...}
Win32_PerfRawData_Counters_PerPr... {} {BuildScatterGatherListCallsPersec, Caption, Description, DPCsDeferredPersec...}
Win32_PerfFormattedData_Counters... {} {AverageIdleTime, C1TransitionsPersec, C2TransitionsPersec, C3TransitionsPersec...}
Win32_PerfRawData_Counters_Proce... {} {AverageIdleTime, AverageIdleTime_Base, C1TransitionsPersec, C2TransitionsPersec...}
Win32_PerfFormattedData_GPUPerfo... {} {Caption, DedicatedUsage, Description, Frequency_Object...}
Win32_PerfRawData_GPUPerformance... {} {Caption, DedicatedUsage, Description, Frequency_Object...}
Win32_PerfFormattedData_HvStats_... {} {C1TransitionsPersec, C2TransitionsPersec, C3TransitionsPersec, Caption...}
Win32_PerfRawData_HvStats_HyperV... {} {C1TransitionsPersec, C2TransitionsPersec, C3TransitionsPersec, Caption...}
Win32_PerfFormattedData_HvStats_... {} {AddressDomainFlushesPersec, AddressSpaceEvictionsPersec, AddressSpaceFlushesPersec, AddressSpaceSwitchesPersec...}
Win32_PerfRawData_HvStats_HyperV... {} {AddressDomainFlushesPersec, AddressSpaceEvictionsPersec, AddressSpaceFlushesPersec, AddressSpaceSwitchesPersec...}
Win32_PerfFormattedData_Lsa_Secu... {} {Caption, ContextHandles, CredentialHandles, Description...}
Win32_PerfRawData_Lsa_SecurityPe... {} {Caption, ContextHandles, CredentialHandles, Description...}
Win32_PerfFormattedData_LSM_User... {} {Caption, Description, Frequency_Object, Frequency_PerfTime...}
Win32_PerfRawData_LSM_UserInputD... {} {Caption, Description, Frequency_Object, Frequency_PerfTime...}
Win32_PerfFormattedData_PerfOS_P... {} {C1TransitionsPersec, C2TransitionsPersec, C3TransitionsPersec, Caption...}
Win32_PerfRawData_PerfOS_Processor {} {C1TransitionsPersec, C2TransitionsPersec, C3TransitionsPersec, Caption...}
Win32_PerfFormattedData_PerfProc... {} {Caption, CreatingProcessID, Description, ElapsedTime...}
Win32_PerfRawData_PerfProc_Process {} {Caption, CreatingProcessID, Description, ElapsedTime...}
Burda bana göz kırpan class Win32_Process class'ı. Bu class'ın metotlarını görmek istiyorum. Böylece class'ı aynı programlamada olduğu gibi kullanabiliriz.
PS C:\Users\Administrator> Get-WmiObject -Namespace "root/cimv2" -List | Where-Object {$_.Name -eq "Win32_Process"} | select -ExpandProperty Methods
Name : Create
InParameters : System.Management.ManagementBaseObject
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Constructor, Implemented, MappingStrings, Privileges...}
Name : Terminate
InParameters : System.Management.ManagementBaseObject
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Destructor, Implemented, MappingStrings, Privileges...}
Name : GetOwner
InParameters :
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Implemented, MappingStrings, ValueMap}
Name : GetOwnerSid
InParameters :
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Implemented, MappingStrings, ValueMap}
Name : SetPriority
InParameters : System.Management.ManagementBaseObject
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Implemented, MappingStrings, ValueMap}
Name : AttachDebugger
InParameters :
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Implemented, ValueMap}
Name : GetAvailableVirtualSize
InParameters :
OutParameters : System.Management.ManagementBaseObject
Origin : Win32_Process
Qualifiers : {Implemented, ValueMap}
Evet ha-ri-ka! Burdaki Create metodu oldukça ilgimi çekti. Ancak ilk olarak normal bir şekilde bu class'ı çağırmak istiyorum.
Get-WmiObject -Class Win32_Process
Bu komutu çalıştırdığımızda local bilgisayarımızdaki process'lerle alakalı ayrıntılı bilgiye sahip olabiliriz. Get-WmiObject -Class Win32_Process |Out-GridView daha iyi bir görünüm için grid çıktısını kullanmak isteyebilirsiniz. İsterseniz sonuçları select-object ile de düzenleyebilirsiniz ama konumuz bu değil...
İlk powershell komutumuzu hatırlayalım. Get-Help *wmi* komutu ile gelen çıktılarda Invoke-WmiMethod cmdlet'ini görmüştük. Şimdi bunu kullanmanın zamanı geldi...
PS C:\Users\Administrator> Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "notepad.exe"
__GENUS : 2
__CLASS : __PARAMETERS
__SUPERCLASS :
__DYNASTY : __PARAMETERS
__RELPATH :
__PROPERTY_COUNT : 2
__DERIVATION : {}
__SERVER :
__NAMESPACE :
__PATH :
ProcessId : 4988
ReturnValue : 0
PSComputerName :
Yukarıdaki komut aracılığı ile bir notepad.exe işlemi başlatmış olduk.
Yukarıdaki default namespace ten bahsettiğimiz kısımda bunun root/cimv2 olduğunu söylemiştik. Bundan dolayı Invoke-WmiMethod ile Win32_Process class'ını kullanırken ayrıca namespace parametresini kullanmamıza gerek kalmadı.
İlk Yorumu Siz Yapın