Combining PowerShell Cmdlet Results

In my last post I used used New-Object to create an desirable output when the “Get-Mailbox” cmdlet didn’t meet my needs.  If your eyes glazed over trying to read the script, let me make it a bit simpler by focusing on a straight forward example.

Say you need to create a list of user’s mailbox size with their email address.  This sounds like a simple request, but what you’d soon find is that mailbox sizes are returned with the Get-MailboxStatistics cmdlet and the email address is not.  For that, you need to use another cmdlet, such as Get-Mailbox.

With the New-Object cmdlet, we are able to make a custom output that contains data from essentially wherever we want.

See this example:

$MyObject = New-Object PSObject -Property @{
EmailAddress = $null
MailboxSize = $null
}

In this example, I have created a new object with 2 fields, and saved it as the $MyObject variable.

For now, we’ve set the data to null, as shown below:

$MyObject

The next step is to populate each of those fields.  We can write to them one at a time with lines like this:

$MyObject.EmailAddress = (Get-Mailbox mcrowley).PrimarySmtpAddress
$MyObject.MailboxSize = (Get-MailboxStatistics mcrowley).TotalItemSize

Note: The variable we want to populate is on the left, with what we want to put in it on the right.

To confirm our results, we can simply type the variable name at the prompt:

$MyObject with data

Pretty cool, huh?

Ok, so now about that list.  My example only shows the data for mcrowley, and you probably need more than just 1 item in your report, right?

For this, you need to use the foreach loop.  You can read more about foreach here, but the actual code for our list is as follows:

(I am actually going to skip the $null attribute step here)

$UserList = Get-mailbox -Resultsize unlimited
$MasterList = @()
foreach ($User in $UserList) {
$MyObject = New-Object PSObject -Property @{
EmailAddress = (Get-Mailbox $User).PrimarySmtpAddress
MailboxSize = (Get-MailboxStatistics $User).TotalItemSize
}
$MasterList += $MyObject
}
$MasterList

$MasterList with data

Finally, if you wanted to make this run faster, we really don’t need to run “get-mailbox” twice.  For better results, replace the line:

EmailAddress = (Get-Mailbox $User).PrimarySmtpAddress

With this one:

EmailAddress = $User.PrimarySmtpAddress

29 thoughts on “Combining PowerShell Cmdlet Results

  1. Hi Mike,

    If I wanted to return additional data such as DisplayName, Database, ServerName, itemcount, lastlogontime and {$_.TotalItemSize.Value.ToMB()} how would I add this? also how can you export this to a .csv?

    thanks

    • I think i like my mailbox script that I made up myself. Lemmie know what you think ….

      Get-Mailbox | Get-MailboxStatistics | FT @{label=”DisplayName”;expression={$_.DisplayName}}, @{label=”Total Items Count”;
      Expression={$_.ItemCount}}, @{label=”Storage Limit”;expression={$_.StorageLimitStatus}}, @{label=”TotalStorageSize”;
      Expression={$_.TotalItemSize}}, LastLogonTime -autosize

      —————————————

  2. Hello,

    Thanks for this script, i’m trying to do the same thing with multi organizations environment.
    I wrote that :

    $MasterList = @()
    foreach($User in Get-Organization) {
    $MyObject = New-Object PSObject -Property @{
    Name = (Get-Mailbox -Organization $Org).displayname
    }
    $MasterList += $MyObject
    }
    $MasterList | Export-CSV -Path c:\test.csv -Delimiter “;” -Notype

    But my CSV file looks like (no value) :

    “Name”

    Can you help me ?

  3. One-liner, can be customized to add anything you want:
    Get-Mailbox -Identity | Select-Object -Property PrimarySmtpAddress,@{Name=”MailboxSize”;Expression={ $_ | Get-MailboxStatistics | Select-Object -ExpandProperty TotalItemSize }}

  4. Pingback: Combining PowerShell Cmdlet Results - Office 365 MVPs
  5. Thanks, I’m trying to use this as well but I’m a bit confused on your comment about adding more properties from different commands, you wrote “You need to first get that data from somewhere. Once you have worked out the command do to that, you can add fields to the new-psobject block, and then add lines below the $masterobject.whatever section.”.

    So if I want to run get-msoluser as my first command, then add in info from get-mailbox, then get-mailboxstatistics, and then get-aduser, how can I do that?

  6. I’m trying to do something along these lines but a bit trickier. I’m trying to build a list of group names and their email addresses. However, I want this to work for Security groups (acting jointly as distribution groups) and distribution groups. The problem I’m having is if I use “get-adGroupMember” I can get names, but how do I match those names if its a security group? I tried something like the below and of course it wouldn’t work. Gives you an idea though. I am obviously a powershell noob but am trying to figure what I can do with it.

    $GroupName=Read-host “Enter Group Name (name must be exact)”

    $SavePath=”$Home\desktop\Group by name and email.csv”

    Import-Module ActiveDirectory

    add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010

    Get-DistributionGroupMember $GroupName | sort-object | Select PrimarySmtpAddress

    get-ADGroupMember $GroupName | sort-object | select name

    Export-CSV -path $SavePath

    Write-Host “File saved to:” $SavePath

  7. As you’ve seen, get-ADGroupMember and get-DistributionGroupMember both output arrays of users. I don’t understand what you want the CSV file to look like. What do you want in each column? Also, because Exchange distribution groups are just AD groups anyway, why bother with the Exchange output? Can’t you get whatever you need from get-ADGroupMember?

  8. Ahh, good questions. I haven’t been able to get the email addresses from get-ADGroupMember, as active directory no longer handles email addresses (instead, the exchange management console does, thats why I had the add-pssnapin in there). I’d like to be able to enter the name of distribution or security group and have it give me all the names as well as their primary email address. I’m sure its possible, I just haven’t been able to do it yet (my own lack of knowledge surely to blame).

  9. Sure. I want one column to be name, the other to be email address, pulled from either distribution lists OR security groups that act as distribution lists (can be emailed). so a security group called helpers

    Smith, John john.smith@whatever.wk
    Smith, James james.smith@whatever.wk
    Lake, Jane jane.lake@whatever.wk

    The names would be the member names, the hard part is linking them to the email addresses (at least so far) when AD has no built in exchange extensions like AD and exchange 2003 did. Sorry if that still doesn’t explain it.

  10. I’m still not following, sorry. This generates an output identical to what you’re asking, but it doesn’t require any custom work: Get-DistributionGroupMember group1 | select DisplayName, PrimarySmtpAddress

  11. Hi !
    I tried my best to apply the knowledge found in this blog to my problem without success.
    I am checking the mailbox permissions and extended AD permissions (more specifically “send as” by using
    Get-MailboxPermission boss1| where {$_.user.tostring() -ne “NT AUTHORITY\SELF” -and $_.IsInherited -eq $false}

    and

    Get-ADPermission boss1 | Where {$_.ExtendedRights -like “*Send-As*” -and $_.user.tostring() -ne “NT AUTHORITY\SELF”}

    The two outputs are typically like this:

    User AccessRights
    —- ————
    secretary1 {FullAccess}
    secretary2 {FullAccess}
    secretary3 {FullAccess}

    User ExtendedRights
    —- ————–
    secretary1 {Send-As}
    secretary2 {Send-As}
    secretary3 {Send-As}

    Shame on me, I cannot understand how to combine them so that I get an output like this:

    User AccessRights ExtendedRights
    —- ———— ————–
    secretary1 {FullAccess} {Send-As}
    secretary2 {FullAccess} {Send-As}
    secretary3 {FullAccess} {Send-As}

    Thank you in advance!!!

  12. How would you be able to import a csv and have the script scan one particular column for a list of User name?
    When I try to use the following it errors out to a pipeline error
    $UserList = import-csv c:\istofusers.csv | get-mailbox -resultsize unlimited

      • Thank you tremendously for your quick reply, Mr. Crowley!

        When I use the following:
        $UserList = import-csv c:\ListofUsers.csv
        $UserList | get-mailbox
        $MasterList = @()

        I get this error:
        The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the
        parameters that take pipeline input.
        + CategoryInfo : InvalidArgument: (@{Name=username,…DriveSize(MB)=}:PSObject) [Get-Mailbox], ParameterBindingException
        + FullyQualifiedErrorId : InputObjectNotBound,Get-Mailbox

      • Thank you for your patience!
        Which approach would you use in this case?

        $UserList = import-csv c:\listofusers.csv
        $UserList | get-mailbox
        $MasterList = @()

        foreach ($User in $UserList) {

        $MyObject = New-Object PSObject -Property @{
        EmailAddress = $null
        MailboxSize = $null
        LastSent = $null
        }

        $ErrorActionPreference = ‘SilentlyContinue’

        $MyObject.LastSent = ((Get-TransportServer | Get-MessageTrackingLog -Sender $user.PrimarySmtpAddress | sort timestamp)[-1]).timestamp
        $MyObject.EmailAddress = ($User).PrimarySmtpAddress
        $MyObject.MailboxSize = (Get-MailboxStatistics $User).TotalItemSize

        $ErrorActionPreference = ‘Continue’

        $MasterList += $MyObject
        }

        $MasterList

  13. If I have a list of mailboxes in a .txt how do I parse each of it to a Get-MailboxPermission?
    I need to get the list of permissions of only that narrowed list but I cannot find a wait to parse it.
    I tried: get-content list.txt | Get-MailboxPermission
    And it is not being accepted. I´m trying other methods online but no one works… HELP!!!??

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s