powershellrowversion

How to find the maximum in array of binary(8) using powershell?


I'm trying to find the max by using

function ExecuteSqlQuery ($SQLQuery) {
try 
{
$Datatable = New-Object System.Data.DataTable    
$Connection = New-Object System.Data.SQLClient.SQLConnection
$Connection.ConnectionString = $connStr
$Connection.Open()
$Command = New-Object System.Data.SQLClient.SQLCommand
$Command.Connection = $Connection
$Command.CommandText = $SQLQuery
$Command.CommandTimeout=$commandTimeout
$Reader = $Command.ExecuteReader()
$Datatable.Load($Reader)
return $Datatable
}

$data= ExecuteSqlQuery "Select col1,col2,col3, RowVersion from table"
$byteArray = [System.Collections.ArrayList]@()
foreach ($row in $data) {

   $byteArray.Add($row.Item("RowVersion"))
}

$max=($byteArray | Measure-Object -Maximum).Maximum 
Write-host $max

But I get an error:

ERROR: Error: Cannot compare "System.Byte[]" because it is not IComparable

Then I tried to converting to int64 and finding the max

$byteArray = [System.Collections.ArrayList]@()
foreach ($row in $data) {

   $byteArray.Add([bitconverter]::ToInt64($row.Item("RowVersion"),0))
}
Write-Host ($byteArray | Measure-Object -Maximum).Maximum 
$max=[Convert]::ToByte(($byteArray | Measure-Object -Maximum).Maximum)   
Write-host $max

But still has an error, output:

9.1298706847202E+18
2017-10-25 21:00:51 ERROR: Error: Value was either too large or too small for >an Int32..

Are there any methods to solve this?
Converting a binary to an int32 retuns 0


Solution

  • binary(8) from SQL should be represented as a [byte[]] in PowerShell, so you have an ArrayList of byte arrays. There's no built-in way to compare a byte array to other byte arrays in the .Net Framework for sorting. That behavior is not defined, so you'll have to define it or otherwise define an algorithm.

    Assuming the first byte is the most significant, the second is the next most significant, and so on, you should be able to get the "maximum" it by doing something like this:

    $byteArray | Sort-Object -Property {$_[0]},{$_[1]},{$_[2]},{$_[3]},{$_[4]},{$_[5]},{$_[6]},{$_[7]} -Descending | Select-Object -First 1
    

    This only looks at the first 8 bytes, but, if the base type was really a binary(8), there's only 8 bytes in the field.

    If that doesn't work, then you'll have to iterate through the ArrayList and find the maximum yourself by comparing bytes and saving the maximum.