Subscribe
Accepted Solution

newbie general powershell looping question

I have a sorted csv file in the following format:

 

name, uniqueID, environment

 

server1 x123 production

server1 x234 installed

server1 x345 n/a

server2 x999 anything

 

what I want to do is read the environment for the first occurance of server1, and then update the unique identifiers via API for any subsequent occurances of the name

 

so my expected output would be  

server1  x123  production

server1 x234   production

server1 x345   production

server2  x999 anything

etc ...

 

Anyone know what type of foreach loop with a nested loop would produce such a result?

 

thanks

 

Thanks in advance

 

Re: newbie general powershell looping question

Hello @stephen2,

 

Here is a quick example I created:

 

$csv = "name,id,status
server1,x123,production
server1,x234,installed
server1,x345,n/a
server2,x999,anything"

$lines = $csv | ConvertFrom-Csv

$values = @{}
$output = New-Object System.Collections.Generic.List[System.Object]

foreach ($line in $lines) {
    if ($values.Keys -notcontains $line.name) {
        $values.Add($line.name, $line.status)
    }

    $line.status = $values.($line.name)
    $output.Add($line)
}

$output

 

Hope that helps!

 

Andrew

If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Re: newbie general powershell looping question

Thanks Andrew - using the hash table does not help because for each record, I have to maintain the id field, so I need to accomplish the following:

 

first record, store the env field and write the server, id, and env field

subsequent record - write the server, id, and saved env

 

Is it possible to accomplist the functionality using some other structure?

Re: newbie general powershell looping question

Did you execute the code?  Cause I'm not sure what you mean...it outputs correctly from what I can tell:

 

name    id   status    
----    --   ------    
server1 x123 production
server1 x234 production
server1 x345 production
server2 x999 anything  

The hash is only used to store the first name -> status and keep them for later.  I'm assuming that the names are not always in order, e.g there could be another "server1" after "server2", which is why I'm using the hash to store the values.

If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Re: newbie general powershell looping question

I tried but I may have done something wrong. I modified as follows and got the below message

$csv = import-csv env.csv

$lines = $csv| ConvertFrom-Csv $values = @{}

$output = New-Object System.Collections.Generic.List[System.Object]

foreach ($line in $lines) {

            if ($values.Keys -notcontains $line.name) {

                        $values.Add($line.name, $line.status)

            }

            $line.status = $values.($line.name)

            $output.Add($line)

}

$output

 

ConvertFrom-Csv : Cannot validate argument on parameter 'InputObject'. The argument is null or empty. Provide an argument that is

At line:1 char:32

+ $lines = $csv| ConvertFrom-Csv $values = @{}

+                                ~~~~~~~

    + CategoryInfo          : InvalidData: (Smiley Happy [ConvertFrom-Csv], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ConvertFromCsvCommand

 

Re: newbie general powershell looping question

You don't need to use "Import-Csc" and "ConvertFrom-Csv", just one or the other.  If it's a file on disk, just use Import-Csv...

 

$lines = Import-Csv env.csv

$values = @{}
$output = New-Object System.Collections.Generic.List[System.Object]

foreach ($line in $lines) {
    if ($values.Keys -notcontains $line.name) {
        $values.Add($line.name, $line.status)
    }

    $line.status = $values.($line.name)
    $output.Add($line)
}

$output

If you want to output the result to a new CSV, use the ConvertTo-Csv cmdlet...

 

$output | ConvertTo-Csv -NoTypeInformation

Andrew

If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Re: newbie general powershell looping question

thought I tried that, but I will give it a shot again. Thanks

Re: newbie general powershell looping question

where does the status field come from? Do I need to add it to my input file?  Im getting this:

 

Exception setting "status": "The property 'status' cannot be found on this object. Verify that the property exists and can be set."

At line:5 char:5

+     $line.status = $values.($line.name)

+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (Smiley Happy [], SetValueInvocationException

    + FullyQualifiedErrorId : ExceptionWhenSetting

 

 

thank you for this help by the way

Re: newbie general powershell looping question

I didn't use your original field names...I may have missed them Smiley Very Happy

 

Using your field names it should be...

 

$lines = Import-Csv env.csv

$values = @{}
$output = New-Object System.Collections.Generic.List[System.Object]

foreach ($line in $lines) {
    if ($values.Keys -notcontains $line.name) {
        $values.Add($line.name, $line.environment)
    }

    $line.environment = $values.($line.name)
    $output.Add($line)
}

$output
If this post resolved your issue, please help others by selecting ACCEPT AS SOLUTION or adding a KUDO.

Re: newbie general powershell looping question

ah - thank you - sorry Im a newbie