Link to home
Start Free TrialLog in
Avatar of Albert Widjaja
Albert WidjajaFlag for Australia

asked on

Modifying Powershell script to get the active user in the past 30 days ?

I had this question after viewing List out all active mailboxes with powershell.

Hi All,

I'm trying to get the active Exchange mailbox by using the powershell script below which go thrugh each Sent Items folder for the email youngest than 30 days in the sent items:

$xDays = 30 
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {  
         $si = Get-MailboxFolderStatistics $_ -IncludeOldestAndNewestItems -FolderScope SentItems 
         if($si.NewestItemReceivedDate -AND (New-TimeSpan $si.NewestItemReceivedDate.ToLocalTime()).Days -lt $xDays) { 
            #$_ 
               New-Object PSObject -Property @{
                     Name = $_.Name
                     Alias = $_.Alias
                         PrimarySmtpAddress = $_.PrimarySmtpAddress
                         WhenCreated = $_.WhenCreated
                         Database = $_.Database
                     	 LastSentItemDate = $si.NewestItemReceivedDate 
                         LastLogonTime = $si.LastLogonTime
                         Mailboxsize = (Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()
               } 
      } 
} | Select Name,Alias,PrimarySmtpAddress,LastSentItemDate,WhenCreated,LastLogonTime,Database,Mailboxsize | Sort LastSentItemDate | Export-Csv -Path C:\temp\Active30Days.csv -NoTypeInformation -UseCulture

Open in new window


But somehow it doesn't work ?

This is the error I got:

Cannot process argument transformation on parameter 'Identity'. Cannot convert value "John Hadisur" to type "Microsoft.Exchange.Configuration.Tasks.MailboxOrMailUserIdParameter". Error: "Cannot 
convert hashtable to an object of the following type: Microsoft.Exchange.Configuration.Tasks.MailboxOrMailUserIdParameter. Hashtable-to-Object conversion is not supported in restricted language mode 
or a Data section."
    + CategoryInfo          : InvalidData: (:) [Get-MailboxFolderStatistics], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-MailboxFolderStatistics
    + PSComputerName        : PRODMBX02-VM

Open in new window

Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

You can pipe into Get-MailboxStatistics.
$xDays = 30 
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {  
         $si = $_ | Get-MailboxFolderStatistics -IncludeOldestAndNewestItems -FolderScope SentItems 
         if($si.NewestItemReceivedDate -AND (New-TimeSpan $si.NewestItemReceivedDate.ToLocalTime()).Days -lt $xDays) { 
            #$_ 
               New-Object PSObject -Property @{
                     Name = $_.Name
                     Alias = $_.Alias
                         PrimarySmtpAddress = $_.PrimarySmtpAddress
                         WhenCreated = $_.WhenCreated
                         Database = $_.Database
                     	 LastSentItemDate = $si.NewestItemReceivedDate 
                         LastLogonTime = $si.LastLogonTime
                         Mailboxsize = (Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()
               } 
      } 
} | Select Name,Alias,PrimarySmtpAddress,LastSentItemDate,WhenCreated,LastLogonTime,Database,Mailboxsize | Sort LastSentItemDate | Export-Csv -Path C:\temp\Active30Days.csv -NoTypeInformation -UseCulture

Open in new window

Avatar of Albert Widjaja

ASKER

I got this error:

Pipeline not run because a pipeline is already running. Pipelines cannot be run concurrently.
    + CategoryInfo          : OperationStopped: (Microsoft.Power...tHelperRunspace:ExecutionCmdletHelperRunspace) [], PSInvalidOperationException
    + FullyQualifiedErrorId : RemotePipelineExecutionFailed

Open in new window

Oh that one. Try the Identity property, it's normally wired for Exchange. I can't check I'm afraid, not running Exchange.
$xDays = 30 
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {  
         $si = Get-MailboxFolderStatistics -Identity $_.Identity -IncludeOldestAndNewestItems -FolderScope SentItems 
         if($si.NewestItemReceivedDate -AND (New-TimeSpan $si.NewestItemReceivedDate.ToLocalTime()).Days -lt $xDays) { 
            #$_ 
               New-Object PSObject -Property @{
                     Name = $_.Name
                     Alias = $_.Alias
                         PrimarySmtpAddress = $_.PrimarySmtpAddress
                         WhenCreated = $_.WhenCreated
                         Database = $_.Database
                     	 LastSentItemDate = $si.NewestItemReceivedDate 
                         LastLogonTime = $si.LastLogonTime
                         Mailboxsize = (Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()
               } 
      } 
} | Select Name,Alias,PrimarySmtpAddress,LastSentItemDate,WhenCreated,LastLogonTime,Database,Mailboxsize | Sort LastSentItemDate | Export-Csv -Path C:\temp\Active30Days.csv -NoTypeInformation -UseCulture

Open in new window

Thanks Chris,

However, it returns the below error:

Cannot process argument transformation on parameter 'Identity'. Cannot convert value "John O'Connor" to type "Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter". Error: 
"Cannot convert hashtable to an object of the following type: Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter. Hashtable-to-Object conversion is not supported in restricted 
language mode or a Data section."
    + CategoryInfo          : InvalidData: (:) [Get-MailboxStatistics], ParameterBindin...mationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Get-MailboxStatistics
    + PSComputerName        : PRODMBX01-VM
 
Foreach-Object : You cannot call a method on a null-valued expression.
At C:\Users\Admin\AppData\Local\Temp\99d25a74-942d-4cf9-b40e-6776ecd9f7c5.ps1:6 char:71
+ ... ltSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {
+                                                          ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [ForEach-Object], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull,Microsoft.PowerShell.Commands.ForEachObjectCommand

Open in new window


At least it is now different than pipeline issue.
Useless thing. Attempts to fix the first error (again), avoids the second error entirely.
$xDays = 30 
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {  
         $si = Get-MailboxFolderStatistics -Identity $_.DistinguishedName -IncludeOldestAndNewestItems -FolderScope SentItems 
         if($si -and $si.NewestItemReceivedDate -AND (New-TimeSpan $si.NewestItemReceivedDate.ToLocalTime()).Days -lt $xDays) { 
            #$_ 
               New-Object PSObject -Property @{
                     Name = $_.Name
                     Alias = $_.Alias
                         PrimarySmtpAddress = $_.PrimarySmtpAddress
                         WhenCreated = $_.WhenCreated
                         Database = $_.Database
                     	 LastSentItemDate = $si.NewestItemReceivedDate 
                         LastLogonTime = $si.LastLogonTime
                         Mailboxsize = (Get-MailboxStatistics $_).TotalItemSize.Value.ToMB()
               } 
      } 
} | Select Name,Alias,PrimarySmtpAddress,LastSentItemDate,WhenCreated,LastLogonTime,Database,Mailboxsize | Sort LastSentItemDate | Export-Csv -Path C:\temp\Active30Days.csv -NoTypeInformation -UseCulture

Open in new window

Chris,

Somehow this Irish guy mailbox has caused me the trouble ?

Cannot convert value "John O'Connor" to type "Microsoft.Exchange.Configuration.Tasks.GeneralMailboxOrMailUserIdParameter" then the script stopped with 0 KB result ?
Picking the distinguishedName property should resolve that, it'll have any character sequences properly escaped and it's a unique, well-formed identity value.

The version above, which explicitly uses distinguishedName, still causes trouble?
Ohh I missed one. Sorry! Missed the internal call to Get-MailboxStatistics.
$xDays = 30 
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {  
         $si = Get-MailboxFolderStatistics -Identity $_.DistinguishedName -IncludeOldestAndNewestItems -FolderScope SentItems 
         if($si -and $si.NewestItemReceivedDate -AND (New-TimeSpan $si.NewestItemReceivedDate.ToLocalTime()).Days -lt $xDays) { 
            #$_ 
               New-Object PSObject -Property @{
                     Name = $_.Name
                     Alias = $_.Alias
                         PrimarySmtpAddress = $_.PrimarySmtpAddress
                         WhenCreated = $_.WhenCreated
                         Database = $_.Database
                     	 LastSentItemDate = $si.NewestItemReceivedDate 
                         LastLogonTime = $si.LastLogonTime
                         Mailboxsize = (Get-MailboxStatistics -Identity $_.DistinguishedName).TotalItemSize.Value.ToMB()
               } 
      } 
} | Select Name,Alias,PrimarySmtpAddress,LastSentItemDate,WhenCreated,LastLogonTime,Database,Mailboxsize | Sort LastSentItemDate | Export-Csv -Path C:\temp\Active30Days.csv -NoTypeInformation -UseCulture

Open in new window

Chris,

You are very helpful man,

It's almost working:

Foreach-Object : Method invocation failed because [Deserialized.Microsoft.Exchange.Data.ByteQuantifiedSize] does not contain a method named 'ToMB'.
At C:\Users\Admin\AppData\Local\Temp\99d25a74-942d-4cf9-b40e-6776ecd9f7c5.ps1:6 char:71
+ ... ltSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {
+                                                          ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (ToMB:String) [ForEach-Object], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand

Open in new window

Can you show me this for a single user, the return value is a bit broken.
(Get-MailboxStatistics -Identity Someone).TotalItemSize.Value | Get-Member
(Get-MailboxStatistics -Identity Someone).TotalItemSize | Get-Member

Open in new window

It runs well:

Name        MemberType Definition                                                                                                                                                                  
----        ---------- ----------                                                                                                                                                                  
Equals      Method     bool Equals(System.Object obj)                                                                                                                                              
GetHashCode Method     int GetHashCode()                                                                                                                                                           
GetType     Method     type GetType()                                                                                                                                                              
ToString    Method     string ToString(), string ToString(string format, System.IFormatProvider formatProvider), string IFormattable.ToString(string format, System.IFormatProvider formatProvider)


   TypeName: Deserialized.Microsoft.Exchange.Data.Unlimited`1[[Microsoft.Exchange.Data.ByteQuantifiedSize, Microsoft.Exchange.Data, Version=15.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]

Name        MemberType Definition                                                                                                                                                                  
----        ---------- ----------                                                                                                                                                                  
GetType     Method     type GetType()                                                                                                                                                              
ToString    Method     string ToString(), string ToString(string format, System.IFormatProvider formatProvider), string IFormattable.ToString(string format, System.IFormatProvider formatProvider)
IsUnlimited Property   System.Boolean {get;set;}                                                                                                                                                   
Value       Property   Deserialized.Microsoft.Exchange.Data.ByteQuantifiedSize {get;set;}                                                                                                          

Open in new window

It's right though, it doesn't have the method. It's a remoting problem, it's a deserialized object.

Can I see...
(Get-MailboxStatistics -Identity Someone).TotalItemSize.Value.GetType()

Open in new window

I'm most interested in the underlying types. It'd be handy if it were already a number.

Can you also show me the raw value output?
(Get-MailboxStatistics -Identity Someone).TotalItemSize
(Get-MailboxStatistics -Identity Someone).TotalItemSize.Value

Open in new window

Chris,

When I execute the PowerShell from the EMS within the server RDP session, I got this error instead:

Foreach-Object : Cannot convert 'System.Object[]' to the type 'System.DateTime' required by parameter 'Start'. Specified method is not supported.
At C:\temp\Active.PS1:2 char:71
+ Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Ob ...
+                                                                       ~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ForEachObjectCommand

Open in new window

Here's the result of the powershell that you requested:

Script lines from my LKaptop with PowerGUI IDE (Remoting):
(Get-MailboxStatistics -Identity "John O'Connor").TotalItemSize.Value.GetType()
(Get-MailboxStatistics -Identity "John O'Connor").TotalItemSize
(Get-MailboxStatistics -Identity "John O'Connor").TotalItemSize.Value

Open in new window


Result:
IsPublic IsSerial Name                                     BaseType                                                                                                                                     
-------- -------- ----                                     --------                                                                                                                                     
True     False    PSCustomObject                           System.Object                                                                                                                                

IsUnlimited : False
Value       : 12.41 GB (13,328,412,457 bytes)

12.41 GB (13,328,412,457 bytes)

Open in new window

The error message implies you're getting more than one result back when you run Get-MailboxFolderStatistics. Does it return nested folders if a folder is underneath SentItems?
Get-MailboxFolderStatistics -Identity $_.DistinguishedName -IncludeOldestAndNewestItems -FolderScope SentItems"

Open in new window

Start is the (positional) parameter for New-TimeSpan.

For the value conversion, the remoting deserializer isn't going deep enough. There's not much you can do about that other than work-around the problem.
            Mailboxsize        = ([Int](Get-MailboxStatistics -Identity $_.DistinguishedName).TotalItemSize.Value -replace '^.+\(| *bytes.+|,') / 1MB

Open in new window

Need more parens.
            Mailboxsize        = ([Int]((Get-MailboxStatistics -Identity $_.DistinguishedName).TotalItemSize.Value -replace '^.+\(| *bytes.+|,')) / 1MB

Open in new window

Chris,

I have changed the Integer to Long, but somehow it is still failed:

Mailboxsize = ([Long]((Get-MailboxStatistics -Identity $_.DistinguishedName).TotalItemSize.Value -replace '^.+\(| *bytes.+|,')) / 1MB

Open in new window


This is the error message:
Foreach-Object : Cannot convert 'System.Object[]' to the type 'System.DateTime' required by parameter 'Start'. Specified method is not supported.
At C:\Users\Admin\AppData\Local\Temp\99d25a74-942d-4cf9-b40e-6776ecd9f7c5.ps1:6 char:71
+ ... ltSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {
+                                                          ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ForEachObjectCommand

Open in new window

Long is a good idea, I forgot mailboxes can be quite large :)

Unreleated problems now. You're back to the this one.

Can Get-MailboxFolderStatistics return more than one value with the arguments you're giving it?

If it can, you must account for that. The simplest, least efficient, way is to add another loop.
$xDays = 30 
Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {  
    $mailboxFolders = Get-MailboxFolderStatistics -Identity $_.DistinguishedName -IncludeOldestAndNewestItems -FolderScope SentItems
    
    foreach ($mailboxFolder in $mailboxFolders) {
        if ($mailboxFolder.NewestItemReceivedDate -AND (New-TimeSpan $mailboxFolder.NewestItemReceivedDate.ToLocalTime()).Days -lt $xDays) {
            New-Object PSObject -Property @{
                Name               = $_.Name
                Alias              = $_.Alias
                PrimarySmtpAddress = $_.PrimarySmtpAddress
                WhenCreated        = $_.WhenCreated
                Database           = $_.Database
                LastSentItemDate   = $mailboxFolder.NewestItemReceivedDate 
                LastLogonTime      = $mailboxFolder.LastLogonTime
                Mailboxsize        = [Int64]((Get-MailboxStatistics -Identity $_.DistinguishedName).TotalItemSize.Value -replace '') / 1MB
            }
        } 
    }
} | Select-Object Name, Alias, PrimarySmtpAddress, LastSentItemDate, WhenCreated, LastLogonTime, Database, Mailboxsize |
    Sort-Object LastSentItemDate |
    Export-Csv -Path C:\temp\Active30Days.csv -NoTypeInformation -UseCulture

Open in new window

Chris,

This time it gives me this strange result ?

Foreach-Object : Cannot convert value "12.41 GB (13,328,515,781 bytes)" to type "System.Int64". Error: "Input string was not in a correct format."
At C:\Users\Admin\AppData\Local\Temp\99d25a74-942d-4cf9-b40e-6776ecd9f7c5.ps1:6 char:71
+ ... ltSize Unlimited -RecipientTypeDetails UserMailbox | Foreach-Object {
+                                                          ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [ForEach-Object], RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToInteger,Microsoft.PowerShell.Commands.ForEachObjectCommand

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Many thanks Chris, this is a very great efforts and wonderful script :-)