CIM Cmdlet 一些提示和技巧
获取所有CIM Cmdlet
Get-Command -Module CimCmdlets
Tip1: 使用CIM会话
CIM会话是代表到本地或远程计算机的连接的客户端对象。CIM会话包含有关连接的信息,例如ComputerName,用于连接的协议,会话ID和实例ID。
当您尝试连接到远程计算机时,可能必须通过凭据。使用凭证创建CIM会话时,New-CimSession
cmdlet将使用PSCredential对象。PSCredential对象的构造函数只接受安全密码字符串。
提示时输入密码
$creds = Get-Credential -Credential administrator
保存凭据以备将来使用
$creds | Export-Clixml -Path C:\creds.clixml
在需要时使用保存的凭据
$savedCreds = Import-Clixml -Path C:\creds.clixml
PowerShell远程连接指定TrustedHost
PowerShell 默认的远程连接是通过winrm
实现的。在域内很容易,一般指定域名就可以直接连接,如果希望连接工作组的机器,或者通过IP地址远程访问,那么他会报错:绕过的方法很简单,添加IP地址到指定的TrustedHost即可。
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force
Get-Item WSMan:\localhost\Client\TrustedHosts
Enter-PSSession -ComputerName 10.201.31.10 -Credential
类似的invoke-command
也可以这么做
Invoke-Command -ComputerName 10.201.31.10 {ls c:\} -Credential administrator
用Credentials创建CimSession
$session = New-CimSession -ComputerName "10.201.31.10" -Credential $savedCreds
如果添加了ComputerName参数,则使用的协议是WS-Management(WS-Man)。
如果未添加ComputerName参数,则该cmdlet将使用DCOM/COM
创建DCOM会话
$session = New-CimSession
通过DCOM执行枚举
$inst = Get-CimInstance Win32_OperatingSystem
如果添加ComputerName,则cmdlet会覆盖WS-Man
$session = New-CimSession -ComputerName localhost
$inst = Get-CimInstance Win32_OperatingSystem -ComputerName localhost
如果使用New-CimSessionOption
中的-Protocol DCOM
之外的任何参数,那么会话选项将帮助生成WS-Man会话。
DCOM会话
$sessionOp = New-CimSessionOption -Protocol Dcom
$sessionDcom = New-CimSession -SessionOption $sessionDcom -ComputerName localhost
WS-Man Session:添加到New-CimSessionOption命令的参数UseSSL指定WS-Man协议
$sessionOp2 = New-CimSessionOption -UseSsl
$sessionWSMAN = New-CimSession -SessionOption $sessionOp2 -ComputerName localhost
New-CimSessionOption命令中的Default协议对应于WS-Man。
使用默认协议创建一个CimSession
New-CimSession -ComputerName localhost -SessionOption (New-CimSessionOption -Protocol Default)
如果您正在执行大量的远程操作,我建议您重用会话。这可以提供显着的性能增益。
使用computerName执行Get-CimInstance
$time1 = Measure-Command {1..100 | %{Get-CimInstance -ClassName CIM_ComputerSystem -ComputerName localhost} }
创建一个CimSession
$session = New-CimSession -ComputerName localhost
$time2 = Measure-Command {1..100 | %{Get-CimInstance -ClassName CIM_ComputerSystem -CimSession $session}}
在上面的示例中,$time1 > $time2,因为每次使用ComputerName参数的Get-CimInstance cmdlet调用都会在hood下创建一个CIM会话。
在第二种情况下,在我们使用明确创建的CIM会话的情况下,在每次调用中创建CIM会话的成本都不存在。
Tip2:Fan-out
使用多个服务器
所有CIM cmdlet都接受一系列CIM会话或计算机名称。这些可用于在一行中的多个服务器上执行操作。
创建多个会话
$allSessions = New-CimSession -ComputerName "10.201.31.10", "localhost" -Credential administrator
使用CIM会话阵列
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $allSessions
报错:Get-CimInstance : WS-Management 服务无法处理该请求。使用 DMTF 资源 URI 访问的是非 DMTF 类。请使用非 DMTF 资源 URI 重试。
重新启动一行中的所有机器
显示Win32_OperatingSystem方法的定义代码
Get-CimClass Win32_OperatingSystem|select CimClassMethods|Format-Custom
查看Win32_OperatingSystem类方法
Get-CimClass Win32_OperatingSystem|select CimClassMethods
Invoke-CimMethod -ClassName Win32_OperatingSystem -MethodName Reboot -CimSession $allSessions
或
Invoke-CimMethod -ClassName Win32_OperatingSystem -MethodName Reboot -ComputerName "10.201.31.10","10.202.34.11",localhost
如果您使用管道,则不必通过会话。实例是机器感知的
如果从一个cmdlet接收到的实例通过管道连接到另一个cmdlet,则管道右侧的cmdlet无需指定计算机名称或CIM会话,因为这些实例是机器感知的。管道右侧的cmdlet可以从实例中提取与机器相关的信息。
从类中获取实例
$session = New-CimInstance -ComputerName machine1
Get-CimInstance -Query "select * from TestClass where v_key = 2" -Namespace root/test -CimSession $session
传递CIM实例
$props = @{boolVal = $true}
$inst | Set-CimInstance -CimInstance $inst -Property $props
进入设置的管道结果
Get-CimInstance -Query "select * from TestClass where v_key = 2" -Namespace root/test -CimSession $session | Set-CimInstance -CimInstance $inst -Property $props
Tips3:使用非Windows CIMOM
连接到需要资源URI的设备
某些供应商支持非DMTF 资源URI(这里DMTF代表分布式管理任务组),但使用ClassName的CIM cmdlet参数集可能无法在该场景中使用。CIM cmdlet提供了一个接受非DMTF资源URI的参数集,并允许您管理这些设备。以下示例演示了这一点:
非DMTF资源URI
$resourceuri = "http://intel.com/wbem/wscim/1/amt-schema/1/AMT_PETFilterSetting"
获取实例
$inst = Get-CimInstance -Namespace $namespace -ResourceUri $resourceuri -CimSession $session
查询实例
$inst = Get-CimInstance -Query $query -Namespace $namespace -ResourceUri $resourceuri -CimSession $session
修改实例
$propsToModify = @{LogOnEvent=$false}
Set-CimInstance -InputObject $inst -Property $ propsToModify -ResourceUri $resourceuri -CimSession $session
如果公共信息模型对象管理器(CIMOM)不支持TestConnection,则New-CimSession
命令将失败。如何确保可以使用这种CIMOM创建会话?
当服务器/CIMOM不支持TestConnection时,创建CIM会话
$session = New-CimSession -CN "10.201.31.10" -Credential $creds -SkipTestConnection
如果CIMOM正在监听非默认端口的端口,则可以确保New-CimSession调用特定端口。
Windows上WS-Man的默认HTTP端口
$httpPort = 5985
Windows上WS-Man的默认HTTPS端口
$httpsPort = 5986
Port参数由New-CimSession指定,而不是New-CimSessionOption指定
$session = New-CimSession -CN "10.201.31.10" -Credential $creds -Port $httpPort
如果使用HTTPS
$sop = New-CimSessionOption -UseSsl
$session = New-CimSession -CN "10.201.31.10" -Credential $creds -Port $httpsPort
Tips4:获取关联的实例
在CIM世界中,关联是重要的,因为它们定义了两个类之间的关系。Get-CimAssociatedInstance
提供了一种计算这些关系的方法。
获取DriveType = 3
的Win32_LogicalDisk
类的实例(硬盘驱动器)
$disks = Get-CimInstance -class Win32_LogicalDisk -Filter 'DriveType = 3'
获取与此磁盘关联的所有实例
Get-CimAssociatedInstance -CimInstance $disks[0]
获取特定类型的实例
Get-CimAssociatedInstance -CimInstance $disks[0] -ResultClassName Win32_DiskPartition
通过特定的CIM关系查找关联的实例
Get-CimAssociatedInstance -CimInstance $disks[0] -Association Win32_LogicalDiskRootDirectory
Tips5:传递ref和嵌入式实例
你知道吗?如果您将实例作为REF传递,则只有关键值通过基础结构传递给提供者; 例如,即使所有属性都在实例内部填充,提供者也只能看到键值。
REF数组有一些边缘情况。
如果使用New-CimInstance
命令中的 ClientOnly
参数创建实例,并将其传递到需要REF数组的方法中,我们应该将其转换为ref[]
。
用New-CimInstance -ClientOnly
创建一个实例:类型将其转换为[ref[]]
$inst1 = New-CimInstance –className foo –Namespace root/test –Property @{A= 1; B= 2} –ClientOnly
$inst2 = New-CimInstance –ClassName foo –Namespace root/test –Property @{A= 3; B= 4} –ClientOnly
$instArray = @($inst1, $inst2)
Invoke-CimMethod –ClassName Class1 –Namespace root/test –Method MethodRefArray –Property @{vals = [ref[]] $instArray}
如果实例来自Get-CimInstance
,并且与服务器对象相同,则应该通过将该实例数组类型化为Ciminstance[]
来完成方法调用。
从Get-CimInstance获取实例:将它转换为[Ciminstance[]]
$inst = Get-CimInstance –ClassName foo –Namespace root/test
Invoke-CimMethod –ClassName Class1 –Namespace root/test –Method MethodRefArray –Property @{vals = [Ciminstance[]] $inst}
下一个示例显示调用带有嵌入式实例的方法。
$nums = New-CimInstance –ClassName numbers -Namespace root/test -Property @{numbers = @([int64]5 , [int64]6); count = [uint32]2} –Local
Invoke-CimMethod -ClassName TestCalculator -MethodName AddNumbers -Arguments @{numbers = $nums} –Namespace root/test
$nums2 = Get-CimInstance –ClassName numbers -Namespace root/test
Invoke-CimMethod -ClassName TestCalculator -MethodName AddNumbers -Arguments @{numbers = [CimInstance] $nums} -NS root/test
Tips6:使用指示
接收指示允许开发人员通知消费应用程序某些系统配置数据已更改,而不必为此数据连续轮询Windows Management Instrumentation(WMI)。从CIM cmdlet层,注册指示很容易。以下脚本块介绍了如何注册,获取和取消订阅指示。
注册一个事件
Register-CimIndicationEvent -ClassName Win32_ComputerShutdownEvent -Namespace root/CIMV2
获取到目前为止产生的所有事件
$x = Get-Event
取消注册特定事件
$sourceID = $x[0].SourceIdentifier
Unregister-Event -SourceIdentifier $sourceID
清理迄今收到的所有事件
Remove-Event *
要么
定义你自己的SID
$sid = “TestSID”
Register-CimIndicationEvent -ClassName Test_IndicationClass -Namespace root\test –SourceIdentifier $sid
$x = Get-Event –SourceIdentifier $sid
Unregister-Event -SourceIdentifier $sid
Tips7:类型转换/使用日期时间/使用UInt8
在使用散列表作为CIM cmdlet参数的输入时,您可能需要对正在传递的数据进行类型转换。这里的简单规则是:
— 如果在运行cmdlet时传递类模式,则会在运行时发现数据类型,因此不必显式转换值。
— 如果类schema未传递,则使用缺省数据类型,这可能会在运行cmdlet时导致失败。在这种情况下需要类型转换。
以下示例代码阐明了这一点:
Invoke-CimMethod -ClassName TestCalculator -Namespace root/test -MethodName Add –Arguments @{Left = 4; right=5}
报错
Invoke-CimMethod:参数Left
的类型不匹配,如果Left和Right是SInt64值
上面的失败发生是因为默认所有值都被视为UInt32。
Invoke-CimMethod -ClassName TestCalculator -Namespace root/test -MethodName Add –Arguments @{Left = [int64]4; right=[int64]5}
如果使用CimClass参数,则不需要类型转换。
$c = Get-CimClass -Namespace root/test -ClassName TestCalculator
Invoke-CimMethod -CimClass $c -MethodName Add -Arguments @{Left = 4; right=5}
在使用任何DateTime类型参数时,我们必须对DateTime的字符串表示形式进行类型转换。同样,在传入一个值为UInt8的值时,我们必须将其转换为Byte。
$inst = New-CimInstance -ClassName TestClass -Namespace root\test -Key v_uint8 -Property @{ v_uint8 = [byte] 3; v_dateTime = [DateTime] “12/31/1899 3:59:59 PM” }
Tips8:传递操作选项
无法通过CIM cmdlet将操作选项值传递给WMI提供程序。要将operationOptions值传递给您的提供者,您可能必须采取以下过程:
$s = New-CimSession
创建MethodParameterCollection
$x = New-Object Microsoft.Management.Infrastructure.CimMethodParametersCollection
$param = [Microsoft.Management.Infrastructure.CimMethodParameter]::Create("number", 40, [Microsoft.Management.Infrastructure.CimType]::UInt64, [Microsoft.Management.Infrastructure.CimFlags]::None)
$x.Add($param)
创建一个OperationOption对象
$operationOption = new-object Microsoft.Management.Infrastructure.Options.CimOperationOptions
$operationOption.SetCustomOption("TEST_SET_NAMESPACE", $true, $false)
调用该方法
$s.InvokeMethod(“root/test”, “TestalCalculator”, “PrimeFactors”, $x, $operationOption)
$returnVal.OutParameters[“factors”].Value.CimSystemProperties
Tips9 AssociationClass
的实例只有对关联两端的引用,而不是实际的实例。
当枚举关联类的实例时,返回的属性包含对该关联的两个端点的引用。由于这些属性仅供参考,因此仅填充关键值。
Get-CimInstance Win32_DiskDriveToDiskPartition Antecedent : Win32_DiskDrive (DeviceID = "\\.\PHYSICALDRIVE0") Dependent : Win32_DiskPartition (DeviceID = "Disk #0, Partition#2")
Tips10:让Get/Enumerate高效
通过使用-ClientOnly
创建实例来保存往返行程
如果实例的键值已知,并且预期的操作是从服务器获取实例,则用户可以创建一个ClientOnly类实例,然后在其上运行Get-CimInstance。这节省了一次往返服务器的时间。
$instLocal = New-CimInstance –className foo –Namespace root/test –Property @{A= 1; B= 2} –ClientOnly
$instFromServer = Get-CimInstance –InputObject $instLocal –CimSession $session
只获取关键属性
如果不需要整个实例,并且意图只是检查实例的关键属性,则用户可以只根据需要获取实例的关键属性。
$inst = Get-CimInstance -ClassName Win32_Process -KeyOnly
这可以用来调用一个方法
Invoke-CimMethod -InputObject $inst -MethodName “Terminate”
此处执行报错
Invoke-CimMethod : Cannot convert 'System.Object[]' to the type 'Microsoft.Management.Infrastructure.CimInstance' required by parameter 'InputObject'. Specified method is not supported.
如何刷新PowerShell中的实例数据,而无需再次获取WMI对象。
原始对象保持不变,但数据刷新。
获取一个类的实例
$p = Get-CimInstance -ClassName Win32_PerfFormattedData_PerfOS_Processor
通过传递先前收到的实例再次执行获取,并获取更新的属性。$p的值保持不变。
$p | Get-CimInstance | select -Property PercentProcessorTime
我希望这些技巧和窍门能够让您更好地体验CIM cmdlet。如果您对这些cmdlet有任何疑问,请随时告诉我们。
谢谢
Vaibhav Chugh [MSFT]
原文链接:CIM Cmdlets – Some Tips & Tricks
来源:freebuf.com 2018-06-12 14:49:16 by: scala
请登录后发表评论
注册