循环并向对象添加额外的属性

问题描述

我正在运行一个简单的脚本,以检查几台特定的服务是否正在计算机阵列上运行。除循环的每次迭代中每个“行”都出现以外,它工作正常。在这种情况下3次。如何编辑/添加到现有对象的属性?即我想为同一对象/行添加额外的属性...

ComputerName qualys Cloud Agent SplunkForwarder Service Cb Defense
------------ ------------------ ----------------------- ----------
dc01         Found              Found                   Found     
dc01         Found              Found                   Found     
dc01         Found              Found                   Found     
dc02         Found              Found                   Found     
dc02         Found              Found                   Found     
dc02         Found              Found                   Found     
ds01         Found              Found                   Found     
ds01         Found              Found                   Found     
ds01         Found              Found                   Found     


$ComputerName = 'dc01','ds01','dc02'
$ServiceList ='qualys Cloud Agent','SplunkForwarder Service','Cb Defense'

$objarray = @()
$obj = @()
$ServiceArray = get-service -ComputerName $ComputerName -displayName $ServiceList  |  select-object -property MachineName,displayName,Name,Status

Foreach ($Computer in $ComputerName){

    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $Computer

    Foreach($Service in $ServiceList){
        If ((gsv -computername $computer -displayname $Service).Status -eq 'Running'){
            #write-output "Found $Service on $Computer"
            $obj | Add-Member -MemberType NoteProperty -Name $service -Value 'Found'
            $objArray += $obj        
        }
        else{
            #write-output "Not  Found"
            $obj | Add-Member -MemberType NoteProperty -Name $service -Value 'Not Found'
            $objArray += $obj
        }
    }


}

$objarray | sort computername

解决方法

$objArray += $obj语句移到内部循环之外-这样,每个对象仅由数组一次引用:

Foreach ($Computer in $ComputerName){
    $obj = New-Object PSObject
    $obj | Add-Member -MemberType NoteProperty -Name "ComputerName" -Value $Computer

    Foreach($Service in $ServiceList){
        If ((gsv -computername $computer -displayname $Service).Status -eq 'Running'){
            #write-output "Found $Service on $Computer"
            $obj | Add-Member -MemberType NoteProperty -Name $service -Value 'Found'
        }
        else{
            #write-output "Not  Found"
            $obj | Add-Member -MemberType NoteProperty -Name $service -Value 'Not Found'
        }
    }
    
    # Only need to add the resulting object ONCE
    $objArray += $obj        
}

我个人更喜欢将每个对象属性列表构造为一个字典,然后在循环的最后将其转换+输出-在这一点上,我们只需将的结果分配给整个foreach()语句更改为所需变量:

$objArray = foreach($Computer in $ComputerName){
    # Create dictionary to keep track of the new properties
    $props = [ordered]@{ ComputerName = $Computer}

    foreach($Service in $ServiceList){
        # Populate dictionary with remaining properties inside the inner loop
        if((gsv -computername $computer -displayname $Service).Status -eq 'Running'){
            $props["$service"] = 'Found'
        }
        else{
            $props["$service"] = 'Not Found'
        }
    }
    
    # convert to object,[pscustomobject]$props
}
,

如果要向对象添加属性,请将对象通过管道传递给“ add-member”。这是一个简单的示例:

$files = Get-childitem "$env:USERPROFILE\Documents\*"
Foreach ($item in $files)
{
    $item | Add-Member -MemberType NoteProperty -Name "extention" -Value $item.Name.Substring($item.name.Length - 3)
}
$files.extention