Olivier R.
Olivier R.

Reputation: 76

Powershell pipeline - Retrieve outputs from first cmdlet?

I am trying a few things in Powershell and what I don't manage to achieve is the following (in Exchange):

Get-User | Get-MailboxStatistics

But in the output I would like some fields/outputs from the "Get-User" cmdlet and some fields/outputs from the "Get-MailboxStatistics" cmdlet.

If anyone has an answer, I have searched the web but with no success as I've had difficulties explaining it in a few words.

Thanks in advance for your help.

Upvotes: 3

Views: 12538

Answers (4)

John Mello
John Mello

Reputation: 31

Get-ADUser -identity ADACCOUNT | Select-object @{Name="Identity";Expression={$_.SamAccountName}} | Get-MailboxStatistics

For some reason the Identity parameter doesn't take pipelne input by value, only by property name. So in order to get it to work you can change the name of piped in data to match the parameter name of Identity. Then Get-MailboxStatistics finally knows how to treat the data your feeding it via the pipeline.

Upvotes: 0

Olivier R.
Olivier R.

Reputation: 76

$users = Get-User  -RecipientTypeDetails UserMailbox
$users | Foreach-Object{ $user = $_; $stats = Get-MailboxStatistics $user.DistinguishedName; New-Object -TypeName PSObject -Property @{FirstName = $user.FirstName; LastName = $user.LastName;MailboxSize = $stats.TotalItemSize;ItemCount =  $stats.ItemCount  }}

I've had to add a specific field in input of Get-MailboxStatistics because remotely, I was having:

The following Error happen when opening the remote Runspace: System.Management.Automation.RemoteException: Cannot process argument transformation on parameter 'Identity'. Cannot convert the "gsx-ms.com/Users/userName1" value of type "Deserialized.Microsoft.Exchange.Data.Directory.Management.User" to type "Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter".

Anyway, thank you both @Jumbo and @Shay-levy

Upvotes: 0

Shay Levy
Shay Levy

Reputation: 126712

Start with the execution of one cmdlet, pipe the results to Foreach-Object and then save a reference to the current object ($user), now execute the second command and save it in a variable as well. Create new object with properties from both objects.

You also need to filter users that have mailboxes, use the RecipientTypeDetails parameter.

$users = Get-User -RecipientTypeDetails UserMailox 
$users | Foreach-Object{

    $user = $_
    $stats = Get-MailboxStatistics $user

    New-Object -TypeName PSObject -Property @{
        FirstName = $user.FirstName
        LastName = $user.LastName
        MailboxSize = $stats.TotalItemSize
        ItemCount =  $stats.ItemCount   
    }
}

Upvotes: 3

jumbo
jumbo

Reputation: 4868

I don't know if it is the best or optimal solution, but you certainly do it by saving actual user to variable in foreach:

$users = Get-User 
$users | % { $user = $_; Get-MailboxStatistics $_ | % 
    { 
        "User name:{0} - some mailbox statistics: {1}" -f $user.SomePropertyOfUser, $_.SomePropertyOfMailbox
    } 
}

The first step (saving users into separate variable) is required only when working with Exchange cmdlets - as mentioned here, you cannot nest Exchange cmdlets in foreach...

This error is caused when executing the Exchange cmdlets through PowerShell remoting, which do not support more than one pipeline running at the same time. You may see this error when you pipe the output from a cmdlet to foreach-object, which then runs another cmdlet within its scriptblock.

Upvotes: 2

Related Questions