Home > Software design >  how to change column colour base on a condition in powershell html
how to change column colour base on a condition in powershell html

Time:10-17

Firstly i would apologize if i was asking a very noob question, i'm a beginner powershell users and i don't have much exp in scripting, i have some issue to output html report using powershell. I wanted to change the colour of each row according to the utilization % wheter it is above or below 90%. However i only manage to change the colour of the first row.

i have 2 file which i use to output the report.

output from agg.csv

Aggregate_01_Data1,10.01TB,90%,96.93TB,online,86.92TB,
Aggregate_02_Data1,9.03TB,91%,96.93TB,online,87.90TB,
root_Aggregate_01,17.85GB,85%,368.4GB,online,350.6GB,
root_Aggregate_02,17.85GB,95%,368.4GB,online,350.6GB,

output from aggregate.csv

Aggregate,Size,Available,Used,Utilized,State
Aggregate_01_Data1,96.93TB,10.01TB,86.92TB,90,online
Aggregate_02_Data1,96.93TB,9.03TB,87.90TB,91,online
root_Aggregate_01,368.4GB,17.85GB,350.6GB,85,online
root_Aggregate_02,368.4GB,17.85GB,350.6GB,95,online

my code to generate the html report.

$a1=gc $TPATH\agg.csv
$b1 =$a1 

 for ($i1 = 0;$i1 -lt $a1.count;$i1  )
 {
  $c1=$b1[$i1].split(",",10)
  $c = $c1[2].Length
  $c = $c - 1
  
  $d1=$c1[0]   ","   $c1[3]   ","   $c1[1]   ","   $c1[5]   ","   $c1[2].remove($c)    ","   $c1[4]
  $d1 | Out-File ("$TPATH\aggregate.csv") -Encoding UTF8 -append

 $bodyB = (import-csv $TPATH\aggregate.csv) |Select Aggregate,Size,Available,Used,Utilized,State -OutVariable ag | ConvertTo-Html -Fragment |
 foreach { if($ag.Utilized -gt 90) {$_ -replace "<tr>", "<tr bgcolor=#FE0808>"}else{$_ -replace "<tr>", "<tr bgcolor=#E5FCA1>"}} |Out-String 

 }     
convertTo-HTML -Body "<br> $bodyB" |out-file $PATH\Netapp.html

my final output look like this

enter image description here

how can i get the output to be like this, i want to have the colour change to Red if the threshold is above 90% in the Utilized column and Green if the threshold is below 90%. enter image description here

Thank you in advance for those whom willing to help, really appreciate your help in this.

Thank You.

CodePudding user response:

Replace -OutVariable ag with -PipelineVariable ag, so that $ag in your foreach (ForEach-Object) script block refers only to the single input object at hand.

  • The purpose of the common -PipelineVariable (-pv) parameter is to store the current object being output in a self-chosen variable, so that it can be accesses in a script block later in the same pipeline.

  • By contrast, the purpose of the common -OutVariable (-ov) parameter is to collect all output from a command in a self-chosen variable, for later processing in a different, subsequent statement, not in the same pipeline.

    • If you do access such a variable in a script block in the same pipeline, you'll see the output objects accumulated so far (which explains the behavior you saw - see below).

As for what you tried:

Due to the mistaken use of -OutVariable ag, your script block saw the Import-Csv output objects collected so far rather than the output object at hand.

Thus, starting with the second output object, $ag was in effect an array of objects, and accessing its . Utilized property resulted in member-access enumeration, and therefore returning an array of utilization values.

Since -gt, like all PowerShell comparison operators, acts as a filter when its LHS is an array, $ag.Utilized -gt 90 started to generate a return value (the subarray of matching values) as soon as at least one element in the array of values satisfied this condition.

In a Boolean context such as an if-statement conditional, a non-empty array is interpreted as $true.

Therefore, in effect ($ag.Utilized -gt 90) returned $true as soon as the first value above 90 was part of the return array, and invariably remained true.

  • Related