Calling Powershell Function inside the Add-Member -InputObject ForEach loop?

Ask your PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
User avatar
ITEngineer
Posts: 208
Joined: Wed Oct 12, 2011 10:52 am

Calling Powershell Function inside the Add-Member -InputObject ForEach loop?

Post by ITEngineer »

People,

I wonder if anyone here can assist in integrating the below function to Get Last Logon Time in Exchange Online mailbox with the simple script I have put together?

The main script that is already working to collect mailbox size statistics then output to Out-Gridview:

Code: Select all

Write-Host "Gathering Stats, Please Wait.."

$Mailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails SharedMailbox | Select-Object UserPrincipalName, identity, ArchiveStatus, RecipientTypeDetails, SKUAssigned
$CountTotalMbx = $Mailboxes.Count
$CountTotalMbxSize = 0
$MailboxSizes = @()

foreach ($Mailbox in $Mailboxes) {
    $ObjProperties = New-Object PSObject
    $MailboxStats = Get-MailboxStatistics $Mailbox.UserPrincipalname | Select-Object LastLogonTime, TotalItemSize, ItemCount
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "UserPrincipalName" -Value $Mailbox.UserPrincipalName
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Last Logged In" -Value $MailboxStats.LastLogonTime
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Mailbox Size" -Value $MailboxStats.TotalItemSize
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Mailbox Size (MB)" -Value ([math]::Round(($MailboxStats.TotalItemSize.ToString().Split("(")[1].Split(" ")[0].Replace(",", "") / 1MB), 0))
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Mailbox Item Count" -Value $MailboxStats.ItemCount
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Mailbox Type Details" -Value $Mailbox.RecipientTypeDetails
    Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Mailbox License assigned" -Value $Mailbox.SKUAssigned
    if ($Mailbox.ArchiveStatus -eq "Active") {
        $ArchiveStats = Get-MailboxStatistics $Mailbox.UserPrincipalname -Archive | Select-Object TotalItemSize, ItemCount
        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Archive Size" -Value $ArchiveStats.TotalItemSize
        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Archive Item Count" -Value $ArchiveStats.ItemCount
    }
    else {
        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Archive Size" -Value "No Archive"
        Add-Member -InputObject $ObjProperties -MemberType NoteProperty -Name "Archive Item Count" -Value "No Archive"
    }
    $CountTotalMbxSize += [math]::Round(($MailboxStats.TotalItemSize -replace "(.*\()|,| [a-z]*\)", "") / 1GB, 2) + [math]::Round(($ArchiveStats.TotalItemSize -replace "(.*\()|,| [a-z]*\)", "") / 1GB, 2)
    $MailboxSizes += $ObjProperties
}

$MailboxSizes | Out-GridView -Title "There are $($CountTotalMbx) mailboxes with total usage $($CountTotalMbxSize) GB of both Mailbox and Archive in size"
Therefore additional column LastUserActionTime, LastActionTimeUpdatedOn, CreationTime and InactiveDays column can be added?
using this function Get_LastLogonTime to return the correct Last logon time for the mailboxes:

Code: Select all

Function Get_LastLogonTime {
    $MailboxStatistics = Get-MailboxStatistics -Identity $upn
    $LastActionTime = $MailboxStatistics.LastUserActionTime
    $LastActionTimeUpdatedOn = $MailboxStatistics.LastUserActionUpdateTime
    Write-Progress -Activity "`n     Processed mailbox count: $MBUserCount "`n"  Currently Processing: $DisplayName" 
   
    #Retrieve lastlogon time and then calculate Inactive days 
    if ($LastActionTime -eq $null) {
        $LastActionTime = "Never Logged In" 
        $InactiveDaysOfUser = "-" 
    } 
    else { 
        $InactiveDaysOfUser = (New-TimeSpan -Start $LastActionTime).Days
        #Convert Last Action Time to Friendly Time
        if ($friendlyTime.IsPresent) {
            $FriendlyLastActionTime = ConvertTo-HumanDate ($LastActionTime)
            $friendlyLastActionTime = "(" + $FriendlyLastActionTime + ")"
            $LastActionTime = "$LastActionTime $FriendlyLastActionTime" 
        }
    }
   
    #Convert Last Action Time Update On to Friendly Time
    if (($friendlyTime.IsPresent) -and ($LastActionTimeUpdatedOn -ne $null)) {
        $FriendlyLastActionTimeUpdatedOn = ConvertTo-HumanDate ($LastActionTimeUpdatedOn)
        $FriendlyLastActionTimeUpdatedOn = "(" + $FriendlyLastActionTimeUpdatedOn + ")"
        $LastActionTimeUpdatedOn = "$LastActionTimeUpdatedOn $FriendlyLastActionTimeUpdatedOn" 
    }
    elseif ($LastActionTimeUpdatedOn -eq $null) {
        $LastActionTimeUpdatedOn = "-"
    }
  
    #Inactive days based filter 
    if ($InactiveDaysOfUser -ne "-") {
        if (($InactiveDays -ne "") -and ([int]$InactiveDays -gt $InactiveDaysOfUser)) { 
            return
        }
    } 
  
    #Filter result based on user mailbox 
    if (($UserMailboxOnly.IsPresent) -and ($MBType -ne "UserMailbox")) {
        return
    } 
  
    #Never Logged In user
    if (($ReturnNeverLoggedInMBOnly.IsPresent) -and ($LastActionTime -ne "Never Logged In")) {
        return
    }
  
    #Export result to CSV file 
    $Result = @{'LastUserActionTime' = $LastActionTime; 'LastActionTimeUpdatedOn' = $LastActionTimeUpdatedOn; 'CreationTime' = $CreationTime; 'InactiveDays' = $InactiveDaysOfUser; 'MailboxType' = $MBType } 
    $Output = New-Object PSObject -Property $Result 
    $Output | Select-Object UserPrincipalName, DisplayName, LastUserActionTime, LastActionTimeUpdatedOn, InactiveDays, CreationTime, MailboxType, AssignedLicenses, Roles | Export-Csv -Path $ExportCSV -Notype -Append
}
Thank you in advance.
/* IT Engineer */

jvierra
Posts: 14543
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Calling Powershell Function inside the Add-Member -InputObject ForEach loop?

Post by jvierra »

You can just add a computed property that calls the function.

Add-Member is a very inefficient way to build an object. If you use a [pscustomobject] then it would be much esier to write your code and then just retrieve the function data and add it to the object.

Code: Select all

[pscustomobject]@{
       Prop1 = $value1
       Prop2 = $value2
       ...
       LastLogonTime = Get-LastLogonTime
}
We do not use underscores in function names. They will cause confusion.

You are trying to convert a single date to a timespan. A timespan is the difference between two dates. You code won't work.

I have no idea what the following line is supposed to due. All dat time objects in PowerShell are human readable.
$FriendlyLastActionTime = ConvertTo-HumanDate ($LastActionTime)

User avatar
ITEngineer
Posts: 208
Joined: Wed Oct 12, 2011 10:52 am

Re: Calling Powershell Function inside the Add-Member -InputObject ForEach loop?

Post by ITEngineer »

Ah, I see,

Because I have already installed this to play and learn around date-time formatting

https://www.powershellgallery.com/packa ... anizer/3.2
/* IT Engineer */

jvierra
Posts: 14543
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: Calling Powershell Function inside the Add-Member -InputObject ForEach loop?

Post by jvierra »

That is not the intended use. The dates need no change. Changing them that way doesn't do anything useful that I can see. It just makes teh code more complicated and that has lead to many errors fo design and many, many needless lines of code.

I also cannot quite understand what you are trying to ask. The function return many dates in a very odd way.

This is not the way to code this:

Code: Select all

    #Retrieve lastlogon time and then calculate Inactive days 
    if ($LastActionTime -eq $null) {
        $LastActionTime = "Never Logged In" 
        $InactiveDaysOfUser = "-" 
    } 
    else { 
        $InactiveDaysOfUser = (New-TimeSpan -Start $LastActionTime).Days
        #Convert Last Action Time to Friendly Time
        if ($friendlyTime.IsPresent) {
            $FriendlyLastActionTime = ConvertTo-HumanDate ($LastActionTime)
            $friendlyLastActionTime = "(" + $FriendlyLastActionTime + ")"
            $LastActionTime = "$LastActionTime $FriendlyLastActionTime" 
        }
    }
   
Should be like this:

Code: Select all

    #Retrieve lastlogon time and then calculate Inactive days 
    if ($LastActionTime) {
        $InactiveDaysOfUser = (New-TimeSpan -Start $LastActionTime).Days
        $friendlyLastActionTime = '({0:MMdyyyy})' -f $LastActionTime
    }else{ 
        $LastActionTime = 'Never Logged In"'
        $InactiveDaysOfUser = '-'
    }
With the better approach that PS allows coding becomes much easier. Applying old VB or just Basic approaches makes using PowerShell much harder.

If the code was readable I might be able to guess at what you are asking. You will need to try to clarify your request.

Locked