Absoblogginlutely! » Posts in 'Powershell' category

Retrieve Mailbox Migration errors for Office365 No comments yet

When you have a lot of mailboxes to migrate, Microsoft’s provided method of viewing the errors involves a tedious amount of clicking by logging into the portal, selecting Exchange, Migration, View details, scroll down to find a failure, select the user, click view details.

Viewing Migration status in Office365

 

Rather than use the tedious method of going into the details, selecting a user and then viewing details, run the following powershell script (once connected using the previous office365 connection script)

get-migrationuser -status failed  | get-migrationuserstatistics | select identity,emailaddress,recipienttype, error,bytestransferred |export-csv c:\temp\migrationstatus.csv

I also have a simple loop that gets me the status once an hour. Obviously change the email address’s appropriately.

while (1)
{
$a=(get-migrationuser | out-string)
send-mailmessage -to myemailaddress@domain.com -subject “Company Migration Stats” -from administrator@company.com -smtpserver my.mailserver.com  -body $a
start-sleep -seconds 3600
}

Find mailboxes that have the Email Address Policy disabled No comments yet

Took me a while to work this one out but the powershell line for this is

get-mailbox | where {$_.EmailAddressPolicyEnabled -eq $false}

Or you could switch it to the following but this is less easy to read for junior techs to understand as the ! is not necessarily obvious.

get-mailbox | where {!$_.EmailAddressPolicyEnabled}

Pimp your Powershell Prompt No comments yet

I use powershell a lot at work – I’m not a guru by any means and I often find it hard to remember the commands I have run in a session, either for future use or for documenting in my time sheet (which also acts as a point of reference for future helpdesk tickets).

When I started going through the Powershell in a month of lunches book (which I highly recommend or the Powershell v3 book) I decided to use the start-transcript commandlet to record all my powershell activities.  This worked very well until I would scroll through several screens worth and then forget what file I had saved my transcript too.  There was also the possibility of forgetting to transcript everything.

By using the powershell profile file I was able to enter the commands to automatically set the transcript to the current date. I was then able to modify the title of the powershell prompt to display the filename so I could always see where the file was saved with the added bonus of a variable being used if I ever needed to open the transcript

My next step was to include the time in the powershell prompt – this enables me to go back through the transcript and see how long it took to run the commands for my timesheet entries.  Remembering back to the good old dos days, I remembered the prompt command. A quick bit of experimenting with the Date command I had the current time displayed at the beginning on the Powershell prompt. Note this is displayed after the previous command is run, so technically it’s not the exact current time, but the time that the prompt was displayed on the screen.

The final profile script can be copy/pasted into notepad by typing in

notepad $profile

is as follows:-

cd \andy\powershellinamonthoflunches

$log="c:\temp\powershelllogs-" + $env.username + (get-date -uformat "%y%m%d-%H%M") + ".txt"
start-transcript $log
$host.ui.rawui.WindowTitle = $log

function prompt
{
write-host ((Date -uformat %T).ToString() + "PS " +$(get-location) + ">") -nonewline
return " "
}

This ends up with a powershell prompt that looks like the following. Hope this brief posting inspires you to change your powershell prompt to be even more useful for you.

 

Powershell prompt with the filename in the title and current time in the prompt

 

Fixed – Office365 journalling does not work for one user No comments yet

I’ve been working on a case with Microsoft’s Office365 support for several weeks trying to find out why email sent *to* a particular user was not being journalled. All the other mail seemed to be journalled to the external recipient, email from the user was working, just not email to that user.

The experience was quite frustrating as Microsoft’s support were terrible at calling back and could not grasp the concept of email tracking. Their solution after making a change was to wait a day to see if it was fixed although it was quite apparent that the Microsoft servers were not even trying to send the email (by looking at the Trace Logs you can see what email was being sent and received).

After checking the connectors were setup, mail properly scoped, the user had no rules on their mailbox, Microsoft’s solution was to delete the mailbox and reset it up again.  Not so easy when the mailbox/user is federated with Active Directory and the user happens to be the owner of the company. That was not a conversation I was going to have with them!

The only thing that was different with this user was that in troubleshooting this issue we had set the user up to receive the journalling non delivery reports. I figured that if the emails were not being delivered, maybe sending him the errors would help. However no reports were being received either.  However, according to KB 2829319 this behaviour can be seen. Although I had removed the journal receipient in the web gui, the emails were still not being journalled until I added another external email address to the configuration using the powershell command set-transportconfig -JournalingReportNdrTo myemailaddress@somethingorother.com

At this point, all the email started to be journalled.

Note that we only added the recipient into the mix when I was trying to work on the initial problem so it looks like this wasn’t the only fix.

The other thing we did was change the outboundconnector to be onpremises. Changing the setting in the GUI we then ran Set-OutboundConnector archivemymailconnector -routeAllmessagesviaonpremises $true.

 

These two combinations seemed to fix the issue.

One thing I also learnt was that it is really useful to send multiple emails between changes and keep the subject line starting the same. Use the date/time at the end of the email. That way you can sort the email logs by Subject and just pick out the ones you were working on. By having the subject start with zzz followed by Round X (ie zzz Round 1 – change connector – 1345pm and zzz Round 1 – change connector 1346pm ) then the results are likely to appear at the end of your mail logs if you sort by subject.  Sorting by Date was not always a good idea as mail flow could occur between mail coming into the server and mail leaving the server.

 

Fixed: Installing Powershell 3 fails on Windows7 with “The update is not applicable to your computer” 2 comments

Powershell 3 was released this week and is now available to download for Windows 7 (sp1) platforms. I tried to install it on my home machine this weekend and got
“The update is not applicable to your computer”. It turns out that this is actually because .net framework 4 (or higher) has not been installed.
The full .net 4 framework package is available at http://www.microsoft.com/en-us/download/details.aspx?id=17718 or you could install the newer 4.5 framework at http://www.microsoft.com/en-us/download/details.aspx?id=30653. Make sure that you close the false powershell installation before attempting the .net installation or the .net will try to install for about 5 minutes on your computer and then complain that another install is already in use and does not give you the option to retry. You can only abort and then run the whole installation again. All in all a pretty bad user experience for trying to install the software.

Thanks to the Troubleshooting guide for the beta version of Powershell 3 that tipped me off for the pre-reqs which are not mentioned on the original download page for Powershell 3 and unfortunately there is no place on that web page to provide feedback.

Scripting Guys blog formatting – now in html format. No comments yet

You can thank me later ;-)

On my way home from work late the other night I was listening to episode 152 of the Mind Of Root Podcast where Keith and Steve interviewed Ed Wilson from the Hey Scripting Guy! blog. It was a really interesting podcast and explained their goals to get users learning Powershell and push out some best practice ideas.  So far I like the power of Powershell but I’m finding the learning curve pretty steep. Especially as I can do a lot of my scripting requirements within a normal dos batch file in a lot fewer lines than Powershell requires. However I do understand that Powershell provides a lot more functionality, especially when built into products such as BPOS, exchange etc.

The next weekend I found Ed’s scripting blog, read a few articles, commented on one about using streams.exe to unblock zip files (been there, done that – very frustrating to find out you should unblock a zip file before extracting many thousands of files) and then subscribed to the blog feed.

Unfortunately the blog posts lost all their formatting when reading the rss feed so something that looks nice and clear on the webpage

Hey Scripting Guy! blog showing formatting of blog postlooked horrendous when viewed in Google reader – there are no line breaks, text formatting or anything else that makes the blog post easy to read.

Hey Scripting Guy blog post in Google Reader.I’m not quite sure why the post is a garish pink colour either, but I could live with that.

A quick look through other blogs hosted on blogs.technet.com show that formatting can be preserved (see Matt Hesters Blog feed) below so I sent an email to Ed Wilson to see if the settings could be changed.

imageHe responded back the next day and said he would pass the request onto the webmaster.  Since then I’ve been checking the rss feed and the website and today everything is displaying correctly (it looks like the switch started yesterday).  So thanks to Ed and the Technet website admins – the change is really appreciated. Hopefully this makes the reading of the blog easier for everyone else too!

Enabling powershell to run scripts with registry permissions. 1 comment

As part of my powershell work I obviously need to run powershell scripts. I tried to run one last night and got the usual message about scripts needing to be signed. I had previously changed the settings on my XP machine, but this was obviously the first time I had run a script on my Windows7 machine.

Running the usual “set-executionpolicy remotesigned” I got the following error message “Execution Policy Change. The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose you to the security risks described in the about_Execution_Policies help topic. Do you want to change the execution policy?”

Answering Yes to the prompt I then got the following error message – “Set-ExecutionPolicy : Access to the registry key ‘HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell’ is denied”. Sure enough I don’t have permission to this registry key.

I checked with our admin to ensure this wasn’t set in group policy before I started fiddling around. Found out that there is another setting that is user specific that can be set with “Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

After doing this I was then able to run scripts, and more importantly my profile script runs. Seeing as though this is my workstation I don’t really care about anyone else’s powershell scripts on my machine ;-)

However, if you want to set it for all users, then set the Scope Parameter to be LocalMachine

To set it domain wide, you need to download the PowerShell group policy templates from Microsoft and follow the instructions to set up a policy.

Powershell script to retrieve email from archived mailbox in Exchange2007 No comments yet

The other powershell script I worked on was to retrieve a detached mailbox that was still retained in exchange, archive the mail to a pst file, move the pst file to the managers home directory and then delete the mailbox again.
The following script does this – note some paths are hardcoded and I already have a temporary account in AD called tempuser that does not have a mailbox. This is the account that the deleted mailbox is attached to.
The main disadvantage to this method is that at the end of the script all of the detached mailboxes will appear as tempuser in the exchange console. In this particular script I also do very little error checking as this was designed for my use but hopefully helps others too.


$user=$args[0] #user is the first parameter passed
$fname=$args[1] #first name
$lname=$args[2] #last name
$fullname=$fname + " " + $lname
$manager=$args[3] #manager windows accountname is the last parameter passed
if ($manager -eq $null) {exit} # if not enough parameters are provided then quit the script

write-host $user
write-host $manager
$Host.UI.RawUI.WindowTitle = "attaching mailbox to tempuser account"

$result=Connect-Mailbox -Identity $fullname -Database 'servername\First Storage Group\Standard User Mailbox' -User 'domain\tempuser' -Alias 'tempuser'

$Host.UI.RawUI.WindowTitle = "Sleeping 60 until moving mailbox"
start-sleep -s 60 # sleep 60 seconds after moving mailbox to tempuser account before doing the export

$Host.UI.RawUI.WindowTitle = "exmerging mailbox"
export-mailbox tempuser -pstfolderpath d:\mailboxes -confirm:$false

$Host.UI.RawUI.WindowTitle ="sleep 20 seconds"
start-sleep -s 20 # sleep 20 seconds after exporting mailbox to tempuser account before doing the mailbox move

$Host.UI.RawUI.WindowTitle = "Moving pst file to managers mailbox"
$newdir="\\archiveserver\c$\users\" + $manager + "\" + $user
$result=mkdir $newdir
$newpst=$newdir + "\" + $user + ".pst"
$newpst
Move tempuser.pst $newpst

$Host.UI.RawUI.WindowTitle = "disabling tempuser mailbox for reuse"
disable-mailbox tempuser -confirm:$false

Note that I use the $Host.UI.RawUI.WindowTitle statement a lot – this enables me to easily see whereabouts in the script I have got to. I much preferred to use the command title in my batch files to do the same thing. Likewise the $null = $host.UI.RawUI.ReadKey(“NoEcho,IncludeKeyDown”) is the equivalent of the batch command pause

Powershell script to retrieve list of emails from Exchange2007 in the past 24 hours. No comments yet

As in my previous post I needed to obtain a list of emails that have gone through a mail server within the past 24 hours (so it can be run on a daily basis). I struggled with the code initially but ended up with the following.

$yesterday = (get-date).adddays(-1).tostring(“g”)
$rightnow = (Get-Date).ToString(“g”)
get-messagetrackinglog -Start $Yesterday -End $rightnow -EventID RECEIVE -Result size 5000| select-object EventID,Sender,@{name=’Recipients';expression={[string]::join(“;”,($_.Recipients))}},MessageSubject,TimeStamp | export-csv receive.csv
get-messagetrackinglog -Start $Yesterday -End $rightnow -EventID SEND -Resultsize 5000| select-object EventID,Sender,@{name=’Recipients';expression={[string]::join(“;”,($_.Recipients))}},MessageSubject,TimeStamp | export-csv send.csv

My next step is to automate this and send it via email

Twitter helped me with powershell this week. No comments yet

This week at work I’ve been doing a fair amount of work with powershell. It has been a slow process as I’ve had no training in powershell and was basically teaching myself as I went along. I had two goals in mind.

The first was to automatically attach a mailbox to a temporary account, export the mail within this mailbox to a pst file, move the pst file to a folder and then delete the account again.  As Exchange2007 needs to use powershell to export the data I had to change my user deletion script to run within powershell.

My other goal was to write a report for all mail sent or received through the exchange server in the past 24 hours. Using the exchange tracking logs I was able to pull the information required to do this.

The second problem was causing me more hassles  as I could not work out how to retrieve the time from 1 day ago AND have the result in the format needed for the next part of the script. I could get the current time in the correct format OR I could get the time from 1 day ago but not in the current format. I went onto the #powershell room on irc.freenode.net but it looked like everyone was asleep as I didn’t get any response to my query.  I decided to post a tweet on twitter about the problem and within 5 minutes I had about 3 or 4 responses which was great. At the same time I also got a response in the chatroom. As usual with coding, there are several ways to get an answer.  However Jaykul was very helpful in telling me that “get-date (get-date).addays(-1) -f g”  is 2 ten thousandths of a second quicker than “[datetime]::now.adddays(-1).tostring(“g”)”
Best way to get the Time from 24 hours ago.
Now you can probably see why I was confused and struggling to get the code working!

I’m going to post the resulting code in the next posts to make it easier to search on.

Top of page / Subscribe to new Entries (RSS)