A little confused,
so i want to retreive all mailboxes and output them to an array which is working fine code below
$MBDatabases = Get-MailboxDatabase | where {$_.name -like "*EU*"} | select name
$outarray = @()
foreach ($MBDatabase in $MBDatabases)
{
$Users = Get-MailboxStatistics -Database $MBDatabase.name | where {$_.ObjectClass -eq “Mailbox”}
foreach ($user in $users)
{
$properties = @{Name = $User.Displayname
MBSize = $User.TotalItemSize
ItemCount = $User.ItemCount
Database = $user.Database
Servername = $user.ServerName
}
$Obj = New-Object -TypeName psobject -Property $properties
$outarray += $obj
}
}
$outarray | Out-GridView
now i also want to include the ‘title’ & ‘samAccountname’ attribute in the object, to get the details im using
$user2 = $user | select -ExpandProperty displayname
$adusers = get-aduser -filter {displayname -eq $user2} -Properties title | select title, samaccountname
i want to combine the two commands so i output one array of objects
$properties = @{Name = $User.Displayname
MBSize = $User.TotalItemSize
ItemCount = $User.ItemCount
Database = $user.Database
Servername = $user.ServerName
Title = $aduser.title
SamAccountName = $aduser.samaccountname
}
i know im going wrong somewhere but lost as to where ? last method i tried was below but seems to only give me the last result of each DB, HEEEELLLP!
$MBDatabases = Get-MailboxDatabase | where {$_.name -like "*EU*"} | select name
$outarray = @()
foreach ($MBDatabase in $MBDatabases)
{
$Users = Get-MailboxStatistics -Database $MBDatabase.name | where {$_.ObjectClass -eq “Mailbox”}
foreach ($user in $users)
{
$user2 = $user | select -ExpandProperty displayname
$adusers = get-aduser -filter {displayname -eq $user2} -Properties title | select title, samaccountname
foreach ($aduser in $Adusers)
{
$properties = @{Name = $User.Displayname
MBSize = $User.TotalItemSize
ItemCount = $User.ItemCount
Database = $user.Database
Servername = $user.ServerName
Title = $aduser.title
SamAccountName = $aduser.samaccountname
}
}
}
$Obj = New-Object -TypeName psobject -Property $properties
$outarray += $obj
}
$outarray | Out-GridView
for each MailBoxStatistic object you easily can get mailbox or user with
Get-Mailbox -Identity $user.LegacyDN
Get-User -Identity $user.LegacyDN
and do something like
# [...]
$Users = Get-MailboxStatistics -Database $MBDatabase.name | where {$_.ObjectClass -eq “Mailbox”}
foreach ($user in $users)
$mb = Get-MailBox $user.LegacyDN
$us = Get-User $user.LegacyDN
#Do not use "$obj =" here, let it flow thru pipeline
[PSCustomObject]@{
MBSize = $User.TotalItemSize
ItemCount = $User.ItemCount
Database = $user.Database
Servername = $user.ServerName
Title = $us.title
SamAccountName = $us.samaccountname
}
and please do not use accumulator like “$outarray += $obj”
you can
foreach ($MBDatabase in $MBDatabases)
{
# [...]
} | Out-GridView
Much appreciated Max, will give this a shot first thing tomorrow
Hi Max gave this a shot today, but it reports the last line in wrong
$MBDatabases = Get-MailboxDatabase | where {$_.name -like "*EU*"} | select name
foreach ($MBDatabase in $MBDatabases)
{
$Users = Get-MailboxStatistics -Database $MBDatabase.name | where {$_.ObjectClass -eq “Mailbox”}
foreach ($user in $users)
{
$mb = Get-MailBox $user.LegacyDN
$us = Get-User $user.LegacyDN
[PSCustomObject]@{
MBSize = $User.TotalItemSize
ItemCount = $User.ItemCount
Database = $user.Database
Servername = $user.ServerName
Title = $us.title
SamAccountName = $us.samaccountname
}
}
}| Out-GridView -Wait
At H:\EAA\Powers Shell Commands\get all mb sizes.ps1:31 char:2
+ }| Out-GridView -Wait
+ ~
An empty pipe element is not allowed.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : EmptyPipeElement
sorry, I’m misinform you
this way works
$output = foreach ($MBDatabase in $MBDatabases)
{
# [...]
}
$output | Out-GridView
Thanks max, just another quick Q
out of interest whats the benefit of this over adding objects to an array ?
Hey Mark,
Both methods result in an array.
Example
$numlist = 1..10
$addarray = @()
$returnedarray = foreach ($num in $numlist) {
$psobj = [pscustomobject]@{
num = $num
}
$addarray += $psobj
$psobj
}
In the above example we are using both methods. One to add the custom PS object to $addarray using +=, and the other to return the custom PS object so that it is included in $returnedarray as a return value.
With these two variables now populated with values, the same values, we can check out what they are using Get-Member
(Get-Member -InputObject $addarray).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
(Get-Member -InputObject $returnedarray).GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
As you can see both BaseTypes are System.Array
The difference is that collecting the objects into an array as they are returned seems to be faster than adding them to an array using +=.
$numlist = 1..10000
$addarray = @()
Measure-Command {
$returnedarray = foreach ($num in $numlist) {
[pscustomobject]@{
num = $num
}
}
} | Select-Object -ExpandProperty TotalSeconds
Measure-Command {
foreach ($num in $numlist) {
$addarray += [pscustomobject]@{
num = $num
}
}
} | Select-Object -ExpandProperty TotalSeconds
0.141293
6.5053623
In addition to @Curtis explanation
“+=” also memory expensive
for array with 10000 elements after “$array += 1”
you have two arrays in memory: named $array with 10001 element and unnamed (old) with 10000 elements
it falls under GarbageCollection after that but still exists some time…
Thanks both, have a much better understanding now