Mastodon

Sunday, 14 February 2016

Replicating cmd.exe behaviour in PowerShell for Ping / Tracert / Telnet



Reading this blog post (https://thinkpowershell.com/2016/02/use-test-netconnection-replace-ping/) recently got me thinking (not for the first time) about using more of the new PowerShell versions of the cmd.exe commands I use so frequently.

Then and in the past the two things that stop me are 1) after so many years, running ping is almost down to muscle memory, and 2) as diverse and powerful as they might be, the PowerShell versions aren't exactly known for their brevity!

My solution... spending the afternoon knocking together some functions which I can add to my profile, which replicate the syntax and produce similar if not better results than I normally get.

Ping

The first one's simple enough really :

function ping
{
    param(
        $PingAddress
    )
    Test-NetConnection -computername $PingAddress
}

Tracert

Trace route gets a bit more complex, not least because simply adding -TraceRoute to the Test-NetConnection command only returns the resulting IP addresses, but I generally want to know what they resolve to as well. As you'll see the required command gets a bit long if you want it to resolve the PTR records as well.

For added giggles, I also added a GeoIP lookup where the address is an IPv4 address as that's often handy to know.

function tracert
{
    param(
        $TracertAddress
    )
    # Where the address is an IP, do a GeoIP lookup as well
    If ($TracertAddress -match '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$')
    {
        # GeoIP Author: Patrick Lambert - http://dendory.net
        $geoip = New-WebServiceProxy -Uri "http://www.webservicex.net/geoipservice.asmx?wsdl" -Namespace WebServiceProxy
        $geoip.GetGeoIP($TracertAddress)
    }
    # The actual tracert part
    Test-NetConnection -ComputerName $TracertAddress -TraceRoute | `
        Select -ExpandProperty TraceRoute | `
        % { Resolve-DnsName $_ -type PTR -ErrorAction SilentlyContinue }
}

Telnet

The final one is Telnet, or specifically in my case seeing what is returned when a connection to a specified port is made. Note, you can do this using Test-NetConnection as well, however it only returns whether the connection is successful. If you're checking something like the responsiveness of an SMTP server, you also want to see the banner information returned as part of the request, which is why this script is a lot longer!

function telnet
# Based on http://myitpath.blogspot.co.uk/2013/02/simple-powershell-tcp-client-for.html
{
    param(
        [parameter(mandatory=$true,position=0,helpmessage="Hostname or IP")]
      [string]$hostname,
      [parameter(position=1)]
        $PortNum
    )

    if (test-connection $hostname) {
        $conn = new-object system.net.sockets.tcpclient($hostname,$PortNum)
        $str = $conn.getstream()
        $buff = new-object system.byte[] 1024
        $enc = new-object System.Text.ASCIIEncoding
        start-sleep -m 200
        $output = ""
        while ($str.DataAvailable -and $output -notmatch "username") {
            $read = $str.read($buff,0,1024)
            $output += $enc.getstring($buff, 0, $read)
            start-sleep -m 300
        }
        $conn.close()
        $output
    } else {
        Write-Error "Unable to ping or resolve host"
        exit 1
    }
}

So by adding those three to your PowerShell $profile (see http://www.howtogeek.com/50236/customizing-your-powershell-profile/ if you're unsure how) you can add those three old style commands to your PowerShell every time it loads.

Friday, 31 July 2015

12 ways to annoy IT Support


1. Report an urgent problem just before you leave for the day. Don't provide any detailed information about the problem (who's affected, what's happening, how can it be reproduced etc). Be sure to  complain first thing the next morning that it hasn't been fixed yet. Bonus points are awarded if your Out of Office reply has been turned on before support email for more information.

2. Constantly tell the support person you're speaking to that you don't understand IT, then no matter how simply they attempt to explain something, flatly refuse to try the things they're suggesting might fix your issue.

3. When you receive an email containing an error (for instance when it's unable to deliver your message) go ahead and delete it permanently. Once it's been removed you can contact support and demand that they tell you what the error message means. Make sure you've made no attempt to remember what it said.

4. Ensure you're up to date with your email filing before calling IT regarding email issues. If you're complaining about spam volumes, ensure they’ve already been deleted, otherwise hide the message you're calling about where it can't easily be found.

5. Even though you called IT for help, feel free to assume you know more than they do. When the support person gives you step by step instructions, treat them more as suggestions. Go ahead and select divergent options or jump ahead of them, then complain about their lack of knowledge when what you see on screen isn't what they expect.

6. Call support and insist you know what the cause of your problem is. Resist any attempts to fully troubleshoot the issue, and if necessary lie or withhold information that might lead support to a different conclusion. Feel free to omit certain information if you feel it's not relevant, regardless of whether support have specifically asked for.

7. Call support and complain that "everything's slow" today. Refuse to elaborate or clarify what is slow or who is affected and insist that you're far too busy to discuss it, but do make it very clear that the issue is costing you time and money and you want it fixing.

8. When comparing prices, if you don’t understand what a certain component is or its significance (for instance the difference between Home and Pro editions) then don't worry. Ignore it and focus on comparing just those elements you do understand. Based on those few elements, complain that you can purchase the machine elsewhere for less.

9. If support email you asking for three pieces of information to allow them to troubleshoot, pick just one of those three and answer it. Resist further attempts to provide answers to the other questions.

10. When asking IT for advice to resolve a problem feel free to reject their solution. Wait a month and then complain that your problem still exists, but continue to reject the solution being offered.

11. When you get an error on your computer, make sure you've closed it before calling IT and be unable to remember the exact wording of the message. If the message comes up while on the phone, cherry pick elements of the text to give them, avoiding any error numbers or potentially useful information. If you're absolutely pushed into reading out the entire text, do so quickly and impatiently so as to prevent any form of note taking.

12. And finally... Utter the words "since you did…" or "can you just…", we love them!

Thursday, 28 May 2015

Updating the MasterServer property on all secondary DNS zones using PowerShell

I recently found myself with an interesting issue. Along with the DNS primary zones we host on our DNS servers, we also have a few customers with their own DNS servers for whom we host secondaries of their domains to provide some resiliency. One customer who has a lot of domains setup on our servers recently moved his server to a different site, and with that a different IP address, and as such the Master Servers property on every one of his secondary domains needing updating to the new IP Address.

Unfortunately while you can do many things with PowerShell, or even dnscmd for that matter, it does seem there are some limitations. Try as I might I've been unable to find a way using either system to query DNS for all secondary domains that have a specific Master Server IP address (they have 100+ domains, and that's a fraction of those we maintain, so manually checking wasn't an option!).

Fortunately I found a work around using the registry!

Windows DNS Server stores all non-AD Integrated zone data in the registry by default, and that includes settings relating to Secondary zones. By querying the registry using PowerShell you can do what I was looking for. So for instance, to simply list all domains who have a MasterServer of 1.1.1.1 you can run :

$AllTargetDomains=Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DNS Server\Zones' |
    ForEach-Object {Get-ItemProperty $_.pspath | Where-Object {$_.MasterServers -eq "1.1.1.1"}}
$AllTargetDomains.PSChildName


Note, you can also change the last line to :

$AllTargetDomains.PSChildName.Count

If you just want to know how many domains were found.

Now, to change the MasterServer property for all zones, in this case to 2.2.2.2, you run the following version. Note, the entire thing can be run as a single line of code.

Get-ChildItem 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DNS Server\Zones' |
    ForEach-Object {Get-ItemProperty $_.pspath | Where-Object {$_.MasterServers -eq "1.1.1.1"}} |
    ForEach-Object {Set-DnsServerSecondaryZone -name $_.PSChildName -MasterServers "2.2.2.2"}

   
If you re-run the earlier list version of the code you'll see no entries remaining, and if you check the domain within DNS Management you'll find that the Master Servers list has been changed.

Sunday, 13 April 2014

Adding and mounting a new disk in Linux to expand storage and house the contents of /home

So you want to add another disk to your Linux install. There could be several reasons for this, for instance running out of space on your existing setup, or wanting to split your system across multiple drives.

In my case I'd setup a new cPanel instance and wanted more capacity for the content in /home using a second disk. As such this post also explains how to move the existing /home content onto the newly added disk, such that everything continues to work like it did before.

I'll start by assuming you've added the new drive to your server, whether physically or as a new virtual disk, in your chosen hyper-visor.

Check that the system has detected the new disk by running :

    ls /dev/sd*

You'll see a list of all the physical disks detected, and the partitions on them. The first drive is /dev/sda, and if that has two partitions on it currently you'll see /dev/sda1 and /dev/sda2 listed. This increments for each drive, so a newly added second drive will be /dev/sdb.

You can check and ensure /dev/sdb has nothing on it already by running :

    fdisk -l

which will display the disk and partition details, and indicate that /dev/sdb doesn't contain a valid partition table. So lets get a partition added. Run :

    fdisk /dev/sdb

then at the prompt press n for New. You'll be asked what type of partition you want, so press p for primary. Now you'll be asked to select how much of the disk to use, these default to the first and last cylinders, so if you're using the entire disk you can simply press return on both and use the defaults. Finally at the last prompt press w to write the table to disk and exit. Note, if you quit without pressing w then nothing will be changed.

Now if you check in /dev you'll see a newly added /dev/sdb1 listed, but before we can use it we need to format it. To format it as ext3 run :

    /sbin/mkfs.ext3 -L /home /dev/sdb1

which will format the disk. The "-L /home" part of the command specifies the volume label, so if you're not using this disk for your /home folder then you might want to adjust it accordingly.

Now we want to move the existing contents of /home onto the newly formatted disk, but obviously new and old can't be /home at the same time so...

    mkdir /mnt/home
    mount /dev/sdb1 /mnt/home


to create a temporary mount point for the new drive and then mount it. Now copy the data with :

    cp -Ra /home/* /mnt/home

and then check in /mnt/home that the data is all there. Now we're finished with the temporary mount point so we can remove it with :

    umount /mnt/home
    rmdir /mnt/home


Before we can mount the new disk to its proper home we need to get rid of the existing /home folder, so let's rename it rather than delete it :

    mv /home /home-backup

which also means that if things go wrong you can switch back to the original data. Then, because we still need a folder to mount the new drive to :

    mkdir /home

To permanently mount the new disk we need to edit the fstab file, otherwise if we simply mount it then it won't reload next time the server is booted. Edit /etc/fstab and then add the following line :

    /dev/sdb1    /home    ext3    defaults    0 2

This then mounts the drive partition /dev/sdb1 to the folder /home using the ext3 file system and using the default options. The 0 relates to the archiving frequency (generally set to 0) and 2 controls the order that fsck checks for errors on the drive at boot time. You'd set that to 1 for the boot device (so not relevant here), or 2 for a subsequent drive. Many people blogging about this set it to 0 which disables checking, which I wouldn't recommend for anything other than a drive you were using short term.

Once that's saved we just need to test that it's working. You could reboot, but personally I prefer to run :

    mount -a

which will execute all of the entries listed in fstab (but do nothing where something's already mounted). If your new entry is OK then it should mount the new disk and make the contents accessible via /home, or if there's a problem then it will indicate where the issue is so you can edit /etc/fstab again to correct the issue.

So now you have a newly mounted drive, containing the same folder structure as before, but with the /home content stored on a separate drive. If you run :

    df

you'll see the newly added mount point and drive, and the disk usage / availability.

The above steps were tested on a CentOS 6.4 Hyper-V virtual machine, but should obviously work on most Linux installs.

Sunday, 30 March 2014

Migrating CentOS / cPanel from VMWare to Hyper-V

To migrate a CentOS / cPanel virtual machine from VMWare to Hyper-V there are a few steps you need to remember if you want to keep things easy.

The following steps assume you're attempting to migrate an existing CentOS installation, between host servers in the same network, eg you don't need or want to change any settings on the guest server like IP addresses etc. Simply convert, copy, import and power up.

Before shutting down the guest, it's advisable to uninstall the VMWare Tools from the server if they have been installed. While not always an issue, there are some reports of people having difficulties uninstalling it once the server has been migrated. Additionally, I'd suggest installing the Hyper-V Linux Integration Services prior to migration (current version at time of writing is 3.5 available here http://www.microsoft.com/en-gb/download/details.aspx?id=41554). This ensures when you power up the guest in Hyper-V that you don't have any issues with it recognising the network adaptor.

Linux installations hard code the MAC address of the NIC alongside the IP address details, which means if the MAC address changes (as it will by default when moving to another host), you'll find your network settings no longer work. Make a note of the current MAC address, either from the network settings in VMWare, or by looking in /etc/sysconfig/networking/devices/ifcfg-eth0.

Shutdown the server being migrated, and copy the files to the new Hyper-V server to convert them. You could convert them on the old server, but it's probably older and slower (hence you migrating) so moving them now saves time.

To convert the files I recommend using WinImage. Simply point it at the target vmdk file, tell it where to put the resulting .vhd file and its name, and it gets on with it. Note, some people report issues converting single large vmdk files (I don't know if this applies to WinImage), in which case the advise is to use VMWare Converter to split them into smaller files before the conversion. Once finished, copy the now converted .vhd file into the folder you'll create as part of the setup for the VM in the next step.

While the conversion is taking place create the new Hyper-V VM. At time of writing it will need to be a generation 1 virtual machine if you're running 2012 R2, as CentOS doesn't support generation 2 machines. Create the VM as normal, but when prompted to configure the HDD choose the option to Attach a virtual hard disk later.

Once configured, go into the Settings for the new VM. Newer versions of CentOS may be fine, but for 5.10 I found the NIC must be configured as a Legacy Network Adaptor, so remove the Network Adaptor that's there and then add a Legacy Network Adaptor instead. Within the Adaptor settings, go into the Advanced Features and statically assign the MAC address to the one you previously recorded from VMWare. Finally, select IDE Controller 0, select Hard Drive and click Add, then click Browse and find the .vhd file you converted earlier. Obviously if you have multiple drives then repeat this for each of them.

Once all this is done you can start the VM. You should find it starts successfully and works exactly the same as previously without the need to adjust anything on the server.

Tuesday, 27 August 2013

Querying DNS RecordData properties in PowerShell

Using the Get-DnsServerResourceRecord cmdlet it's simple to retrieve the records in a domain, and by combining it with Where-Object it's simple to filter by most of the properties of the zone as well. For instance :

    Get-DnsServerResourceRecord -ZoneName "mydomain.com" | Where-Object {$_.RecordType -eq "MX"}

will give you all the MX records within the mydomain.com zone. We can equally filter by HostName, DistinguishedName and a few others since they're simple string values.

What happens when we want to query a zone on RecordData? For example, how would we find all the records that point to "192.168.0.1", or MX records that are using "mydomain.com". This data isn't stored as a normal string, so it can't be queried in the same way. Using Get-Member to find the properties of Get-DnsServerResourceRecord you'll find that the RecordData property type is "CimInstance#Instance", not string like others mentioned above.

What this essentially means is that the RecordData property has properties within it, and it's these that we need query. Each type of record has its own individual properties corresponding to the type of data held within it.

Depending on the type of record you're querying there are different property names to use. To find the list use :

    $records = Get-DnsServerResourceRecord -ZoneName "mydomain.com"
    $records.RecordData | Get-Member


You'll see some have one relevant property, for instance IPv4Address, while others which hold more info have multiple, for instance MailExchange and Preference for MX records.

Note, you'll only see those values that exist within the zone you used above. So if the zone doesn't have an MX record you won't see any MX record details listed.

To query using them you add the property after RecordData, for instance :

    Get-DnsServerResourceRecord -ZoneName "mydomain.com" | Where-Object {$_.RecordData.IPv4Address -eq "192.168.0.1"}

or

    Get-DnsServerResourceRecord -ZoneName "mydomain.com" | Where-Object {$_.RecordData.MailExchange -match "mydomain.com"}

You see it's fairly straight forward to query these, it's just a question of finding them in the first place. Below is a list of the most common record types, it's not every single one possible but it should cover most situations.

A Record            IPv4Address
AAAA Record      IPv6Address
MX Record          MailExchange, Preference
CNAME Record    HostNameAlias
SRV Record        DomainName, Port, Priority, Weight
TXT Record        DescriptiveText
SOA Record       PrimaryServer, ExpireLimit, MinimumTimeToLive,   

                        RefreshInterval, ResponsiblePerson, RetryDelay, Serial Number
NS Record         NameServer
PTR Record        PtrDomainName

If you require any additional record types simply use Get-Member as listed above on a zone containing the required properties.

References:
http://ninjamonki.blogspot.co.uk/2013/02/powershell-and-dns.html
http://social.technet.microsoft.com/Forums/windowsserver/en-US/6817b151-12f3-42d5-92ae-f4f0a7e99858/querying-getdnsserversourcerecordrecorddata-ciminstanceinstance-data-in-powershell-30

Thursday, 18 July 2013

Removing a secondary zone from all DNS servers in an AD domain with PowerShell 3.0

Following on from the last blog "Adding secondary zones to all DNS servers in an AD domain with PowerShell 3.0" I'll move on to removing secondary zones from all the DNS servers in an AD domain.

Much of the code is very similar to that used when creating a new secondary, so I won't bother repeating those bits. As before you obviously need to retrieve the current list of DNS servers on the network and then work through the list.

To delete the zone itself we use the command :

    Remove-DnsServerZone -Name $domain -ComputerName $dnsserver -Force

but to add a little complication I also wanted to log the currently configured master server for the zone before deleting it. With that logged if we accidentally delete a zone it's easy to find where it pointed previously and set it up again.

Unfortunately as far as I can find there's currently no way to retrieve this info using PowerShell, so I had to resort to using the old friend of DNS scripting, dnscmd :

    $master=(dnscmd /zoneinfo $domain) -split '[,]' | ? {$_ -like '*addr=*'}
    write-output "Current master server for $domain is $master" | out-file $logfile -append


This retrieves the zoneinfo data for the domain being deleted, grabs the line containing "addr=" which lists the master servers, and then outputs that information to a log file.

You can download the completed script, which includes logging and error trapping, from http://gallery.technet.microsoft.com/Delete-a-secondary-DNS-44fce3eb.

Monday, 1 July 2013

Adding secondary zones to all DNS servers in an AD domain with PowerShell 3.0

One of the advantages of AD Integrated DNS is that adding or editing a zone on one server automatically replicates that action onto all the others, but that only works when the domain is an AD Integrated Primary. If you're dealing with secondary zones that doesn't apply, and things work like they do in a non-AD environment.

Adding a secondary zone needs to be done on each DNS server within the AD domain individually, which if you have a lot of DNS servers could be a lot of work. Add to that the more servers you're working with, the more chance of a mistake being made on one of them.

To get around this I wanted to script a way to create a secondary zone on all the DNS servers at once.

The first step is getting a list of the DNS servers on the domain. You could manually create and maintain a list of servers, but I prefer to assume things will change and get the script to allow for this. To generate a list of DNS servers I use the following :

    $dnserversldap = [ADSI]"LDAP://ou=Domain Controllers,dc=mydomain,dc=co,dc=uk"
    $objsearcher = new-object system.directoryservices.directorysearcher
    $objsearcher.searchroot = $dnserversldap
    $objsearcher.filter = "(objectcategory=computer)"
    $proplist = "name","cn","lastlogon"
    foreach ($i in $proplist){$objsearcher.PropertiesToLoad.add($i)}
    $results = $objsearcher.findall()
    $serverlist = $results.properties.cn


Note, I'm assuming in this example that all DNS servers are also AD DC's and therefore appear in the Domain Controllers OU, if that's not the case for you then you'd need to adjust it accordingly.

$serverlist now contains a list of DNS servers to work with.

From there I can simply use foreach to work through the list, and call the AddDnsServerSecondaryZone cmdlet to add the required secondary as follows :

    foreach ($dnsserver in $serverlist)
    {
        Add-DnsServerSecondaryZone -Name $domain -ZoneFile $zonefile -MasterServers $ipaddr -ComputerName $dnsserver
    }


Since I want this to be runnable at a PowerShell prompt rather than have to edit the script each time, I add the following at the beginning :

    $domain=$args[0]
    $ipaddr=$args[1]
    $zonefile=$domain + ".dns"


which reads in the domain and IP Address arguments passed to the script, and then generates the .dns filename to be used in the command (since secondary zones aren't stored in AD).

You can download the completed script, which includes logging and error trapping, from http://gallery.technet.microsoft.com/Create-secondary-DNS-zone-3793c0d8 since it also maintains the formatting.

Thursday, 20 June 2013

Adding modules into PowerShell 3.0 ISE for services running on other machines

In my last blog I talked a little about the new Commands menu within the PowerShell 3.0 ISE, the ability to view all the cmdlets relating to an individual module, and then use it to build a command.

It's a great feature and of course there are a lot of modules out there for different applications and services. As you install new roles and features that use their own set of modules the installer adds those modules into the list, so by default the PowerShell ISE modules list contains all the modules relevant to the local installation.

But what if you want to write your script and insert cmdlets into it on a machine that doesn't have those roles or features installed? You could install the relevant management pack, but that seems somewhat overkill to me.

The other option is to simply copy the relevant files from a machine that already has them.

All of the module files installed on a machine can be found in :

c:\windows\system32\WindowsPowerShell\v1.0\Modules\

with an individual folder for each module installed. These obviously get loaded when PowerShell ISE loads.

To make these available on another machine, for instance making the DNS Server module show up on your desktop machine, simply copy the relevant folder(s) (in this case DnsServer) from a server that it's installed on, into the modules folder on your target machine (your desktop).

The next time you load the PowerShell ISE you'll find the module and its list of cmdlets listed and available for use. This way on one machine you can have all your required modules, be they SQL Server, Exchange Server, Active Directory, DNS Server etc on a single machine.

Update:

Just to avoid confusion, my intention when finding this method was simply to allow me to write the code on my local machine, NOT to allow me to execute the cmdlets locally. Using the -Computer parameter to specify the machine to run the command against won't work, since your local machine is missing the required dll's. That said, if you've established a connection to the remote server, eg using Enter-PSSession, then the cmdlets generated on your local machine can be run since you're using the dll's on the remote machine not the local ones.

 

Wednesday, 19 June 2013

PowerShell v3 and new features including DNS Server cmdlets

With the introduction of PowerShell v3 in Windows Server 2012 we now have a new collection of cmdlets to play with, and amoung them are a collection of cmdlets for controlling and administering DNS Server.

As someone who's been rewriting many old batchscripts to use PowerShell, and is also in the process of migrating to a new 2012 DNS setup this obviously came as great news. No more using PowerShell as a wrapper for dnscmd or having to dig into WMI calls. Unfortunately as is often the case being up to date has its drawbacks, yep, you guessed it, there's a definite drought of documentation out there explaining how to use it all. There are other additions as well, but DNS Server's the area I've been playing with recently.

For a straight forward list of DNS cmdlets check out http://technet.microsoft.com/en-us/library/jj649850%28v=wps.620%29.aspx. Once you know which cmdlet you need the easiest option is perhaps to use the Commands menu within the PowerShell v3 ISE, which if not already displayed on the right hand side can be viewed by selecting View and then Show Command Add-on.

Using the new commands menu definitely helps, for any cmdlets you haven't used before. Selecting the DnsServer option from the modules list gives you a list of the available cmdlets in that category, and selecting one of them displays the parameter details for it. Note, where the options change depending on what you're doing (for instance using Add-DnsServerResouceRecord, where A records have different options to MX records etc), you'll see tabs along the top to allow you to select the required set of parameters. Simply fill in the required text boxes, and then click Insert, the complete PowerShell command line using those parameters will be created in the bottom window. Either run it there or copy and paste the code into your script.

If you're unsure which details need to go into which box, the -WhatIf parameter will let you know what your current selection would do if it was run (without actually doing it and potentially doing something wrong / unexpected). The WhatIf parameter isn't new to v3, but its combination and availability in the commands menu makes it even more useful. One thing worth noting about the -WhatIf parameter is that it gives an overview of what will happen, not always the exact detail. Take the following example :

Add-DnsServerResourceRecord -DomainName mail.domain.com -Name _autodiscover._tcp -Port 443 -Priority 0 -Srv -Weight 0 -ZoneName foo.com -WhatIf

The output produced will be :

What if: Adding DNS resource record _autodiscover._tcp of type SRV in zone foo.com on MYSERVER server.


You'll see that it confirms the command will create the resource record, that it's an SRV record, where it is and in which zone, but not the finer details. So if you put the port details in the wrong place then WhatIf won't help.

That's enough for now, the next couple of blogs will be looking at specific DNS Server cmdlets and how they can be used.

Wednesday, 17 April 2013

Making Windows 8 that little bit more usable



First of all, let me just say that I actually really quite like Windows 8, so don't expect this to deteriorate into a list of reasons why you shouldn't bother. I upgraded my home desktop almost as soon as I could get my mits on the upgrade, and it's been running on my work desktop for a little while now.

Once I'd got past the initial confusion everyone gets on seeing a new way of doing things, and focused instead on how I actually use my machine and the benefits available in this version, I was well and truly a convert. Yes TIFKAM (The Interface Formerly Known As Metro) jars a little at first, no I really don't like it, however and this is the important point, I hardly ever use it! Since Windows 7* introduced pinning your apps to the task bar I've generally had all my regularly used apps pinned, so I rarely needed to click start for anything other than shutting down. So if I didn't use the Start menu in 7, I probably won't use TIFKAM in 8, so it doesn't matter what it looks like!

All that said, there are a number of little tips and tricks I've discovered to resolve some of the little annoyances, and make Windows 8 far better (in my opinion) than it is out of the box. I figured I'd write about them here, if they help someone else then great, if not I've got a handy crib sheet if I need to set things up again in the future.**


  • For quick access to the desktop when starting Windows, drag the "Desktop" tile on the start menu to the top left hand corner. This then becomes the default tile and is already selected. When you login to Windows and are presented with the Start menu, simply hit return and you'll be at the desktop.
  • To start your applications without needing to use the Start menu the simplest way it to pin them to your task bar. Once they're running, simply right click the taskbar icon, and you'll see an option to "Pin this program to the taskbar". When the app is closed the icon remains without the box surrounding it, making it easy to start next time. You can also re-order them by dragging and dropping them into the order you prefer.
  • If you can't find an app, either type its name in the Start menu to search for it, or (and this isn't always obvious), right click in some empty space and you'll see an option for "All apps" which will being up a complete list of them.
  • Accessing the Shutdown/Restart menu can be done in multiple ways, moving the mouse to the bottom right and selecting settings, pressing Windows-C to access the Charms menu, or Windows-I to go direct to the Setting Charm, but if nothing is open or no applications are selected (eg you clicked on the desktop / taskbar) you can press ALT-F4 to go direct to the menu.
  • If you like having easy access to My Computer, documents, the Control Panel etc, you can get a measure of this functionality back via a taskbar toolbar. Right click on the taskbar, go to Toolbars and select Desktop. You'll now see on the right hand end of the task bar a new entry title "Desktop >>", clicking on the >>'s gives you access to many of those things you previously had through the start menu.
  • And finally, if / when you accidentally open something in Metro mode (it loads full screen, and the taskbar etc is no longer visible) it's simple enough to get back to the desktop, however you'll notice a lack of familiar x to close the application. In Metro mode, move the mouse to the top middle of the screen and the mouse changes to a hand icon, click and drag down until the application is gone (effectively dragging the application off your desktop).

Next post will be some of the useful changes you can make in Office 2013.

* It may have started in Vista, but I never used it and prefer to think of it as a beta version of Windows 7!

** Note, there are various add-ons and start bar replacements out there but I haven't touched them. I spend enough time supporting other peoples machines that I don't want mine moving too far from the default.