Powershell script to stem the flow of spam from a compromised account.

So I work for a community college.  And .edu’s are very, very popular with phishers.  And we have users that still respond to those emails that ask them for their username and password.  So, every semester, we have at least one or two compromised accounts.  And these can do a ton of damage to your email reputation in one overnight binge.

Now, being the kind of person that likes to occastionally sleep, I needed a way to stem the flood of spam until I could be awake enough to deal with it.  So how, on exchange 2003, do you do that without interfereing with normal email operations or buying additional products?

Well I came up with what I think is a pretty nifty script and I’m going to share it with you now.

First we have to get the queues and we do that with the get-wmiobject for exchange.  Can’t give you a ton more info there because I shamelessly googled it.

$queues=get-wmiobject -class exchange_smtpqueue -namespace root\microsoftexchangev2 -computername yourserverhere

Next we pipe the results of that to a foreach loop which gets us the number of messages in each queue.  The foreach loop has an IF statement in it that increments a counter if the queue has more then 10 messages in it.

| foreach-object{if($_.messagecount -gt 10){$counter=$counter + 1}}

Next we check to see the value of the counter.  If the value of counter is greater then 3 we drop into the IF statement and send an email with the value of counter.

$queues=If($counter -gt 3){$emailFrom = "me@blah.blah"
           $emailTo = "me@blah.blah,you@blah.blah,everyone@blah.blah"
           $subject = "Servername Queues are Filling Fast"
           $body="More than " + $counter + " queues are filling!"
           $smtpServer = "yoursmtp.server.com"
           $smtp = new-object Net.Mail.SmtpClient($smtpServer)
           $smtp.Send($emailFrom,$emailTo,$subject,$body)

The step that is very important comes next.  We’re going to actually stop the smtp service on the exchange server so we don’t flood the world with more spam.

sc.exe \\yourserver.name.here stop smtpsvc

Then we close the IF statement and clear the counters just in case.

Complete version of the script. Bits in bold you need to enter your own info for.  As always, if you can do it better, share with me.

$queues=get-wmiobject -class exchange_smtpqueue -namespace root\microsoftexchangev2 -computername yourserverhere | foreach-object{if($_.messagecount -gt 10){
$counter=$counter + 1
}}
$queues=If($counter -gt 3){$emailFrom = "me@blah.blah"
           $emailTo = "me@blah.blah,you@blah.blah,everyone@blah.blah"
           $subject = "Servername Queues are Filling Fast"
           $body="More than " + $counter + " queues are filling!"
           $smtpServer = "yoursmtp.server.com"
           $smtp = new-object Net.Mail.SmtpClient($smtpServer)
           $smtp.Send($emailFrom,$emailTo,$subject,$body)
sc.exe \\yourserver.name.here stop smtpsvc
}

$counter=0
$queues=0

Leave a comment

Filed under Just Powershell

FIXED! Constituency redirect or inability to get consituency into student and have it stay, take your pick

So we’ve had this ongoing problem since we went live with the Datatel Portal.  We have students that don’t get a Consituency when they are created and imported into SharePoint.  I’ve been chasing that dog for months including implementing all kinds of powershell scripts to find them, fix them and fix them as they are created.  We also had a problem for awhile where SharePoint flat out refused to run the profile import on a schedule.  I got SharePoint all happy again, profile imports are on schedule and successful but we’re still getting complaints every day about the constituency redirection.  I already have three powershell scripts that watch the AD for accounts created and it sets their constituency but after running all those scripts we’re still getting complaints so I figure that some process we’re running is removing the Primary Constituency for some students.  Rather then make yet another powershell script to fix that I approached the problem from a different direction.  How about we just send everyone to the Student Constituency page if they don’t have a value of Faculty or Staff?

So off to Google I go.  And I found this absolutely beautiful, AND FREE, webpart.   http://www.sharepointsecurity.com/sharepoint/sharepoint-development/redirector-webpart-sp-solution-file-download/

It wasn’t a huge challenge to install but I will give you the hint to getting rid of the security error you get when you’ve got the webpart on a page.  Here’s the overall basic steps but he goes into good detail on everything but #5,6,7,10 :

1) Download the webpart.
2) Add the solution.  

stsadm -o addsolution -filename RedirectorWebPart.wsp

3) Deploy the solution.

stsadm -o deploysolution -name RedirectorWebPart.wsp  -immediate -allowCasPolicies -allcontenturls

4) Activate the feature.

stsadm -o activatefeature -name RedirectorWebPart -url

5) Make a webpage in your https://site.url/pages library.  This is in the home site and is the place where the default.aspx resides, which does the Datatel delivered redirection.  Just make it a basic webpart page.

6) Add the webpart to the page.  You may get this error:  ‘Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c’.  See step 7.

7) If you are receiving the error above then you need to copy the redirectorwebpart.dll from the c:\inetpub\wwwroot\wss\virtualdirectories\Yourportnumberhere\bin directory to the c:\windows\assembly directory.  I’ve always done a drag and drop for this as I haven’t had alot of success with copying and pasting into the assembly.  You need to do this step on every web front end you have.

8) Configure the web part.  If you go to your url https://site.url/pages/rediret.aspx as an administrator you’ll see the webpart and it looks like it as an error.

Redirector Webpart screenshot 1

This is the normal behaviour for an administrator user.  You will not be redirected anymore.  Instead you will remain at this page and you can now configure the webpart per the directions.

Screen Shot Redirector webpart

9) Test your page as an average user.  The webpart is designed to not redirect admins, which personally I find really nice, but it should work as you expect for the user.

10) When you’re all happy that your redirect.aspx page is working the way you want and expect, then goto site settings for your home site, click on welcome page and change the url there from default.aspx to redirect.aspx.

Screen shot site settings

That’s it.  From now on if you have someone that doesn’t have a constituency they will be automatically redirected to the student page.

I want to give a really big THANK YOU to Adam Buenz of ARB Security Solutions for providing this fabulous webpart as Freeware.

2 Comments

Filed under Datatel Portal, Sharepoint

Powershell split large txt file

So I have a Live@edu implementation with almost 100,000 mailboxes and since we’re still finishing out some of our implementation items I pretty regularly have to run processes against large bunches of users.  I get those files by pulling them with powershell from Live@edu but what I have then is one really large csv file.  Since I’ve had problems with my process timing out while running on that huge file, leaving me wondering where it broke, I like to split it down into more bit sized pieces.  I used to do it with Excel but that’s tedious and unnecessary if you’ve got powershell.

So here’s my script now to split the file automatically into chunks based on the value you provide after -readcount:

$File=‘d:\latest_student_list.csv’ 
$Count =1 
$InputPath =Resolve-Path $(Split-Path-Parent$File) 
$InputName = [IO.Path]::GetFileNameWithoutExtension($File) 
$InputExt = [IO.Path]::GetExtension($File) 
Get-Content  -LiteralPath$File-ReadCount 10000 | ForEach-Object{ 
$OutputFile=Join-Path$InputPath"$($InputName)_$($Count)$InputExt"
 Add-Content$OutputFile$_ 
$Count++ 
}  

This was really cool but made an oppsie while fixing my GALdisabled problem. I set the mailbox for our proxy account to GALDisabled as well as all the users which broke our Datatel web parts. So I decided to protect myself from messing up that account again by having this script automatically remove that account before it splits the file.  Here’s my changed script:

$File=‘d:\latest_student_list.csv’
$file2='d:\latest_student-list.csv'
$saveproxy = Get-content $file | foreach-object{$_ -replace 'accountname*', ''} | Set-content $file2
$Count =1
$InputPath =Resolve-Path $(Split-Path-Parent$File2)
$InputName = [IO.Path]::GetFileNameWithoutExtension($File2)
$InputExt = [IO.Path]::GetExtension($File2)
Get-Content  -LiteralPath$File2-ReadCount 10000 | ForEach-Object{
$OutputFile=Join-Path$InputPath"$($InputName)_$($Count)$InputExt"
Add-Content$OutputFile$_
$Count++
}

I am absolutely sure that someone can produce a more streamlined version of this script.  I am a script klugger, not a script artisan.  It works and that was what I was worried about.  Next up on my improvement list is to add the ability to add a set of column headers to each file as it’s split out so if you get this itch to contribute just drop me a comment…..

Leave a comment

Filed under Just Powershell, Live@edu

Neat Sharepoint Slide Show Webpart – Free!

I have had several sharepoint slideshow webparts and each of them had a little bit of pain to setup.  One looks really cool but you have to make an xml file of the images to use.  Another required an edit of the web.config file which has been a problem in the past.  So I was looking for a new one that would look nice, work in my https portal and be simple for me and the user to implement.

Today I found it – http://www.spelements.com/spelements.com/spslideshow/

Works very nicely, very easy to install and my favorite – it’s totally free.

Leave a comment

Filed under Datatel Portal, Sharepoint

Name changes in Sharepoint

We’ve been having this ongoing problem of name changes with sharepoint.  Actually we’ve had a terrible time with the user profile service all along but at the moment I have it tamed. (Long story there that will be saved for a different blog)  But we’ve been having a problem were users in AD get a name change.  The name change is replicated to the SSP but the Welcome statement when they login isn’t updated.  I googled it quite a bit and came across this handly little STSADM extention so I thought I would share it.

http://hwamigrateuser.codeplex.com/releases/view/19029

It’s both easy to use and it works!  I need multiple admin people to be able to use so I’m going to write a powershell script that allows them to batch users with a csv that feeds the info to the STSADM extention and I’ll share that when I have it done.

Leave a comment

Filed under Datatel Portal, Sharepoint

Live@edu GAL Gotcha

So I’m in the process of fixing a little GAL gotcha.  We are an entirely GAL disabled mailbox plan district for the students.  Imagine my surprise when I got a complaint from a student that they didn’t want to be listed in the GAL.   I logged in with a test account and sure enough there were some users listed in the GAL again.  Not all users.  And no rhyme or reason for the ones that were listed in the GAL.  So I checked the mailbox settings in the GUI and they all were set to GALdisabled mailbox plan.

At that point I opened a ticket with Microsoft support.  It’s been escalated three times now and is in the hands of the Product Engineers.  They are researching why it’s behaving this way.

But since it’s been a couple of days and we haven’t gotten anywhere I whipped out my powershell again and tried just setting the GALdisabled mailbox plan on the mailboxes.  That didn’t produce any changes so I picked a problem user, enabled the default mailbox plan and then set the mailbox to GAL disabled mailbox plan again.  This worked.  The problem user disappeared from the GAL.  Rinsed and repeated a few times and got consitent results.

The bummer is that I can’t make a list of the “broken” mailboxes because they all report as GALdisabled.  So I’m going to break them down into batches and run them through the following scripts:

Script 1

Get-Content "d:\wxyz.csv" | Set-Mailbox -MailboxPlan DefaultMailboxPlan

Script 2

Get-Content "d:\wxyz.csv" | Set-Mailbox -MailboxPlan GalDisabledMailboxPlan

I’m building the list to work from with my script that retrieves all mailboxes and their email addresses. That will be up in another blog post shortly.

I don’t have any word officially from Microsoft on what’s caused this but I think it has to do with our recent migration to R5.  We were setting the galdisabled on the mailboxes as the migration was occuring and I think things got corrupted.

—–UPDATE—–

Still don’t have an official resolution or answer from Microsoft but they did tell me that during a migration all mailboxes are reset to the DEFAULT mailbox plan for the migration.  I have asked, but assume, that they change them back to GALdisabled when the migration is finished.  But it means that it’s worth double checking your GAL after every upgrade/migration or you might find you now have some mailboxes showing……

—–UPDATE—–

You might gotcha yourself cleaning this up like I did.  We have a proxy account that is used for our datatel single-signon webparts like unread messages and my week.  That accounts mailbox must remain default mailboxplan.  If you galdisable it, you break it.  When I fixed my gal problem above what I had done was pull a list of all mailboxes from Live@edu then systematically ran them thru the two scripts but unfortunately our proxy was included in that list and broke the webparts.  My bad.  So I now have a fabulous script to break large files of user accounts into 10,000 record bite sized pieces and I’m going to see if I can write an if statement in there to exclude that special proxy account so I don’t shoot myself in the foot again.

2 Comments

Filed under Just Powershell, Live@edu

Live@edu – Inject calendar appointments into all students calendars

This really “expanded” my horizons a bit.  I thought it would be really useful to put our important dates onto the students calendars for them.  This would cause the dates to show on their calendars in Outlook.com, on their phone, in the portal and could even send them text reminders if they’ve set that up.  But to do this you have to get into the Exchange Web Services.  Scary but cool.  Since I knew how to do part of this with powershell I approached it with powershell calling EWS. 

For details on how to download/ install Exchange Web Services http://www.microsoft.com/downloads/en/details.aspx?FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1.  This should be installed on the machine where you plan to run the script.  I have included some commented out lines so you can test the script without applying it to all of your accounts at once.  You will need to have a windowsliveid that has the EWSImpersonation role assigned to it.  If you’ve setup the My Week webparts for the Datatel Portal to work with Live@edu then just use that account as it’s already setup with that role.  I will be running this every semester for the entire mailbox list but I am also going to add it to all the other things I do to accounts/mailboxes as they’re created so all new students will have the list as well.

Below the script I list the websites I used to get tidbits from as I believe in giving full credit where credit is due. 

Param ([string]$calInputFile = $(throw "Please provide calendar input file..."))
# Testing
#$calinputfile="d:\calendar_inject.csv"
# Connect to Live@edu
# capture the admin LiveID username in a variable
$Username = "Your admin account for powershelling live@edu"
# capture the admin LiveID password in a variable.  Note, that it is stored as a secure string
$Password = ConvertTo-SecureString ‘Password for account above’ -AsPlainText -Force
# populate the $Livecred PowerShell credential with $Username and $Password
$Livecred = New-Object System.Management.Automation.PSCredential $Username, $Password
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $Session
# Load EWS Managed API library
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\1.1\Microsoft.Exchange.WebServices.dll"
# Load all Mailboxes
$exchangeUsers = Get-Mailbox -ResultSize Unlimited | Select UserPrincipalName
#test with just one user
#$exchangeusers = get-mailbox user@domain.com |select UserPrincipalName
# Load all calendar Entries
$calEntries = Import-Csv $calInputFile
# Identify the folder to save our appointments into
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar)
# Create Exchange Service object
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2010)
$service.Url = new-object System.Uri("https://ps.outlook.com/EWS/Exchange.asmx")
# Service account must have ApplicationImpersonation ManagementRoleAssignment in Exchange
$service.Credentials = new-object Microsoft.Exchange.WebServices.Data.WebCredentials("live@edu account with EWSImpersonation role","password")
foreach($mailbox in $exchangeUsers)
{
 # Identify user to which appointment will be added
  $MailboxName = $mailbox.UserPrincipalName
  # Instruct service to use impersonation
  $iUserID = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,$MailboxName)
  $service.ImpersonatedUserId = $iUserID
  # Create new appointment object for each appointment to save
  foreach($entry in $calEntries)
  {
   $appt = New-Object Microsoft.Exchange.WebServices.Data.Appointment($service)
   $appt.Subject = $entry.Subject
   $appt.Start = [System.DateTime]($entry.StartDate)
   $appt.End = [System.DateTime]($entry.EndDate)    #For AllDayEvent, end date must be after start date
   $appt.IsAllDayEvent = $True
   $appt.LegacyFreeBusyStatus = "Free"
   $appt.IsReminderSet = $False   #If you want a reminder then remove this line
  # $appt.Save($folderid)
 $appt.Save()
  }
}
 

This was hands down the most useful post.  There were a few tweaks I had to make.   http://social.technet.microsoft.com/Forums/en/exchange2010/thread/27affc1c-f96a-455f-95e9-cbcbc741720b

This one was also helpful and would be even more helpful if you’re working on showing calendar info in sharepoint. http://gsexdev.blogspot.com/2009/11/basic-powershell-script-to-show.html

This has much more info on Exchange Web Services and powershell.  Caveat:  Exchange Web Services is now installing into the 1.1 directory not 1.0 so just update the path in your script.   http://gsexdev.blogspot.com/2009/04/using-ews-managed-api-with-powershell.html

As always I welcome/would appreciate feedback.  I will be the first to admit I’m more of a Script Kluger then a Script Artisan.

Leave a comment

Filed under Datatel Portal, Just Powershell, Live@edu

Get rid of old powershell session in Live@edu

I was hammering away today on my latest scripting piece for live@edu and I did something silly.  I closed some of my frustrated powershell windows without removing my sessions from live@edu.  Well quicker then I could snap my fingers I was out of sessions.   I’ve never been that naughty before so I started googling for the way to clear those abandoned sessions.

All I found was this article which tells you have to remove the session while you’re still in the powershell window but it did have this gem tucked away at the bottom:

If you’ve been naughty like me you will be sent to the corner for 15 minutes until your abandoned sessions are timed out.

So I took this opportunity to get some water and write this blog post.

http://207.46.16.237/en-us/140/cc952755.aspx

Should I get lucky and get my script to successfully run you all will be in for a tasty treat later…..

Leave a comment

Filed under Uncategorized

Import a CSV with different headers

I had a case recently where the csv file I was writing didn’t have the header that I needed to read with the next script.  I eventually re-wrote the whole process into a single line with a lot of things pipeing to eachother but I did figure out how to import the the csv with a header that I specified at the time of the import.

PS>import-csv myfile.csv -header "samaccountname"

or you could

PS>$header = "samaccountname", "mail", "password", "description"
PS>import-csv myfile.csv -header $header

or maybe you need to remove the top line of the file and then import it with a new header

PS>$header = "field1", "field2", "field3", "field4"
PS>$a = (get-content myfile.csv)
PS>$a=$a[0], $a[2..($a.count -1)]
PS>$a>myfile.csv
PS>import-csv myfile.csv -header $header

All very handy stuff.  Here’s the microsoft doc I got it from: http://technet.microsoft.com/en-us/library/dd347665.aspx

Leave a comment

Filed under Just Powershell

Favorite Blog for Powershell stuff

I wanted to share one of my favorite blogs for powershell and AD stuff.  I’ve used this blog for quite a few things as I was learning powershell.

He’s got a ton of great info but here are some of the ones I’ve used most:

Get a list of ALL user properties – http://dmitrysotnikov.wordpress.com/2007/06/28/get-a-list-of-all-user-properties/

Set ANY AD attribute with PowerShell – http://dmitrysotnikov.wordpress.com/2007/07/25/set-any-ad-attribute-with-powershell/

PowerShell cmdlets for AD – http://dmitrysotnikov.wordpress.com/2007/03/22/powershell-cmdlets-for-ad/

OU Managment with Powershell – http://dmitrysotnikov.wordpress.com/2007/05/04/ou-management-with-powershell/

Hopefully I’ll have time to give you some examples that relate directly to Live@edu and the Datatel Portal.

Leave a comment

Filed under Just Powershell