Thursday 28 February 2008

My First PowerShell Script - delete files which haven't been accessed in 30 days

I thought I'd start with something simple.
I have a Scratch folder on my Windows desktop where I tend to chuck things I only need for a short while - like if someone sends me a file they're having problems with and they want me to figure out what's wrong with it.
Every now and again I notice my Scrach folder is getting cluttered with stuff I don't need, and at that point I sort it by Last Access Date and delete everything I haven't looked at for a month or so.
I'm no good at learning scripting from a book, every scripting and macro language so far I've learnt through necessity - I had a job that needed doing and I didn't know any other way to do it, so I taught myself. I've been waiting for an opportunity to try to get to grips with PowerShell and I thought this would be a great project to start with.
Note that there's no safety net here - running this script deletes all files and subfolders that meet its criteria and once they're gone they're gone! As there's every chance I've made an error here or this may behave differently when you run it, see my disclaimer before you even think about running it!
$userprofile=$env:UserProfile
set-location "$userprofile\desktop\Scratch"
$d=[DateTime]::Now.AddDays(-30)
Get-childitem -recurse | where-object {$_.lastaccesstime -lt $d} | remove-item -recurse -force
Get-ChildItem -recurse | where-object {$_.psiscontainer -and ($_.getfiles().length -eq 0)} | Remove-Item –recurse -force
Notes for those even less PowerShelly than me:
AddDays(-30) subtracts 30 days. (There isn't a separate SubtractDays method.)
The first Get-Childitem line finds all the files and subfolders that haven't been accessed for 30 days and deletes them.
The next Get-ChildItem line finds all the empty subfolders (getfiles().length will be 0 if there are no files in the subfolder) and deletes them. (This took me a while to figure out but I was pretty pleased when I managed it - I'd been looking around couldn't find any examples of a one-liner to delete empty folders.)
Update 29-Feb: For reasons unknown the formatting of the above script had all gone strange when I came back to it today. Hopefully it looks good now.

Wednesday 27 February 2008

And we wonder why Vista costs twice as much here...

VBA Script to create many calendar appointments in Outlook

A while back I was asked to create a few thousand Calendar appointments to help with some testing. I figured the script might be useful in case anyone ever has to do a similar task. I wrote it in Outlook 2003 and for me it works as intended, but it was meant to be quick and cheap (the script was only needed once so I gave it minimal testing and I've included no error handling at all) so you should see my disclaimer before you even think about using it!

Note that I put the items in a Calendar in a PST. This is because I needed to be able to easily share what I'd created, and also because I created the script on my live system (so if I'd written a few thousand Calendar items to the Exchange server I might not have been terribly popular if it had caused problems for other users).

The CreateLotsOfApptsInPST needs to be called with the following parameters:

PSTName - the name of the PST; this is the name it shows with in your folder tree (e.g. "Personal Folders") and not the file path. The PST has to be loaded. I didn't test what happens if there's more than one PST loaded with the same name.
Occurences - How many appointments you want to create
Start - The date and time of the first appointment you want to create
Interval - How far apart, in minutes, you want the start times of each appointment, e.g. if you make the Duration 45 mins and the Interval 60 mins, there will be a 15 mins gap between each appointment.
Duration - The duration of each appointment in minutes.
Subject - The subject you want for each appointment. As it is, the script will append a sequential number to each ("Test Appt 1", "Test Appt 2" etc.) but you could easily amend that.

The second sub is called by the first, but you should be able to see what it's doing.

Sub CreateLotsOfApptsInPST(PSTName As String, Occurrences As Long, _
 
Start As Date, Interval As Integer, Duration As Integer, _
  Subject As String)

Dim count As Integer

For count = 1 To Occurrences
    CreateApptInPST PSTName, Subject & " " & count, _
      Start + ((count - 1) * (Interval * (1 / 24 / 60))), Duration
Next count

End Sub

Sub CreateApptInPST(PSTName As String, Subject As String, _
  DateTime As Date, Duration As Integer)

Dim olApp As Outlook.Application, objName As NameSpace
Dim PST As MAPIFolder, PSTcal As MAPIFolder

Set olApp = Outlook.Application
Set objName = olApp.GetNamespace("MAPI")
Set PST = objName.Folders(PSTName)
Set PSTcal = PST.Folders("Calendar")

Dim i As AppointmentItem
Set i = PSTcal.Items.Add
i.Subject = Subject
i.Start = DateTime
i.Duration = Duration
i.Save

End Sub

More seasoned coders will give me zero points for style, but it did the job for me!

Tuesday 19 February 2008

WHS, Vista, Startup Profiles and Task Scheduler

...well sort of anyway. This is going to be a bit of a rambling post but if you aren't already using Vista's Task Scheduler as a kind of startup profile manager then you might need to read on...

I've had a Windows Home Server set up since the days of the beta programme, and I have to say I'm pretty happy with it. One of its most important jobs is to back up my laptop, so naturally the laptop has the WHS connector (client software) installed. My laptop, however, gets used outside of my home. If I'm at a friend's house I might connect to their wireless network, I may use a 3G card or wireless hotspot when I'm out and about, or I might work offline. Any of which leave the WHS connector doing nothing useful.

My laptop is a lovely lightweight skinny little thing. The downside of that is it doesn't run too quickly. I also have the power-saving options set to get the most time out of a single charge which slows things down even further. It's mostly bearable once it's up and running, but the startup time and the time to recover from hibernation were pretty unacceptable.

The thing that bothered me most was waiting for apps that ran on startup that required the network. If I was off the network (or on a different network to the thing that app wanted to connect to - which is why WHS is in the title of this post) I'd be sitting waiting not only for the damn things to load, but to figure out they couldn't contact the server they wanted to, in some cases complain about it (I KNOW!), then sit there using CPU and memory anyway. Irritating in the extreme when I need to get to some file on my laptop in a hurry. I considered downloading a startup profile manager utility, but couldn't find anything that quite met my needs. On my old XP laptop I made do with a script to start and stop various services depending on where I was, but that was far from perfect.

Anyway, today I finally got so fed up with all the OEM crap taking forever to start on my Vista laptop that I took some time out to fix things. (Shame on you Sony, nobody needs all this junk to run all the time.) In the process I found out that under Vista more and more Startup apps have been added to the Task Scheduler instead of the Run keys in the registry or our old friend the Startup group. I should probably be ashamed to admit I only found that out today, but hey... I got there in the end. But this was where my revelation occurred - I already kind of knew that Task Scheduler was a lot more sophisticated than old-style Scheduled Tasks, but it hadn't really occurred to me how I could use it at home to make my life easier.

The long and the short of it is that I'm now using Scheduled Tasks as a kind of Startup Profile Manager. The WHS Connector has come out of the Startup group and now runs as a Task to run on startup with a condition that it only runs if I'm connected to my home network. My two apps for downloading TV content only run if I'm connected to a network and only if I'm plugged in to mains power and idle for 2 minutes first. I killed some of the OEM ballast and now have things like driver update checks run once a month rather than every time I start up.

My startup time is now pretty reasonable for a slow little machine, and it's improved my temper no end. And all thanks to Task Scheduler.

Thursday 7 February 2008

How item count in Outlook folders affects performance

Where I work we see a lot of Outlook performance issues where the user's Inbox is over 10,000 items. (I think the record was about 150,000 - you can probably guess we don't use email quotas!)

Anyway this article covers some of the reasons a huge number of items in any folder will cause poor performance:

KB905803: Outlook users experience poor performance when they work with a folder that contains many items on a server that is running Exchange Server

In particular the paragraph about how recurring items are populated into the Calendar was something that had never even occurred to me before.

The one thing it doesn't touch on is how Cached Exchange Mode affects the performance. Our experience is that accessing larger mailboxes from desktop or laptop machines with slow hard disks (think not just older machines, but laptops running on battery power), Cached Exchange Mode can slow things down considerably. It's working out of the OST file (the cached copy of your mailbox on your hard disk), so if your hard disk is slow and your folders have many items, building the indexes required each time you switch views or folders will take some time.

I am generally a fan of Cached Exchange Mode (just for starters it can sheild the Exchange server from so much traffic things like Google Desktop can generate) but there are times it requires a little thought. So if your big cheese needs to keep his huge amount of mail and doesn't want his Outlook running like a dog, he's gonna need to fork out for a half-decent machine for his desk. And even then his frequently used folders should ideally stay below 5000 items.

Creative Commons License This work by TechieBird is licensed under a Creative Commons Attribution-No Derivative Works 2.0 UK: England & Wales License.