CIM Cmdlet 一些提示和技巧 – 作者:scala

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

创建DCO​​M会话

$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 = 3Win32_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

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论