Combine 2 powershell scripts and output

Hello Everyone,

For our Exchange on-prem environment I’ve been asked to deliver some output of shared maiboxes and users who have access to it, and vice verca, which user had access to what shared mailbox… And also the mailbox size included.

I have a script for the shared mailbox vs users and vv. which can be filtered in Excel. It works fine, but this output show only “Displayname” and not Mailboxname.

Get-Mailbox -ResultSize Unlimited |
?{$.RecipientTypeDetails -eq “SharedMailbox”} |
Get-MailboxPermission|
?{$
.User.tostring() -ne “NT AUTHORITY\SELF” -and
$.User.tostring() -ne “NT AUTHORITY\SYSTEM” -and
$
.User.tostring() -ne “NT AUTHORITY\NETWORK SERVICE” -and
$.User.tostring() -ne “ICT\CaAdmin” -and
$
.User.tostring() -ne “ICT\Delegated Setup” -and
$.User.tostring() -ne “ICT\Domain Admins” -and
$
.User.tostring() -ne “ICT\Enterprise Admins” -and
$.User.tostring() -ne “ICT\ExcAdm01” -and
$
.User.tostring() -ne “ICT\Exchange Servers” -and
$.User.tostring() -ne “ICT\Exchange Trusted Subsystem” -and
$
.User.tostring() -ne “ICT\Kohler” -and
$.User.tostring() -ne “ICT\Managed Availability Servers” -and
$
.User.tostring() -ne “ICT\Organization Management” -and
$.User.tostring() -ne “ICT\Public Folder Management” -and
$
.user.tostring() -notlike “S-1-5-21*”}|
Select-Object Identity,User,Displayname,Mailboxname,TotalItemSize |
Export-Csv C:\Temp\sharedfolders-users.csv -NoTypeInformation

For the mailbox size I use this simple line:

Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Sort-Object TotalItemSize -Descending | Select-Object DisplayName,Mailboxname, TotalItemSize | Export-Csv C:\Temp\MailboxSize.csv -NoTypeInformation

This output only show me “Mailboxname” and for some reason not Displayname.
So I get 2 separate csv files which I cant match, because one is Displayname and the other is Mailboxname and they are sometimes totally different in the environment.

Can somebody please help me to get:
A - tTe same output format in Displayname of Mailboxname, so I can easily match them in Excel.
or
B - Combine everything in one script?

Your help will be very welcome!
Thank you in advance,
R76

Well first things first you gotta format your code. Every site you go to that talks about code has a way to format your code so that it’s readable and includes some syntax highlighting. This forum is no different.
Also your code isn’t functional at the moment. Every instance of
$.User.tostring() you have it incorrect as $ isn’t a variable. I’m sure you meant $_ the automatic variable for the current object in the pipeline.

From first glance, these aren’t so much “scripts” as they are one-line strings of commands piped together. Which is great for brevity, but bad for readability and debugging.
I’d suggest refactoring your code to leverage some variables and foreach loops, and then you can manually inspect the objects. Maybe the reason you’re not getting “MailboxName” on the first one is because that particular object does not have a MailboxName property, but you’ll never know if you’re just sending it down the pipeline. You gotta inspect one of those objects, aka “debug” this thing.

2 Likes

Just as a hint: The missing underlines is the result of not formatting the code as code. The forum software removes the underlines then. So it is pretty likely that they are there in the original code. :point_up:t3: :wink:

1 Like

sweet, i didn’t know that, but that definitely explains it.

edit to add: since I had a couple minutes on lunch here is an example of how you might make this more script-like:

$Exclusions = @(
    "NT AUTHORITY\SELF"
    "NT AUTHORITY\SYSTEM"
    "NT AUTHORITY\NETWORK SERVICE"
    "ICT\CaAdmin"
    "ICT\Delegated Setup"
    "ICT\Domain Admins"
    "ICT\Enterprise Admins"
    "ICT\ExcAdm01"
    "ICT\Exchange Servers"
    "ICT\Exchange Trusted Subsystem"
    "ICT\Kohler"
    "ICT\Managed Availability Servers"
    "ICT\Organization Management"
    "ICT\Public Folder Management"
)
$SharedMailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails SharedMailbox
$SharedMBXPermissions = $SharedMailboxes | Where-Object {
    $_.User.ToString() -notin $Exclusions
}
$SharedMBXPermissions | Select-Object -Property Identity,User,Displayname,Mailboxname,TotalItemSize | Export-CSV "C:\Temp\sharedfolders-users.csv" -NoTypeInformation

In this example your accounts to ignore are maintained in an array, and then you only have to make one comparision.
Also, from quickly googling Get-Mailbox it looks like you can filter on shared mailboxes right up front, which is less work and faster.
Because things are stored in Variables at different stages, you can selectively execute this in an IDE and then manually check the objects and their properties so you can better debug why you’re not getting the info you want.

2 Likes

Hello Thanks for your reply and explenation.
sorry I was not aware of formatting the code.
Surely will do it next time, I’m new to the community.
R76

Hello, this is nice! :grinning:
When I run the script I get this message:

You cannot call a method on a null-valued expression.
At C:\temp\SharedFolders-Users-Size-v1.1.ps1:19 char:5
+     $_.User.ToString() -notin $Exclusions
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

If you took my code example and just ran it, that’s not a good practice. My point was to help you see an alternate way of writing this so that when you run in to problems (like this) it would be easier to troubleshoot. The error message makes it pretty clear what the problem is. You cannot call the “ToString” method on the User property because it is null-valued. Looking back at the code I provided vs your original this is because I’m missing the Get-MailboxPermission part so the objects that are getting piped to Where-Object are not the same as in your original code.

$Exclusions = @(
    "NT AUTHORITY\SELF"
    "NT AUTHORITY\SYSTEM"
    "NT AUTHORITY\NETWORK SERVICE"
    "ICT\CaAdmin"
    "ICT\Delegated Setup"
    "ICT\Domain Admins"
    "ICT\Enterprise Admins"
    "ICT\ExcAdm01"
    "ICT\Exchange Servers"
    "ICT\Exchange Trusted Subsystem"
    "ICT\Kohler"
    "ICT\Managed Availability Servers"
    "ICT\Organization Management"
    "ICT\Public Folder Management"
)
$SharedMailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails SharedMailbox
$SharedMBXPermissions = $SharedMailboxes | Get-MailboxPermission | Where-Object {
    $_.User.ToString() -notin $Exclusions
}
$SharedMBXPermissions | Select-Object -Property Identity,User,Displayname,Mailboxname,TotalItemSize | Export-CSV "C:\Temp\sharedfolders-users.csv" -NoTypeInformation

See? I added Get-MailboxPermission back in there. What you should be able to do when you encounter an error like that is work your where selectively through the code, execute it a piece at a time, and check the value of the variables.
I don’t have access to any of these cmdlets in my environment so I can’t test for you, but looking at the contents of the $SharedMailboxes variable would have likely revealed that there is no User property, and then hopefully you’d catch that it wasn’t even mailbox permissions, and that a whole cmdlet was missing.

2 Likes

Thank you very much for all this grateful help!