Powershell 从头开始创建二维系统阵列

Powershell 从头开始创建二维系统阵列,powershell,Powershell,我总是落入这个陷阱。这只是最新的例子。 我有这段代码,它提取了系统阵列中安装的SCCM2007组件的版本: $envComputerName = $env:COMPUTERNAME [System.Management.ManagementObject]$AgentGUID = Get-WmiObject -Computer $envComputerName -Namespace root\ccm -Class CCM_Client -ErrorAction Stop [System.Manag

我总是落入这个陷阱。这只是最新的例子。 我有这段代码,它提取了系统阵列中安装的SCCM2007组件的版本:

$envComputerName = $env:COMPUTERNAME
[System.Management.ManagementObject]$AgentGUID = Get-WmiObject -Computer $envComputerName -Namespace root\ccm -Class CCM_Client -ErrorAction Stop
[System.Management.ManagementObject]$ScanSource = Get-WmiObject -Computer $envComputerName -Namespace root\ccm\SoftwareUpdates\WUAhandler -Class CCM_UpdateSource -ErrorAction Stop
[System.Array]$InstalledComponents = Get-WmiObject -Computer $envComputerName -Namespace root\ccm -Class CCM_InstalledComponent -ErrorAction Stop
$HighestComponentVer = $InstalledComponents | sort version | select version -last 1
[Array]$MyInstalledComponents = $InstalledComponents | sort DisplayName | select DisplayName,Name,version
这个系统数组真正精巧的地方在于列被标记为

#DisplayName                                                  Name                                                         version      
#-----------                                                  ----                                                         -------      
#CCM Framework                                                CcmFramework                                                 4.0.6487.2196
#CCM Policy Agent                                             CcmPolicyAgent                                               4.0.6487.2000
#CCM Status Agent                                             CcmStatusAgent                                               4.0.6487.2000
#SMS Client Core Components                                   SmsClient                                                    4.0.6487.2000
#SMS Operating System Deployment                              SmsOSDeployment                                              4.0.6487.2000
#SMS OutOfBand Management Agent                               SmsOutOfBandManagement                                       4.0.6487.2000
#SMS Power Management Agent                                   SmsPowerManagement                                           4.0.6487.2157
#SMS Remote Control Agent                                     SmsRemoteTools                                               4.0.6487.2000
#SMS Shared Components                                        SmsCommon                                                    4.0.6487.2000
#SMS Software Distribution Agent                              SmsSoftwareDistribution                                      4.0.6487.2160
#SMS Software Metering Agent                                  SmsSoftwareMetering                                          4.0.6487.2000
#SMS Software Updates Agent                                   SmsSoftwareUpdate                                            4.0.6487.2188
#SMS Source List Update Agent                                 SmsSourceUpdateAgent                                         4.0.6487.2000
#SMS Task Sequence                                            SmsTaskSequence                                              4.0.6487.2179
见鬼,即使这样也行:
$MyInstalledComponents.version

我想比较这些版本,需要创建另一个系统阵列进行比较。我所能做的就是:

$SCCM2007ComponentMinVersions = 
@("CCM Framework","CcmFramework","4.0.6487.2196"),
("CCM Policy Agent","CcmPolicyAgent","4.0.6487.2000"),
("CCM Status Agent","CcmStatusAgent","4.0.6487.2000"),
("SMS Client Core Components","SmsClient","4.0.6487.2000"),
("SMS Inventory Agent","SmsInventory","4.0.6487.2184"),
("SMS Operating System Deployment","SmsOSDeployment","4.0.6487.2000"),
("SMS OutOfBand Management Agent","SmsOutOfBandManagement","4.0.6487.2000"),
("SMS Power Management Agent","SmsPowerManagement","4.0.6487.2157"),
("SMS Remote Control Agent","SmsRemoteTools","4.0.6487.2000"),
("SMS Shared Components","SmsCommon","4.0.6487.2000"),
("SMS Software Distribution Agent","SmsSoftwareDistribution","4.0.6487.2160"),
("SMS Software Metering Agent","SmsSoftwareMetering","4.0.6487.2000"),
("SMS Software Updates Agent","SmsSoftwareUpdate","4.0.6487.2188"),
("SMS Source List Update Agent","SmsSourceUpdateAgent","4.0.6487.2000"),
("SMS Task Sequence","SmsTaskSequence","4.0.6487.2179")
但这是一个系统阵列的系统阵列。而且我的列也没有标签

是否有一种从头开始创建的方法,或者只有在PowerShell命令或WMI返回阵列时才能获取标签?如果是,为什么?
执行此操作的正确方法是什么?

调用返回的值不是二维数组,而是具有属性的对象数组,这就是为什么您可以获得列名并使用点表示法

您可以从
[hashtable]
创建
[PSObject]
,并拥有以下内容的数组:

$SCCM2007ComponentMinVersions = @(
    @{
        DisplayName = "CCM Framework"
        Name = "CcmFramework"
        Version = "4.0.6487.2196"
    },
    @{
        DisplayName = "CCM Policy Agent"
        Name = "CcmPolicyAgent"
        Version = "4.0.6487.2000"
    }
)
这就形成了一个
[hashtable]
数组,这可能就足够了。要制作
[PSObjects]

$SCCM2007ComponentMinVersions = @(
    [PSCustomObject]@{
        DisplayName = "CCM Framework"
        Name = "CcmFramework"
        Version = "4.0.6487.2196"
    },
    [PSCustomObject]@{
        DisplayName = "CCM Policy Agent"
        Name = "CcmPolicyAgent"
        Version = "4.0.6487.2000"
    }
)

最好的方法是创建具有命名属性的对象数组

  • $var=@()
    生成一个数组
  • $var=@{Key=“Value”}
    生成哈希表
  • $var=new object psobject-property$hashtable
    创建一个新对象,该对象具有与给定hashtable对应的命名属性
考虑到这一点,请查看以下内容:

$SCCM2007ComponentMinVersions = @(
    (new-object psobject -property @{DisplayName="CCM Framework";Name="CcmFramework";Version="4.0.6487.2196"}),
    (new-object psobject -property @{DisplayName="CCM Policy Agent";Name="CcmPolicyAgent";Version="4.0.6487.2000"})
)
这将为您提供一个可以很好地操作的对象数组

PS H:\> $SCCM2007ComponentMinVersions 

DisplayName        Version        Name
-----------        -------        ----
CCM Framework      4.0.6487.2196  CcmFramework
CCM Policy Agent   4.0.6487.2000  CcmPolicyAgent

另外一个好处是,当通过管道连接到导出CSV(或者如果您只想在控制台中测试它,则可以通过管道连接到CSV)和类似的表格数据显示方法时,这种类型的数据结构非常有效。

WMI查询的结果是一个对象数组,所有对象都具有属性
DisplayName
名称
版本
。这就是为什么你有专栏。要快速为您的最低组件版本创建类似的阵列,我将使用:

$SCCM2007ComponentMinVersions = @'
"DisplayName","Name","Version"
"CCM Framework","CcmFramework","4.0.6487.2196"
"CCM Policy Agent","CcmPolicyAgent","4.0.6487.2000"
"CCM Status Agent","CcmStatusAgent","4.0.6487.2000"
"SMS Client Core Components","SmsClient","4.0.6487.2000"
"SMS Inventory Agent","SmsInventory","4.0.6487.2184"
"SMS Operating System Deployment","SmsOSDeployment","4.0.6487.2000"
"SMS OutOfBand Management Agent","SmsOutOfBandManagement","4.0.6487.2000"
"SMS Power Management Agent","SmsPowerManagement","4.0.6487.2157"
"SMS Remote Control Agent","SmsRemoteTools","4.0.6487.2000"
"SMS Shared Components","SmsCommon","4.0.6487.2000"
"SMS Software Distribution Agent","SmsSoftwareDistribution","4.0.6487.2160"
"SMS Software Metering Agent","SmsSoftwareMetering","4.0.6487.2000"
"SMS Software Updates Agent","SmsSoftwareUpdate","4.0.6487.2188"
"SMS Source List Update Agent","SmsSourceUpdateAgent","4.0.6487.2000"
"SMS Task Sequence","SmsTaskSequence","4.0.6487.2179"
'@ | ConvertFrom-Csv | Select-Object DisplayName, Name, @{n="Version";e={ $_.Version -as [version] }}
样本输出:

PS C:\Users\frode> $SCCM2007ComponentMinVersions

DisplayName                     Name                    Version      
-----------                     ----                    -------      
CCM Framework                   CcmFramework            4.0.6487.2196
CCM Policy Agent                CcmPolicyAgent          4.0.6487.2000
CCM Status Agent                CcmStatusAgent          4.0.6487.2000
这还将
Version
转换为一个版本对象,该对象可以轻松地与其他版本对象进行比较(您需要从
CCM\u InstalledComponents
转换字符串值,请参见下面的示例)。但就个人而言,我会使用一个哈希表,而不是一个最小版本列表,因为它更容易与之后的列表进行比较。例:

#Create hashtable for minimumversions
$SCCM2007ComponentMinVersions = @{}

#Fill hashtable with csv-data
@'
"DisplayName","Name","Version"
"CCM Framework","CcmFramework","4.0.6487.2196"
"CCM Policy Agent","CcmPolicyAgent","4.0.6487.2000"
"CCM Status Agent","CcmStatusAgent","4.0.6487.2000"
"SMS Client Core Components","SmsClient","4.0.6487.2000"
"SMS Inventory Agent","SmsInventory","4.0.6487.2184"
"SMS Operating System Deployment","SmsOSDeployment","4.0.6487.2000"
"SMS OutOfBand Management Agent","SmsOutOfBandManagement","4.0.6487.2000"
"SMS Power Management Agent","SmsPowerManagement","4.0.6487.2157"
"SMS Remote Control Agent","SmsRemoteTools","4.0.6487.2000"
"SMS Shared Components","SmsCommon","4.0.6487.2000"
"SMS Software Distribution Agent","SmsSoftwareDistribution","4.0.6487.2160"
"SMS Software Metering Agent","SmsSoftwareMetering","4.0.6487.2000"
"SMS Software Updates Agent","SmsSoftwareUpdate","4.0.6487.2188"
"SMS Source List Update Agent","SmsSourceUpdateAgent","4.0.6487.2000"
"SMS Task Sequence","SmsTaskSequence","4.0.6487.2179"
'@ | ConvertFrom-Csv | ForEach-Object { $SCCM2007ComponentMinVersions.Add($_.Name, ($_.Version -as [version])) }

#Sample WMI-output
$InstalledComponents = @'
"DisplayName","Name","Version"
"CCM Framework","CcmFramework","4.0.6487.2195"
"CCM Policy Agent","CcmPolicyAgent","4.0.6487.2000"
'@ | ConvertFrom-Csv 


#Find old components
$InstalledComponents | Where-Object { ($_.Version -as [version]) -lt $SCCM2007ComponentMinVersions[$_.Name] }
输出:

DisplayName   Name         Version
-----------   ----         -------
CCM Framework CcmFramework 4.0.6487.2195

我不知道你想对比什么版本。我收集到,
$myinstalledcomponents
是比较对象之一,但另一个是什么?FWIW,通常人们称PS中的数组为“数组”。您可以创建和操作PS阵列,而无需显式使用System.Array。这不是我想要的,而是我需要的!非常感谢。