bryane92
bryane92

Reputation: 59

How to compare two custom ps custom objects and change the value of one based on the result of another?

Currently I have two sql queries that I have outputting the following columns

$A | Select-Object -Property DatabaseUserName, Role, PermissionType, PermissionState, ObjectType, ObjectName, col

AND

$B | Select-Object -Property DatabaseUserName, sysadmin

What I want to do in psuedo code: WHERE $B.DatabaseUserName = $A.DatabaseUserName THEN $A.col = $B.sysadmin. Currently I have it setup the following way:

$allUsers = $A | % {
        New-Object psobject -Property @{
            DatabaseUserName = $_.DatabaseUserName
            Role = $_.Role
            PermissionType = $_.PermissionType
            PermissionState = $_.PermissionState
            ObjectType = $_.ObjectType
            ObjectName = $_.ObjectName
            col = 0
        }
    }

    $allUsers += $B | Where-Object {$_.DatabaseUserName -like $B.DatabaseUserName} | % {
        New-Object psobject -Property @{
            $_.col = $B.sysadmin

        }
    }

This still leaves all the columns to be 0 from what I can see when I want them to actually be the value of $B.sysadmin. I am not sure if this is the correct approach.

Upvotes: 0

Views: 349

Answers (2)

bryane92
bryane92

Reputation: 59

I figured this out by doing a nested for each like so

    $AllUsers = $svrInfo | % {
        New-Object psobject -Property @{
            DatabaseUserName = $_.DatabaseUserName
            Role = $_.Role
            PermissionType = $_.PermissionType
            PermissionState = $_.PermissionState
            ObjectType = $_.ObjectType
            ObjectName = $_.ObjectName
            col = 0


        }
    }
    foreach ($admin in $sysAdmin)
    {
        foreach ($User in $AllUsers)
        {   
            if($User.DatabaseUserName -contains $admin.DatabaseUserName)
            {
                Write-Host("$User.DatabaseUserName matches $admin.DatabaseUserName")        
                $User.col = 1

            }



        }
    }

Upvotes: 0

Matthew
Matthew

Reputation: 1166

Your Where-Object clause doesn't make much sense. What it says is "Where a property of one instance of array B is like the entire array of properties". -like is used to compare stings. -contains for arrays...but that wouldn't fix your code either....

If I understand what you're asking in your pseudocode, you want to assign a property of $B to a different property of $A when the DatabaseUserName property matches. However the code you posted assigns an object to $allusers for each element in $A. I am going to assume you want to update the objects in the $allusers array rather than in the $A directly. To do that, try this:

Foreach ($au in $allusers) {
    $au.col = ($B | ? {$_.DatabaseUserName -eq $au.DatabaseUserName}).col
}

The above code loops through each item in $allusers and sets the .col property. Note, this code works only if you have one and only one instance of $B which meets your criteria. If you have 0, .col could equal $null or blank. If you have more than one which meets the criteria, then your .col value would be an array.

Upvotes: 1

Related Questions