user1905097
user1905097

Reputation: 39

enumerate and email with powershell

ok fellas, I've been reading, researching, learning and testing about powershell. Within the last 20 days, here is what I've been able to come up with.

get-mailbox -identity $_.name | select name,userprincipalname,@{label="Size";expression={$size = Get-Mailboxstatistics $_.identity;$size.TotalItemSize.Value.ToMB()}},@{label="Items";expression={$items = Get-Mailboxstatistics $_.name;$item.ItemCount}}

I stored this in a script called accountsizes.ps1. It works exactly as I expected by outputting all the email accounts with the sizes, but in order for me to get only the mailboxes over 2048MB, I have to call it like this:

PS C:\accountsizes.ps1 | where size -gt "2048" | select userprincipalname,size

And this works by return the email addresses and mailbox sizes in MBs. But now my dilemma is; how do I enumerate through the results and extract each email address and send an email to that user and myself, warning them that their mailbox is too large and they need to archive. From what I been reading and learning, I would have to use a ForEach loop and the send-mailmessage cmdlet. I cannot figure out how to use the ForEach and incorporate it with the script: Here is I go brain dead with the ForEach:

PS C:\accountsizes.ps1 | where size -gt "2048" | select userprincipalname,size | ForEach($user in userprincipalname){$_.userprincipalname}

I do not know the right way to go about doing this (so, don't ask me why I'm doing this way :)), I have no previous knowledge about scripting and coding.

Here is my email part:

$smtpserver = "domain.com"
$smtpFrom = "[email protected]"
$smtpTo = "[email protected]"
$messageSubject = "Warning Email Mailbox Too Large"
$body = "blah blah blah blah"

send-mailmessage -from $smtpFrom -to $smtpTo -subject $messageSubject -body $body

Thanks in advance for your helpful advice.

Upvotes: 0

Views: 2003

Answers (2)

TheMadTechnician
TheMadTechnician

Reputation: 36297

Paolo provided excellent information and deserves upvotes if nothing else. As to your question of how to enumerate and send email you probable need something like:

C:\accountsizes.ps1 | where size -gt "2048" | %{
    $smtpServer = "smtp.domain.com"

    #Creating SMTP server object
    $SMTP = new-object Net.Mail.SmtpClient($smtpServer)

    #Creating a Mail object
    $EMail = new-object Net.Mail.MailMessage

    #Construct Email 
    $EMail.From = "[email protected]"
    $EMail.ReplyTo = "[email protected]"
    $EMail.To.Add($_.userprincipalname)
    $EMail.subject = "Warning Email Mailbox Too Large"
    $EMail.body = "blah blah blah blah"

    $SMTP.Send($EMail)
}

You could get a lot more fancy, go by size and send different emails depending on how large their mailbox is, or get content from files for subject and body depending on size, but that is just going to make things complicated. You could also use Send-MailMessage, and that works just fine, I just like this way because it makes it easier to work with in my opinion than one really long line with a ton of switches. If the message and subject are going to be generic you may want to do something more like: $smtpServer = "smtp.domain.com"

#Creating SMTP server object
$SMTP = new-object Net.Mail.SmtpClient($smtpServer)

#Creating a Mail object
$EMail = new-object Net.Mail.MailMessage

#Construct Email 
$EMail.From = "[email protected]"
$EMail.ReplyTo = "[email protected]"
C:\accountsizes.ps1 | where size -gt "2048" | %{$EMail.BCC.Add($_.userprincipalname)}
$EMail.subject = "Warning Email Mailbox Too Large"
$EMail.body = "blah blah blah blah"

$SMTP.Send($EMail)

That would make one email and BCC everybody on it. Then you could do another email to yourself stating who warnings got sent to.

Upvotes: 1

Paolo Tedesco
Paolo Tedesco

Reputation: 57202

The foreach keyword and the ForEach-Object cmdlet are two different things.

If you use the foreach keyword, you give a name to the iteration variable, and you iterate on a collection. For example:

$collection = @("one", "two")
foreach ($item in $collection) {
    Write-Host $item
}

Instead, if you pipe commands outputs, you have to use the ForEach-Object cmdlet with a script block. Inside the script block, you refer to the iteration variable with the special variable $_. Example:

$collection = @("one", "two")
$collection | ForEach-Object {
    Write-Host $_
}

You can shorten ForEach-Object with %:

$collection | % {
    Write-Host $_
}

So, in your case you should probably do this:

C:\accountsizes.ps1 | where size -gt "2048" | select userprincipalname,size | % { $_.userprincipalname }

Upvotes: 2

Related Questions