Prerequisites for this upgrade/migration are that the SBS 2003 server must be at SP2, with Exchange 2003 also at SP2. In addition to this both your domain functional level AND forest functional level must be running at 2003 native (This is the highest available on SBS 2003 SP2). Finally, your Exchange organisation must be running in 2003 native mode.

The first steps involved are upgrading the Active Directory schemas, for this you’ll need to put the Windows 2008 R2 DVD into your 2003 SBS server, open a command prompt and run the following commands:

X:\support\adprep\adprep32.exe /forestprep
X:\support\adprep\adprep32.exe /domainprep
X:\support\adprep\adprep32.exe /domainprep /gpprep

Obviously replacing X with your DVD drive, or it could be a network share etc. In previous versions of Windows Server, you would have to use the correct media to match the architecture of your SBS 2003 server, as of Windows server 2008 R2, x86 is no longer supported, hence the adprep32.exe instead of adprep.exe!

At this point you can fire up the new (x64!) hardware that you’re going to use to run Exchange 2010. Install Windows 2008 R2 onto here, give it a static IP, a name, all the patches and updates it wants, service packs, also do a full IIS install from the server manager page, it’s probably also a good idea enabling remote desktop at this stage! We’ll need a small selection of remote server amdin tools for during the Exchange installation, so run the following command to install them:

ServerCmd -i RSAT-ADDS

We can now go ahead and join the new server onto the domain, once you’ve done this reboot as requested. When the system has come back up, put in the Exchnage 2010 DVD, and fire up a command prompt and run the following command:

X:\Setup.com /PrepareAd

These will prepare Active Directory and your Exchange organisation for the new Exchange server while still allowing for compatibility with Exchange 2003 SP2. If you get any errors here, it might be worth double checking the functional level of your exchange organisation, as mentioned in the prerequisites. Hopefully you haven’t encountered any errors, so can run the main Exchange 2010 setup from the DVD. Select the languages you want to install, and then proceed through the setup. You’ll need to select the current Exchange 2003 server in the mail flow configuration screen, so that mail can route between both Exchange servers during the migration.

The Exchange 2010 setup will then perform some readiness checks, if any of these fail, do what needs to be done, then click retry! Exchange 2010 should then install the relevant roles onto the system.
Once the Exchange setup has completed, it’s probably a good idea to install any updates. While they are installing, have a look on the SBS server, you should now see two administrative groups in the Exchange system manager.

Add a SMTP send connector as required on the 2010 server (Org config > Hub transport > Connector > SMTP), also allow inbound anonymous SMTP connections (Org config > Hub transport > Default > Permissions).

I’d also advise moving the location of the mailbox database and public store databases, as they are on the system drive by default, it’s a good idea to keep logs and databases on separate RAID volumes. You can move them under Org config > mailbox > databases.

I choose to move public folders first, as this can take a long time, so we keep user mailboxes where they are for now. To move the public folders, use the Exchange management on the 2003 server, right click the public folder store, and select move all replicas – take note of the message and what it says – it will take a long time, and it is only complete once the instance store folder is empty as it says. You can check things are moving by using message tracking in the Exchange 2010 powershell. One you are sure this has completed, you can delete the old public folder store in exchange 2003, select the new public folder store when you are asked where to move the existing bits and bobs to, once this has been done, it’s advisable to unmount then remount the public folders database using the exchange 2010 manager.

The final set with regard to the public folders, is to create a new container on the 2010 server, by right clicking on the 2010 exchange group, then selecting new public folder container, once this has been created, simply drag the public folders from the 2003 group into the 2010 folders group.

Now onto moving user mailboxes, easiest way is by using the Exchange 2010 management console, under server > recipient config > mailboxes > new local move. Follow the wizard to move everything over.
Before we are ready to decommission the old 2003 server, we just need to move the offline address book over, this is under Org config > mailbox > offline address book, right click it, select move and use the wizard. We then need to assign an offline address book to our mailbox database – right click it under Org config > mailbox > properties > client, and pick the offline folder.

We can now delete the 2003 mailbox store, say ok to the warnings, then delete both routing group connectors between the two servers. Using 2003 manager, change the recipient policies, so they only have email addresses – not mailbox manager. Finally we need to delete recipient update services for the domain, then the enterprise – although the latter will need doing via ADSIEdit.msc!
Finally, using add remove programs, change the SBS installation so that it doesn’t include Exchange.

At this point, our 2003 Exchange server is decommissioned, and we’ve now running on the new 2010 version.

WPKG – Setup did not finish as expected

February 12th, 2010 by Geoff Kendal No Comments

While trying to deploy the WPKG client onto newly built systems, I kept encountering the following error:

“There is a problem with
this Windows Installer Package. A program run as part of the setup did
not finish as expected. Contagt your support personnel or package
vendor.”

I was trying to install using the MSI with a specified settings.xml file using the following command:

msiexec /qb! /i wpkgclient1-3-6.msi SETTINGSFILE=\\server\wpkg\settings.xml

Looking at the windows installer logs, it appeared that the problem was with the settings file, after checking it was valid XML, I found out that if full paths with drive letters were specified (Z:\settings.xml) it installed fine!

Odd.

Windows SIM unable to generate catalog

February 10th, 2010 by Geoff Kendal No Comments

When using Windows SIM (System Image Manager), which is part of the Windows AIK (Automated Installation Kit) you might run inthe the the following error when you try and load a .WIM image…

“Windows sim was unable to generate a catalog”

Chances are that you are trying to open a .WIM image from the $RemoteInstall share. In this folder structure the WIM’s are slightly different as they incorporate metadata and a .RWM that contains the image data. The easy way around this is to fire up the Windows Deployment Services MMC, then find the image, right click and export to somewhere else. You should then be able to create a catalog using the newly exported .WIM.

I have been looking at getting a script together for a while to mass change some shortcuts we have on our file server to point to a different location. After some research, and some playing around I found a really easy way to do this in Powershell:


# Call wscript com object
$shell = new-object -com wscript.shell

# Recurse through directories for .lnk files
dir "I:\" -filter *.lnk -recurse | foreach {
$lnk = $shell.createShortcut($_.fullname)
$oldPath= $lnk.targetPath

# If match text, perform operation
if($oldpath -match "\\serverold\share1")
{
write-host "Match: " + $_.fullname
remove-item $_.fullname
$lnknew = $shell.createShortcut($_.fullname)
$lnknew.targetPath = "`"\\newserver\share1`""
$lnknew.IconLocation = "%SystemRoot%\system32\SHELL32.dll,4"
$lnknew.Save()
}
}
Write-Host "End..."

Problems with deleting files

January 22nd, 2010 by Geoff Kendal No Comments

I came accross some directories today on our NAS that couldn’t be deleted – I really needed to get rid of them as they were causing backups to fail! Every time I tried to delete, I got the following windows error:

“cannot delete file: cannot read from source or disk”

The solution to this, was to fire up a command prompt, and locate the directory in question (Map a network drive if it’s a UNC path!), then run:

dir /x /a

This should give you the directory name, along with its shortname (e.g. AEU8P3~P). You can then either delete the folder (rd /?) or rename it (ren /?) by using the shortname!

Setting up a free Windows SVN Server

October 23rd, 2009 by Rob Milner No Comments

If you want to setup a Windows SVN server, it’s easy as pie!  I set one up for the company I work for as the Linux SVN Server was getting too difficult to manage.  I would highly recommend using the free version of VisualSVN server for Windows for your code repository: VisualSVN Server.

It’s a ~4MB msi installer, and it’s a doddle to add new repositories and manage them.  There is also an Enterprise version of the software should you need any extra features but we have found that the free one does everything we need and more.

Once you have installed the VisualSVN Server, download and install Tortoise SVN onto your computer: Tortoise Download.

You can then use Tortoise to update and commit code to your repository!

CaptureAnother of my little Windows 7 deployment annoyances has been the fact that windows media player is pinned to the new taskbar by default, and with windows 7, it’s not possible to programmatically add or remove pinned items from the taskbar.

After a while of script hunting for something that might get around this, I found out that there is an option that can be used in the unattended xml file will stop it from being automatically added!

 

 

In windows system image manager, add the following under phase 7 (OOBE):

   Windows shell setup >> Windows Features >> ShowWindowsMediaPlayer >> false

Using get and set methods with C#

October 2nd, 2009 by Rob Milner No Comments

I’ve always wondered when looking at C# what get and set methods are used for.  In basic terms I found that the get and set method was mainly for reading (get) or writing (set) a property.  After scratching my head for some time, I tried to give it a go as I have problems setting a string to a particular value within one of my C# projects.

I setup another class within my project called “tgtNotes”, which would contain my get and set:

class tgtNotesJK
{
   private string LocNotes = null;
   public string NotesLoc
{
   get
   {
     return LocNotes;
   }
   set
   {
     LocNotes = value;
   }
}

I then thought, “surely it’s not that easy”!  I then went back to the code on the form, and defined the class within the code for button1:

tgtNotesJK notestgt = new tgtNotesJK();

Getting and setting is really easy.  To set a value:

notesgt.NotesLoc = "Some text";

And to get the value for example:

Console.WriteLine(notesgt.NotesLoc);

Another great benefit of this is that you will be able to access the methods from anywhere within the C# project.  So because I ’setted’ a value within button1, will mean for example that I can still access the value within other parts (for example button2).

Windows 7 point and print restrictions

September 3rd, 2009 by Geoff Kendal No Comments

I’m currently looking into deploying Windows 7 in our environment, and was having a bit of an issue with printers… When our (non-admin) users log on, our logon script detects the client location and connects the appropriate printers, I don’t want any warnings to be shown or UAC prompts, but just want the drivers to be automatically downloaded and printers added.

On vista, you could disable any prompts, by disabling the “point and print restirctions” group policy object in the user configuration, or enable it and specify certain trusted servers, unfortunatly this didn’t seem to do the trick on Windows 7 RTM. After a bit of playing, I found out that on Windows 7, you need to apply the policy to both computer and user configuration!

From time to time our Citrix users end up with multiple sessions on our Citrix farm, especially when accessing the farm via Citrix access gateway and they loose connectivity. Most of these are fixed by setting sessions in the disconnected state to be automatically reset after 15 mins. (We allow this time  incase users are moving to a meeting room for example).

The big problem for us is that you can’t run multiple instances of Lotus Notes, so the disconnected session needs to be reset before the user can fire up Lotus Notes again, otherwise they will see an error like:

“You cannot use the Administration program while the Domino Server is running. Either shut down the Domino Server (buy keep the file server running) or choose the icon labeled ‘Lotus Notes’ instead.”

In order to try and make things a bit easier on the helpdesk, I created a script that will allow users to reset their own Citrix sessions. If you want to use it you’ll need to populate the first array with a list of all the servers in your farm, then create a shortcut:

cscript /nologo citrixreset.vbs

I’ve set mine to run minimized so that they don’t see random command windows popping up.

It should also be noted, that the script resets any disconnected sessions first, so that it can still carry on and kill the active one at the end! I know it’s not the slickest of scripts (Lots of splitting arrays and capturing command output), but I couldnt find any nice objects to do it properly with!

 citrixServers = array("CXS38", "CXS39", "CXS40", "CXS41")

Set objShell = CreateObject("WScript.Shell")

Sub resetSession(s)
    count = count + 1
    sessionID = trim(mid(s,48,5))
    citrixServer = trim(mid(s,1,6))
    wscript.echo "RESET SESSION " & sessionID & " /SERVER:" & citrixServer
    Set oExec = objShell.Exec("RESET SESSION " & sessionID & " /SERVER:" & citrixServer)
End Sub

userName = objShell.ExpandEnvironmentStrings("%UserName%")

For Each citrixServer In citrixServers

    wscript.echo "QUERY SESSION " & userName & " /SERVER:" & citrixServer
    Set oExec = objShell.Exec("QUERY SESSION " & userName & " /SERVER:" & citrixServer)

    Do While oExec.Status = 0
        WScript.Sleep 100
    Loop

    Do While oExec.StdOut.AtEndOfStream <> True
        sessionOutput = sessionOutput & vbCrLf & citrixServer & oExec.StdOut.ReadLine
    Loop

Next

count = 0
sessions = split(sessionOutput, vbCrLf)
wscript.echo

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Disc") then wscript.echo session
Next

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Active") then wscript.echo session
Next

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Disc") then resetSession(session)
Next

For Each session In sessions
    if InStr(session, "wdica") and InStr(session, "Active") then resetSession(session)
Next

msgbox "Reset " & count & " Citrix session(s) for " & userName