2

I have following arrays in Powershell that I want to compare:

Array1: 
Srvname Loginname sid passwordhash 
Srv1     L1        0xdbc  0xfsfhdfh
Srv2     L2        0xdbe  0xfsfhdfe
Srv3     L3        0xdbc  0xfsfhdfd
 
Array2: 
Srvname Loginname sid passwordhash
Srv1     L1        0xdbd  0xfsfhdfh 
Srv2     L2        0xdbe  0xfsfhdfh
Srv3     L3        0xdba  0xfsfhdfb

It should give output only when there is either sid,password or both mismatch of the same loginname. For example in above case it should give output as below:

Srvname Loginname Srvname2 Loginname2 Mismatch
Srv1      L1       Srv1     L1         sid
Srv2      L2       Srv2     L2         password
Srv3      L3       Srv3     L3         sid and password

If someone can assist with the code that would be greatly appreciated.

Tried below but it didn't work:

$output += $T2 | ForEach-Object {
    $r = $_
    $T1 | Where-Object { $_.LoginName -eq $r.LoginName -and ($_.SId -ne $r.SId -or $_.PasswordHash -ne $r.PasswordHash) } |
        Select-Object @{Name = 'SrvName'; Expression = { $_.srvname }}, $_.LoginName, @{Name = 'SrvName2'; Expression = { $r.srvname } }, @{Name = 'LogiName2'; Expression = { $r.LoginName }}, @{Name = 'Mismatch'; Expression = { 'sid or password' }}
}
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
SQLPRODDBA
  • 171
  • 8
  • did you try anything already? are those powershell objects? also your expected output in the first object, `Srv1 L1 Srv2 L1` there is no correlation between those 2 – Santiago Squarzon Jul 19 '23 at 13:44
  • I guess you want to join the two arrays on the `Srvname` and `Loginname` and then find the discrepancies (as different sids): Using this [`Join-Object Module`](https://www.powershellgallery.com/packages/JoinModule) (see also: [In Powershell, what's the best way to join two tables into one?](https://stackoverflow.com/a/45483110/1701026)): `$Array1 | Join $Array2 -On Srvname, Loginname -Name *1, *2 | Where-Object { $_.sid1 -ne $_.sid2 }` – iRon Jul 19 '23 at 14:08
  • @SantiagoSquarzon Updated question with what I tried. – SQLPRODDBA Jul 19 '23 at 14:44

1 Answers1

3

Assuming these are arrays of objects, using this as an example:

$arr1 = @'
Srvname Loginname sid passwordhash
Srv1     L1        0xdbc  0xfsfhdfh
Srv2     L2        0xdbe  0xfsfhdfe
Srv3     L3        0xdbc  0xfsfhdfd
'@ -replace ' +', ',' | ConvertFrom-Csv


$arr2 = @'
Srvname Loginname sid passwordhash
Srv1     L1        0xdbd  0xfsfhdfh
Srv2     L2        0xdbe  0xfsfhdfh
Srv3     L3        0xdba  0xfsfhdfb
'@ -replace ' +', ',' | ConvertFrom-Csv

You can use Group-Object grouping by Loginname then you can filter where their sid on both sides is not equal OR their passwordhash is not equal and if the condition is met, then output the differences. The code below assumes that Loginname is unique on each side.

$arr1 + $arr2 | Group-Object Loginname | ForEach-Object {
    $sid = $_.Group.sid
    $passwordhash = $_.Group.passwordhash

    $mismatch = @(
        if ($sid[0] -ne $sid[1]) {
            'sid'
        }

        if ($passwordhash[0] -ne $passwordhash[1]) {
            'password'
        }
    ) -join ' and '

    if ($mismatch) {
        [pscustomobject]@{
            SrvnameLEFT  = $_.Group.Srvname[0]
            SrvnameRIGHT = $_.Group.Srvname[1]
            Loginname    = $_.Name
            Mismatch     = $mismatch
        }
    }
}

The output you would get from this example:

SrvnameLEFT SrvnameRIGHT Loginname Mismatch
----------- ------------ --------- --------
Srv1        Srv1         L1        sid
Srv2        Srv2         L2        password
Srv3        Srv3         L3        sid and password
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37