Avatar of TeekayShipping
TeekayShipping
Flag for United Kingdom of Great Britain and Northern Ireland asked on

Adding member to an array

Hello,

Hoping someone can help as i cant find an answer to this. In PowerShell i'm trying to add a new proprty to an array i have imported:

To confirm it looks like this when its imported:

PS C:\Windows\system32> $ImportedForAppend

ConnectionName : AlexanderSpirit 10.13.126.0 (vessel) (Not being upgraded)
ID             : 9c503373-a37f-4f08-9cce-748721b0238e
Status         : DOWN   :-(  25-02:1224
IP             : 10.13.126.250
PingNumber     : 0
TimeStamp      : 25-02-2020:1224

ConnectionName : BahrainSpirit 10.12.24.0 (vessel)
ID             : 8d2ce4a0-bacc-477d-89ca-a02f8d1014fd
Status         : FAST 174ms 25-02:1224
IP             : 10.12.24.250
PingNumber     : 174
TimeStamp      : 25-02-2020:1224

ConnectionName : BarcelonaSpirit 10.12.18.0 (vessel)
ID             : c7a783b5-e650-4023-a58b-2739038b1b8b
Status         : FAST 737ms 25-02:1224
IP             : 10.12.18.250
PingNumber     : 737
TimeStamp      : 25-02-2020:1224


PS C:\Windows\system32> $ImportedForAppend.GetType();

IsPublic IsSerial Name                                     BaseType                                                                                                                                                                                              
-------- -------- ----                                     --------                                                                                                                                                                                              
True     True     Object[]                                 System.Array        
             


Now i'm trying to add a new property to the array with an updated time stamp and a new ping number, so it looks like this:

ConnectionName : AlexanderSpirit 10.13.126.0 (vessel) (Not being upgraded)
ID             : 9c503373-a37f-4f08-9cce-748721b0238e
Status         : DOWN   :-(  25-02:1224
IP             : 10.13.126.250
PingNumber     : 0
TimeStamp      : 25-02-2020:1224
25-02-2020:1250:    677

ConnectionName : BahrainSpirit 10.12.24.0 (vessel)
ID             : 8d2ce4a0-bacc-477d-89ca-a02f8d1014fd
Status         : FAST 174ms 25-02:1224
IP             : 10.12.24.250
PingNumber     : 174
TimeStamp      : 25-02-2020:1224
25-02-2020:1250:   1344

ConnectionName : BarcelonaSpirit 10.12.18.0 (vessel)
ID             : c7a783b5-e650-4023-a58b-2739038b1b8b
Status         : FAST 737ms 25-02:1224
IP             : 10.12.18.250
PingNumber     : 737
TimeStamp      : 25-02-2020:1224
25-02-2020:1250:     566


Question is how to target a specific "ConnectionName" and add a new property with the name/value so the layout stays the same?

I know i can use the below to add a new member but its adding a property to each group and i want to only target certain ones:

$ImportedForAppend | Add-Member -MemberType NoteProperty -Name $Vessel.TimeStamp -Value $CurrentStatusList.PingNumber


ConnectionName  : AlexanderSpirit 10.13.126.0 (vessel) (Not being upgraded)
ID              : 9c503373-a37f-4f08-9cce-748721b0238e
Status          : DOWN   :-(  25-02:1253
IP              : 10.13.126.250
PingNumber      : 0
TimeStamp       : 25-02-2020:1253
Test            : 455

ConnectionName  : BahrainSpirit 10.12.24.0 (vessel)
ID              : 8d2ce4a0-bacc-477d-89ca-a02f8d1014fd
Status          : FAST 221ms 25-02:1253
IP              : 10.12.24.250
PingNumber      : 221
TimeStamp       : 25-02-2020:1253
Test            : 455

ConnectionName  : BarcelonaSpirit 10.12.18.0 (vessel)
ID              : c7a783b5-e650-4023-a58b-2739038b1b8b
Status          : FAST 674ms 25-02:1253
IP              : 10.12.18.250
PingNumber      : 674
TimeStamp       : 25-02-2020:1253
Test            : 455

                                                                                                                                                                   
How to add only one extra property as below to say the "ConnectionName" "BarcelonaSpirit 10.12.18.0 (vessel)"

ConnectionName  : AlexanderSpirit 10.13.126.0 (vessel) (Not being upgraded)
ID              : 9c503373-a37f-4f08-9cce-748721b0238e
Status          : DOWN   :-(  25-02:1253
IP              : 10.13.126.250
PingNumber      : 0
TimeStamp       : 25-02-2020:1253

ConnectionName  : BahrainSpirit 10.12.24.0 (vessel)
ID              : 8d2ce4a0-bacc-477d-89ca-a02f8d1014fd
Status          : FAST 221ms 25-02:1253
IP              : 10.12.24.250
PingNumber      : 221
TimeStamp       : 25-02-2020:1253
Test            : 455

ConnectionName  : BarcelonaSpirit 10.12.18.0 (vessel)
ID              : c7a783b5-e650-4023-a58b-2739038b1b8b
Status          : FAST 674ms 25-02:1253
IP              : 10.12.18.250
PingNumber      : 674
TimeStamp       : 25-02-2020:1253
Powershell

Avatar of undefined
Last Comment
TeekayShipping

8/22/2022 - Mon
oBdA

That's not a way to treat object properties, and you will lose the layout, because you'll have all kinds of different objects.
If you're processing an array with objects, you should make sure every object has the same properties.
So depending on how you want to process this further, I'd suggest to ...

a. either add one string property to each object with the concatenated values, like
Prop = "$Vessel.TimeStamp = $CurrentStatusList.PingNumber"

or b. add two properties to each object, like
Prop1 = $Vessel.TimeStamp
Prop2 = $CurrentStatusList.PingNumber

In both cases, the objects in this array you don't want to process can be left empty.
Which one do you need?
TeekayShipping

ASKER
Hello,

Thanks for the help!

I have added a new property with the time stamp so now every time i run the script its adding the date which is what i want.

How do i then update the value of each property individually?

ConnectionName  : AlexanderSpirit 10.13.126.0 (vessel) (Not being upgraded)
ID              : 9c503373-a37f-4f08-9cce-748721b0238e
Status          : DOWN   :-(  25-02:1418
IP              : 10.13.126.250
PingNumber      : 0
TimeStamp       : 25-02-2020:1418
25-02-2020:1418 :
25-02-2020:1419 :

ConnectionName  : BahrainSpirit 10.12.24.0 (vessel)
ID              : 8d2ce4a0-bacc-477d-89ca-a02f8d1014fd
Status          : FAST 225ms 25-02:1418
IP              : 10.12.24.250
PingNumber      : 225
TimeStamp       : 25-02-2020:1418
25-02-2020:1418 :
25-02-2020:1419 :

ConnectionName  : BarcelonaSpirit 10.12.18.0 (vessel)
ID              : c7a783b5-e650-4023-a58b-2739038b1b8b
Status          : FAST 679ms 25-02:1418
IP              : 10.12.18.250
PingNumber      : 679
TimeStamp       : 25-02-2020:1418
25-02-2020:1418 :
25-02-2020:1419 :

Maybe it will help to explain a bit more. I would like to export the results to a text file each time (the same results that get imported to start with) so that i have a history of results. I would like the script to append the ping results to the CSV each time and i thought the best way to do that would be to import it into an array and then work with the array and then export again.

When i export to a CSV it looks like the attached when i open it, i just need to update the date/time stamp column with the ping number which i thought would be easiest to do before the export.

Thanks
Capture.JPG
David Johnson, CD

where is ping number coming from? For timestamp what do you want? Time Tested? 

If Png is UP update timestamp otherwise don't update timestamp? 


do you have any code that we could work from? 



Your help has saved me hundreds of hours of internet surfing.
fblack61
TeekayShipping

ASKER
Hello,

Thanks for the reply, here is the script that is working just now. It basically tests the connection of a list of vessels. The list is pulled from another script. I have attached the current IP list its using.

Basically i'm trying to make it so that when it tests a connection that it saves that data to a growing CSV file so we can track the connection quality.

Import-Module "${env:ProgramFiles(x86)}\Devolutions\Remote Desktop Manager\RemoteDesktopManager.PowerShellModule.psd1"

$IPListImport = @()
$CompleteStatusList = @()
#PUll the session ID and IP from all the connections in the database so that the workflow can use this

$ExportCSVPath = "C:\RDM_Scripts\IPList.csv"

$IPListImport = Import-CSV $ExportCSVPath

Remove-Item "C:\RDM_Scripts\ConnectionStatus\*.txt" | Where { ! $_.PSIsContainer }

#Workflow to test the conenction on 20 vessels at a time

Workflow CheckConnections
{
Param ($IPListImport)

ForEach -Parallel -Throttle 20 ($Connection in $IPListImport){

$VesselIPworkflow = $null
$CurrentSessionIDworkflow = $null
$ConnectionNameworkflow = $null

$VesselIPworkflow = $Connection.VesselIP
$CurrentSessionIDworkflow = $Connection.CurrentSessionID
$ConnectionNameworkflow = $Connection.ConnectionName


#Test the connection and get the average

$ConnectionStatus = Test-Connection -ComputerName $VesselIPworkflow -Count 6 -ErrorAction SilentlyContinue

$ConnectionStatusRaw = $ConnectionStatus.ResponseTime

$ConnectionStatusAvg = $ConnectionStatusRaw | Measure-Object -Average

$ConnectionStatusNumber = [math]::Round($ConnectionStatusAvg.Average)


#Test for ping degradation

$ConnectionSuccess = $ConnectionStatusRaw | Measure-Object -Line

$ConnectionSuccessLines = $ConnectionSuccess.Lines

$ConnectionDrops = 6 - $ConnectionSuccessLines

$ConnectionStatusDegraded = $null

#Set the status

if ($ConnectionStatus) {

If ($ConnectionStatusNumber -lt 1000) {$ConnectionStatusSimple = "FAST "}
Else {Write-Output "Connection Status Set To" + $ConnectionStatusSimple}

If (($ConnectionStatusNumber -gt 1000) -AND ($ConnectionStatusNumber -lt 2000)) {$ConnectionStatusSimple = "MED "}
Else {Write-Output "Connection Status Set To" + $ConnectionStatusSimple}

If ($ConnectionStatusNumber -gt 2000) {$ConnectionStatusSimple = "SLOW "}
Else {Write-Output "Connection Status Set To" + $ConnectionStatusSimple}

If ($ConnectionDrops -gt 1) {$ConnectionStatusDegraded = " D"}
Else {$ConnectionStatusDegraded =$null}                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                           
}

#Write the connection Status to text files for each vessel test

  if ($ConnectionStatus) {
     $UPorDOWN = "" + $ConnectionStatusSimple + $ConnectionStatusNumber + "ms " + (GET-DATE -format dd-MM:HHmm) + $ConnectionStatusDegraded
  }
  else{
   $UPorDOWN = "DOWN   :-(  " + (GET-DATE -format dd-MM:HHmm)
  }
 
  $CurrentTime = GET-DATE -format dd-MM-yyyy:HHmm

  New-Item -ItemType Directory -Force -Path "C:\RDM_Scripts\ConnectionStatus"
  Set-Content -Path "C:\RDM_Scripts\ConnectionStatus\$ConnectionNameworkflow.txt" -Value "$CurrentSessionIDworkflow, $UPorDOWN, $VesselIPworkflow"
  Write-Output $ConnectionNameworkflow $VesselIPworkflow $UPorDOWN "ConnectionChecked" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

}

#Run the workflow and pass it the conenction list

CheckConnections $IPListImport

####WRITE TEXT FILES TO DATABASE

Get-ChildItem "C:\RDM_Scripts\ConnectionStatus" -Filter *.txt |
Foreach-Object {
   $content = import-csv "C:\RDM_Scripts\ConnectionStatus\$_" –header ID, Status, IP –delimiter ','
   $CompleteStatusList += $content
 
}



Foreach ($LastStatus in $CompleteStatusList){

$DatabaseSessionID = $LastStatus.ID
$DatabaseStatus = $LastStatus.Status
$DatabaseIP = $LastStatus.IP

Set-RDMSessionProperty -Id $DatabaseSessionID -Path MetaInformation -Property CustomField1Value -Value $DatabaseStatus

}


I believe the best time to save the data to the CSV is at the point where i have captured the current tests within the array $CompleteStatusList. I have been trying for some time to work out how best to do that.

Any help appreciated  on what the best approach is.

Thanks
Capture2.JPG
IPList.csv
ASKER CERTIFIED SOLUTION
oBdA

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
TeekayShipping

ASKER
Thanks, i added the below to the script:

$CompleteStatusList | Select ConnectionName, Status, IP, PingNumber | Export-Csv C:\RDM_Scripts\ConnectionStatus\ConnectionHistory.csv -append -NoTypeInformation

Also had to tell it to collect the connection name and full date/time stamp in the text files as well and add that to the array:  $CompleteStatusList

I will test it out and see how it looks as its added to the CSV.

Here is the completed script now:

Import-Module "${env:ProgramFiles(x86)}\Devolutions\Remote Desktop Manager\RemoteDesktopManager.PowerShellModule.psd1"

$IPListImport = @()
$CompleteStatusList = @()
#PUll the session ID and IP from all the connections in the database so that the workflow can use this

$ExportCSVPath = "C:\RDM_Scripts\IPList.csv"

$IPListImport = Import-CSV $ExportCSVPath

Remove-Item "C:\RDM_Scripts\ConnectionStatus\*.txt" | Where { ! $_.PSIsContainer }

#Workflow to test the conenction on 20 vessels at a time

Workflow CheckConnections
{
Param ($IPListImport)

ForEach -Parallel -Throttle 20 ($Connection in $IPListImport){

$VesselIPworkflow = $null
$CurrentSessionIDworkflow = $null
$ConnectionNameworkflow = $null

$VesselIPworkflow = $Connection.VesselIP
$CurrentSessionIDworkflow = $Connection.CurrentSessionID
$ConnectionNameworkflow = $Connection.ConnectionName


#Test the connection and get the average

$ConnectionStatus = Test-Connection -ComputerName $VesselIPworkflow -Count 6 -ErrorAction SilentlyContinue

$ConnectionStatusRaw = $ConnectionStatus.ResponseTime

$ConnectionStatusAvg = $ConnectionStatusRaw | Measure-Object -Average

$ConnectionStatusNumber = [math]::Round($ConnectionStatusAvg.Average)


#Test for ping degradation

$ConnectionSuccess = $ConnectionStatusRaw | Measure-Object -Line

$ConnectionSuccessLines = $ConnectionSuccess.Lines

$ConnectionDrops = 6 - $ConnectionSuccessLines

$ConnectionStatusDegraded = $null

#Set the status

if ($ConnectionStatus) {

If ($ConnectionStatusNumber -lt 1000) {$ConnectionStatusSimple = "FAST "}
Else {Write-Output "Connection Status Set To" + $ConnectionStatusSimple}

If (($ConnectionStatusNumber -gt 1000) -AND ($ConnectionStatusNumber -lt 2000)) {$ConnectionStatusSimple = "MED "}
Else {Write-Output "Connection Status Set To" + $ConnectionStatusSimple}

If ($ConnectionStatusNumber -gt 2000) {$ConnectionStatusSimple = "SLOW "}
Else {Write-Output "Connection Status Set To" + $ConnectionStatusSimple}

If ($ConnectionDrops -gt 1) {$ConnectionStatusDegraded = " D"}
Else {$ConnectionStatusDegraded =$null}                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                           
}

#Write the connection Status to text files

  if ($ConnectionStatus) {
     $UPorDOWN = "" + $ConnectionStatusSimple + $ConnectionStatusNumber + "ms " + (GET-DATE -format dd-MM:HHmm) + $ConnectionStatusDegraded
  }
  else{
   $UPorDOWN = "DOWN   :-(  " + (GET-DATE -format dd-MM:HHmm)
  }
 
  $CurrentTime = GET-DATE -format dd-MM-yyyy:HHmm

  New-Item -ItemType Directory -Force -Path "C:\RDM_Scripts\ConnectionStatus"
  Set-Content -Path "C:\RDM_Scripts\ConnectionStatus\$ConnectionNameworkflow.txt" -Value "$ConnectionNameworkflow, $CurrentSessionIDworkflow, $UPorDOWN, $VesselIPworkflow, $CurrentTime, $ConnectionStatusNumber"
  Write-Output $ConnectionNameworkflow $VesselIPworkflow $UPorDOWN "ConnectionChecked" "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

}

#Run the workflow and pass it the conenction list

CheckConnections $IPListImport

####WRITE TEXT FILES TO DATABASE

Get-ChildItem "C:\RDM_Scripts\ConnectionStatus" -Filter *.txt |
Foreach-Object {
   $content = import-csv "C:\RDM_Scripts\ConnectionStatus\$_" –header ConnectionName, ID, Status, IP, DateTime, PingNumber –delimiter ','
   $CompleteStatusList += $content
 
}


Foreach ($LastStatus in $CompleteStatusList){

$DatabaseSessionID = $LastStatus.ID
$DatabaseStatus = $LastStatus.Status
$DatabaseIP = $LastStatus.IP

Set-RDMSessionProperty -Id $DatabaseSessionID -Path MetaInformation -Property CustomField1Value -Value $DatabaseStatus

}

$CompleteStatusList | Select ConnectionName, Status, IP, DateTime, PingNumber | Export-Csv C:\RDM_Scripts\ConnectionStatus\ConnectionHistory.csv -append -NoTypeInformation