combine get-user get-mailboxstatistics exchange 2010 - powershell

I need to create a report for exchange server 2010.
Where I need the users Display name, lastlogontime and account status ie enabled or disable.
get-mailbox statistics shows lastlogon and get-user can show account control status.
So I tried this not working anyhow.
Get-User -ResultSize Unlimited | Where { $_.RecipientType -eq ‘UserMailbox’ } | ForEach { $Users = #{} } { $Users[$_.SamAccountName] = $_ }
get-mailboxstatistics -server 00-exchbx01 |
ForEach {
New-Object psobject |
Add-Member -PassThru NoteProperty name $_.name |
Add-Member -PassThru NoteProperty lastlogontime $_.lastlogontime |
Add-Member -PassThru NoteProperty UserAccountControl $Users[$_.SamAccountName].UserAccountControl
} |select name,lastlogontime,useraccountcontrol |sort-lastlogontime -descending | export-csv c:\ussersxx.csv -nti
also tried No luck Yet any Help?
Get-User -ResultSize Unlimited | Where { $_.RecipientType -eq ‘UserMailbox’ } | ForEach { $Users = #{} } { $Users[$_.SamAccountName] = $_ } | get-mailboxstatistics -server 00-exchbx01 | select Name,useraccountcontrol, lastlogontime|sort-lastlogontime -descending | Export-csv c:\report.csv
`

This should do it.
$outtbl = #()
$users = Get-User -ResultSize Unlimited | Where { $_.RecipientType -eq ‘UserMailbox’ }
$users | % {
$x = Get-MailboxStatistics $_ | Select LastLogonTime
$t = New-Object PSObject -Property #{
Name = $_.Name
LastLogonTime = $x.LastLogontime
UserAccountControl = $_.UserAccountControl
}
$outtbl += $t
}
This is the way I've always done these "combining results of different commands" type scenarios.
You can then do $outtbl | Sort LastLogonTime -Descending | Export-Csv c:\ussersxx.csv -nti to export the data

There's a couple of things here, most of that looks fine except for your last line:
||sort-lastlogontime -descending |
This should become:
| sort -property lastlogontime -descending |
What you'll also run into is that you might end up with things coming down the pipeline from Get-MailboxStatistics that aren't in your $Users hash table. This will results in getting errors when using your hash table to fill out a property the psobject.
You could adjust this to iterate through the hash table, passing the SamAccountName as the value for the Identity property (but this will likely be slower), or add in some error handling so that you just end up with an empty property rather than it completely erroring out.

Related

Filtering Out Lines Not Containing Defined Values PowerShell ISE

I have a list of users and emails that I am trying to filter. I want to remove all emails that do not match what a define. For example, I only want 'user#example.com' listed and 'user#other.com' or 'user#something.com' not listed.
This is my script:
Get-Mailbox -ResultSize 50 | Select-Object DisplayName, PrimarySmtpAddress, Alias | Sort-Object DisplayName | Out-GridView
As you can see, there are multiple columns (DisplayName, PrimarySmtpAddress, and Alias). I want to target 'PrimarySmtpAddress' and filter from that column.
Continuing from my comment.
For example: Lots of examples for you to work from.
Select-Object PrimarySmtpAddress
Select-Object PrimarySmtpAddress
foreach ($mailbox in (Get-Mailbox -ResultSize Unlimited)) {
$properties = #{
PrimarySmtpAddress = $mailbox.PrimarySmtpAddress
TotalItemSize = $mailbox |
Get-MailboxStatistics |
Select-Object -ExpandProperty TotalItemSize
}
New-Object PSObject -Property $properties
} |
where{$_.TotalItemSize -ge 1000MB} |
Sort-Object TotalItemSize -Descending
PowerShell script to export display name and primary smtp address of
all users
https://techcommunity.microsoft.com/t5/office-365/powershell-script-to-export-display-name-and-primary-smtp/m-p/730888
Get-Mailbox -ResultSize Unlimited |
Select-Object DisplayName,PrimarySmtpAddress,EmailAddresses,EmailAddresses |
Export-CSV C:\Temp\"Exchange Online recipients.CSV" –NoTypeInformation -Encoding UTF8
You can then use Where-Object or matching or comparison operators as needed.

when exporting to the text file compare-object issue

I want to get an output like below.
My output now :
Name Active PrimarySmtpAddress
---- ------ ------------------
DG_Group1 True mail1#contoso.com
DG_Group2 False mail2#contoso.com
DG_Group3 True mail3#contoso.com
My desired output :
mail1#contoso.com
mail2#contoso.com
mail3#contoso.com
script :
$DistroLists = Get-DistributionGroup -ResultSize Unlimited
$MessageTrace = Get-MessageTrace -RecipientAddress $DistroLists.PrimarySmtpAddress -startdate (Get-Date).AddDays(-8) -EndDate (Get-Date)
$DistroLists |
Foreach-Object {
$_ | Add-Member -MemberType NoteProperty -Name Active -Value (
$_.PrimarySmtpAddress -in $MessageTrace.RecipientAddress
) -PassThru
} |
Select-Object Name, Active, PrimarySmtpAddress | Where-Object Active -EQ "FALSE"
Out-File C:\output.txt
You can use Select-Object -ExpandProperty or ForEach-Object -MemberName to grab only the value of a specific property from one or more piped input objects:
... |Select-Object Name, Active, PrimarySmtpAddress | Where-Object Active -eq $false | ForEach-Object -MemberName PrimarySmtpAddress | Out-File...
You can skip first two lines and split the line using space characters. Finally pick the last column as given below:
Get-Content C:\Projects\logtext.txt | Select-Object -Skip 2 | ForEach-Object { "$(($_
-split '\s+',3)[2])" }
mail1#contoso.com
mail2#contoso.com
mail3#contoso.com

Powershell Read Users from ActiveDirectory , sort and group the result

I want to read users from different Active Directory groups and then sort and group the results.
From a list like
UserName UserGroup
UZZ GAA
UKK GAA
UZZ GBB
ULL GBB
I want to get that:
Username UserGroup
UKK GAA
ULL GBB
UZZ GAA
So, from User UZZ I want to get only one entry in the list with the first value of UserGroup (first in the alphanumeric sort).
Till now I have the following code:
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter * | Where {$_.name -like "G-Q-T*"} | select name -expandproperty name)
$Table = #()
$Record = #{"GroupName" = """Username" = ""}
Foreach ($Group in $Groups) {
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name, samaccountname
foreach ($Member in $Arrayofmembers) {
$Record."GroupName" = $Group
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objRecord
}
}
$Table | Sort-object -property Username | Group-object -property Username | export-csv "U:\members.csv" -NoTypeInformation**
The part making the list works fine. But not the sort and group part.
Thank you a lot for an answer and help.
Meanwhile I found out, that I have also to add the SID into the .csv File.
The SID is also in the Get-AdGroupMember. But then I try to implement is as the following, the output in case of SID stays empty. What did I wrong where? Thank you in advance for an answer:
Import-Module ActiveDirectory
$Groups = (Get-AdGroup -filter "name -like 'G-Q-T*'" | select name -expandproperty name)
$Table = #()
$Record = #{
"GroupName" = ""
"Username" = ""
"SID" = ""
}
Foreach ($Group in $Groups)
{
$Arrayofmembers = Get-ADGroupMember -identity $Group | select name,samaccountname,SID
foreach ($Member in $Arrayofmembers)
{
$Record."GroupName" = $Group
$Record."UserName" = $Member.samaccountname
$Record."SID" = $Member.SID
$objRecord = New-Object PSObject -property $Record
$Table += $objRecord
}
}
$Table | Group-Object -Property Username |
Select-Object #{n="UserName";e={$_.Name}} , #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} , #{n="SID";e={$_.SID | Sort-Object SID | Select-Object -First 1 -ExpandProperty SID}}| Export-Csv "U:\member.csv" -NoTypeInformation
I would group on username and use calculated properties to create the desired result. Sort the groupnames in the group and pick out the first value. Try to replace your last line with:
$Table | Group-Object -Property Username |
Select-Object #{n="UserName";e={$_.Name}}, #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} |
Export-Csv "U:\members.csv" -NoTypeInformation
Avoid -Filter * as it retrieves every group. Use it to get only the groups you need
$Groups = Get-ADGroup -Filter "name -like 'G-Q-T*'"
Alternative using the famous pipeline:
Get-ADGroup -Filter "name -like 'G-Q-T*'" | ForEach-Object {
$groupname = $_.Name
$_ | Get-ADGroupMember | ForEach-Object {
New-Object -TypeName psobject -Property #{
UserName = $_.SamAccountName
SID = $_.SID
GroupName = $groupname
}
}
} | Group-Object -Property UserName |
Select-Object #{n="UserName";e={$_.Name}}, #{n="SID";e={$_.Group[0].SID}}, #{n="GroupName";e={$_.Group | Sort-Object GroupName | Select-Object -First 1 -ExpandProperty GroupName}} |
Export-Csv "U:\members.csv" -NoTypeInformation

Script output that will work on the console as well as with Export-Csv

I'm working on a basic PowerShell script that inputs a pair of dates then gets all accounts with passwords expiring between those times. I'd like to output the data to the console in a way that is compatible with Export-Csv. That way the person running the script can either just view in the console, or get a file.
Here is my script:
[CmdletBinding()]
param(
[string]$StartDate = $(throw "Enter beginning date as MM/DD/YY"),
[string]$EndDate = $(throw "Enter end date as MM/DD/YY")
)
$start = Get-Date($StartDate)
$end = Get-Date($EndDate)
$low = $start.AddDays(-150)
$high = $end.AddDays(-150)
$passusers = Get-ADUser -Filter { PasswordLastSet -gt $low -and PasswordLastSet -lt $high -and userAccountControl -ne '66048' -and userAccountControl -ne '66080' -and enabled -eq $true} -Properties PasswordLastSet,GivenName,DisplayName,mail,LastLogon | Sort-Object -Property DisplayName
$accts = #()
foreach($user in $passusers) {
$passLastSet = [string]$user.PasswordLastSet
$Expiration = (Get-Date($passLastSet)).addDays(150)
$obj = New-Object System.Object
$obj | Add-Member -MemberType NoteProperty -Name Name -Value $user.DisplayName
$obj | Add-Member -MemberType NoteProperty -Name Email -Value $user.mail
$obj | Add-Member -MemberType NoteProperty -Name Expiration -Value $expiration
$accts += $obj
}
Write-Output ($accts | Format-Table | Out-String)
This prints to the console perfectly:
Name Email Expiration
---- ----- ----------
Victor Demon demonv#nsula.edu 1/3/2016 7:16:18 AM
However when called with | Export-Csv it doesn't:
#TYPE System.String
Length
5388
I've tried multiple variations using objects, and data tables, however it seems like I can only get it to work for console or for CSV, not for both.
Replace
Write-Output ($accts | Format-Table | Out-String)
with
$accts
That way your users can run your script any way they like, e.g.
.\your_script.ps1 | Format-Table
.\your_script.ps1 | Format-List
.\your_script.ps1 | Export-Csv
.\your_script.ps1 | Out-GridView
...
Format-Table | Out-String converts your output to a single string whereas Export-Csv expects a list of objects as input (the object properties then become the columns of the CSV). If Export-Csv is fed a string, the only property is Length, so you get a CSV with one column and one record.
$accts | ConvertTo-Csv | Tee -File output.csv | ConvertFrom-Csv

How do I show the value of LastLogonTime from a mailbox query

How can I show the value of the attribute LastLogonTime?
function Get-MailboxesNotLoggedOnTo {
param(
[int]$days = 90
)
$mailboxes = Get-Mailbox -ResultSize 500
$mailboxes | Where-Object {
(Get-MailboxStatistics $_).LastLogonTime -and
(Get-MailboxStatistics $_).LastLogonTime -le (Get-Date).AddDays(-$days)
} | FT DisplayName, Alias, ServerName, LastLogonTime
}
This is happening because Get-Mailbox does not return a property called LastLogonTime. Get-MailboxStatistics does. What you need to do is add the timestamp as a property of your output
$mailboxes = Get-Mailbox -ResultSize 200
$mailboxes | Where-Object {
(Get-MailboxStatistics $_).LastLogonTime -and
(Get-MailboxStatistics $_).LastLogonTime -le (Get-Date).AddDays(-$days)
} | ForEach-Object {Add-Member -InputObject $_ -MemberType NoteProperty -Name LastLogonTime -Value (Get-MailboxStatistics $_).LastLogonTime -PassThru} |
Select DisplayName, Alias, ServerName, LastLogonTime
Using Add-Member we can fill in the missing piece. The one issue I have with this is the multiple calls to Get-MailboxStatistics which im working on improving now. Should be something closer to this.
$checkDate = (Get-Date).AddDays(-90)
$mailboxes = Get-Mailbox -ResultSize 200
$mailboxes | ForEach-Object{
$stats = Get-MailboxStatistics $_
If ($stats.LastLogonTime -and ($stats.LastLogonTime -le $checkDate)){
Add-Member -InputObject $_ -MemberType NoteProperty -Name LastLogonTime -Value $stats.LastLogonTime -PassThru
}
} | Select DisplayName, Alias, ServerName, LastLogonTime
The extra calls to Get-MailboxStatistics would make it slower. Reduced the call to only the one. Still using Add-Member with -PassThru which just pipes out to a select statement. This should be a more efficient approach.