Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In PowerShell, how can I combine the results of two commands that have a 1-to-1 relashionship?

Tags:

powershell

This particular example is Get-User and Get-Mailbox (Exchange 2010). Get-User returns some of the columns I need, and Get-Mailbox some others. I am having difficulty figuring out how I can combine the results of the two into a single table with the results from both.

Get-User -Filter "..." | Get-Mailbox -Filter "..."

How do I take the results of a command similar to the above and turn it into results similar to below?

FirstName  LastName  Alias   CustomAttribute1
---------  --------  ------  ----------------
Bob        Smith     bsmith  Example
Johnny     NoMail
Adam       Blye      ablye   Has a Mailbox

Note that FirstName and LastName are not returned by Get-Mailbox, and conversely Alias and CustomAttributes are not returned from Get-User. Not every user has a mailbox, so sometimes a portion of the columns would be null. But I'm having a devil of a time figuring out the best way to return a combined table like this.

like image 513
Myrddin Emrys Avatar asked Jul 30 '12 12:07

Myrddin Emrys


People also ask

How do I combine two PowerShell commands?

Chaining multiple PowerShell commands in one line However, if you want to do run multiple unrelated commands on the same line, you can use the firstcommand; secondcommand method. In this case, the second command gets executed even if the first command fails.

Does += work in PowerShell?

The equals sign ( = ) is the PowerShell assignment operator. PowerShell also has the following compound assignment operators: += , -= , *= , %= , ++ , -- , ??= . Compound assignment operators perform operations on the values before the assignment.

How do I run two commands in one line in PowerShell?

The commands can be in one PowerShell invocation by using a SEMICOLON at the end of each line. You need just one execution of PowerShell, and multiple commands passed to it.


1 Answers

I make a custom object, which may be overkill, but it's the simplest way I've found.

Here's some sample code to play with. Let me know if it generates any trouble or additional questions:

$outputCollection = @()
$users = Get-User -Filter "..."
$mailboxes = Get-Mailbox -Filter "..."

$users | Foreach-Object {
    #Associate objects
    $userObject = $_
    $mailboxObject = $mailboxes | Where-Object {$_.Name -eq $userObject.Name}

    #Make a combined object
    $outputObject = "" | Select Name, UserAttribute, MailboxAttribute
    $outputObject.Name = $userObject.Name
    $outputObject.UserAttribute = $userObject.UserAttribute
    $outputObject.MailboxAttribute = $mailboxObject.MailboxAttribute

    #Add the object to the collection
    $outputCollection += $outputObject
}

$outputCollection

Another option that should work is called calculated properties:

Get-User -Filter "..." | Select Name, UserAttribute, @{Name="OtherAttribute"; Expression={(Get-Mailbox $_.Name).MailboxAttribute}}

...note that this will run a new Get-Mailbox command for each entry, potentially increasing execution time

like image 126
Chris N Avatar answered Oct 22 '22 21:10

Chris N