Monday, 8 February 2016

I've had a requirement to audit a whole site, where no knowledge of the devices are on there.  This is a combination of scripts taken from:
https://gallery.technet.microsoft.com/scriptcenter/Invoke-TSPingSweep-b71f1b9b
and http://www.truesec.com

The only information I have is the gateways on each site should be at IP x.y.z.1, but also might be at x.y.z.17.  These gateways should reply to a ping.  The ranges are all 10.x.y.z with a mask of 255.255.255.0

The scripts on these sites originally took parameters, I've butchered this script to have hard coded settings.  It looks for the first 18 addresses (line 132).  If there is no reply to a ping by then, assume the range is dead.

If it finds a valid ping reply, the full range is port scanned for the list of ports I'm interested in at line 66.

Once its done, a CSV is produced.  That will be read into SQL so I can lookup which IPs have which ports open on them.  I can infer what types of machines I can see then, e.g.
Port 9100 would be a printer,
443 and 902 might be an ESXi host,
8080, 443 and 21 may be a QNAP


cls


#https://gallery.technet.microsoft.com/scriptcenter/Invoke-TSPingSweep-b71f1b9b
function Invoke-TSPingSweep {
  <#
    .SYNOPSIS
    Scan IP-Addresses, Ports and HostNames

    .DESCRIPTION
    Scan for IP-Addresses, HostNames and open Ports in your Network.
   
    .PARAMETER StartAddress
    StartAddress Range

    .PARAMETER EndAddress
    EndAddress Range

    .PARAMETER ResolveHost
    Resolve HostName

    .PARAMETER ScanPort
    Perform a PortScan

    .PARAMETER Ports
    Ports That should be scanned, default values are: 21,22,23,53,69,71,80,98,110,139,111,
    389,443,445,1080,1433,2001,2049,3001,3128,5222,6667,6868,7777,7878,8080,1521,3306,3389,
    5801,5900,5555,5901

    .PARAMETER TimeOut
    Time (in MilliSeconds) before TimeOut, Default set to 100

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost -ScanPort

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost -ScanPort -TimeOut 500

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.10.254 -ResolveHost -ScanPort -Port 80

    .LINK
    http://www.truesec.com

    .NOTES
    Goude 2012, TrueSec
  #>
  Param(
    [parameter(Mandatory = $true,
      Position = 0)]
    [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
    [string]$StartAddress,
    [parameter(Mandatory = $true,
      Position = 1)]
    [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
    [string]$EndAddress,
    [switch]$ResolveHost,
    [switch]$ScanPort,
    [int[]]$Ports = @(21,22,23,25,53,69,80,110,123,139,389,443,445,636,901,902,1433,3260,3306,3389,4333,5800,5900,8080,9100),
    [int]$TimeOut = 100
  )
  Begin {
    $ping = New-Object System.Net.Networkinformation.Ping
  }
  Process {
    foreach($a in ($StartAddress.Split(".")[0]..$EndAddress.Split(".")[0])) {
      foreach($b in ($StartAddress.Split(".")[1]..$EndAddress.Split(".")[1])) {
        foreach($c in ($StartAddress.Split(".")[2]..$EndAddress.Split(".")[2])) {
          foreach($d in ($StartAddress.Split(".")[3]..$EndAddress.Split(".")[3])) {
            write-progress -activity PingSweep -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100)
            $pingStatus = $ping.Send("$a.$b.$c.$d",$TimeOut)
            if($pingStatus.Status -eq "Success") {
              if($ResolveHost) {
                write-progress -activity ResolveHost -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100) -Id 1
                $getHostEntry = [Net.DNS]::BeginGetHostEntry($pingStatus.Address, $null, $null)
              }
              if($ScanPort) {
                $openPorts = @()
                for($i = 1; $i -le $ports.Count;$i++) {
                  $port = $Ports[($i-1)]
                  write-progress -activity PortScan -status "$a.$b.$c.$d" -percentcomplete (($i/($Ports.Count)) * 100) -Id 2
                  $client = New-Object System.Net.Sockets.TcpClient
                  $beginConnect = $client.BeginConnect($pingStatus.Address,$port,$null,$null)
                  if($client.Connected) {
                    $openPorts += $port
                  } else {
                    # Wait
                    Start-Sleep -Milli $TimeOut
                    if($client.Connected) {
                      $openPorts += $port
                    }
                  }
                  $client.Close()
                }
              }
              if($ResolveHost) {
                $hostName = ([Net.DNS]::EndGetHostEntry([IAsyncResult]$getHostEntry)).HostName
              }
              # Return Object
              New-Object PSObject -Property @{
                IPAddress = "$a.$b.$c.$d";
                HostName = $hostName;
                Ports = $openPorts
              } | Select-Object IPAddress, HostName, Ports
            }
          }
        }
      }
    }
  }
  End {
  }
}

# Variables don't change
[int16] $x = 0
[int16] $y = 0


# varialbles change
[string] $outputFile = "C:\scripts\scanEntireNetwork\output.csv"
[string] $startingIP = "10.x.y.z"
$startingOctave = 0  # If the IP range starts at zero, change this to 0
$endingOctave = 255  # If you want to only go through half a range (why?), limit this upper value
$rangeCheck = 18 # How many ips to check at the start of the range before the range is skipped
[int16] $xStart = $startingOctave
[int16] $yStart = $startingOctave
[int16] $zStart = $startingOctave




#if (Test-Path $outputFile)
#{
#    Remove-Item $outputFile -Force
#}

for ($x = $xStart; $x -le $endingOctave; $x++)
{
    for ($y = $yStart; $y -le $endingOctave; $y++)
    {
        #$ActiveMachinesAndPorts.Clear()
        $startIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$startingOctave)
        $endIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$endingOctave)
        $endCheckIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$rangeCheck)
        $startIP

        #Check the first 5 addresses for a ping reply
        $quickCheck = Invoke-TSPingSweep -startAddress $startIP -EndAddress $endCheckIP
        if ($quickCheck)
        {
            #If it finds one, check the numbered ports in the entire range
            $ActiveMachinesAndPorts = Invoke-TSPingSweep -startAddress $startIP -EndAddress $endIP -ScanPort

            #Turn the Object into a String
            foreach ($singleMachine in $ActiveMachinesAndPorts)
            {
                $singleMachine.Ports = $singleMachine.Ports -join ","
                #$ActiveMachinesAndPorts.Ports = $ActiveMachinesAndPorts.Ports -join ","
            }

            #Write the data to a CSV
            $ActiveMachinesAndPorts | Export-Csv $outputFile -Append
        }
    }
}

Sunday, 7 June 2015

Code to go through all the IPs in a range.  The though here is it checks the first 5 addresses for a ping reply.  If there isn't a reply I'm assuming the range is dead.

Not sure what is going on with the colours below.  This link goes to the source code




cls


#https://gallery.technet.microsoft.com/scriptcenter/Invoke-TSPingSweep-b71f1b9b
function Invoke-TSPingSweep {
  <#
    .SYNOPSIS
    Scan IP-Addresses, Ports and HostNames

    .DESCRIPTION
    Scan for IP-Addresses, HostNames and open Ports in your Network.
    
    .PARAMETER StartAddress
    StartAddress Range

    .PARAMETER EndAddress
    EndAddress Range

    .PARAMETER ResolveHost
    Resolve HostName

    .PARAMETER ScanPort
    Perform a PortScan

    .PARAMETER Ports
    Ports That should be scanned, default values are: 21,22,23,53,69,71,80,98,110,139,111,
    389,443,445,1080,1433,2001,2049,3001,3128,5222,6667,6868,7777,7878,8080,1521,3306,3389,
    5801,5900,5555,5901

    .PARAMETER TimeOut
    Time (in MilliSeconds) before TimeOut, Default set to 100

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost -ScanPort

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.0.254 -ResolveHost -ScanPort -TimeOut 500

    .EXAMPLE
    Invoke-TSPingSweep -StartAddress 192.168.0.1 -EndAddress 192.168.10.254 -ResolveHost -ScanPort -Port 80

    .LINK
    http://www.truesec.com

    .NOTES
    Goude 2012, TrueSec
  #>
  Param(
    [parameter(Mandatory = $true,
      Position = 0)]
    [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
    [string]$StartAddress,
    [parameter(Mandatory = $true,
      Position = 1)]
    [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")]
    [string]$EndAddress,
    [switch]$ResolveHost,
    [switch]$ScanPort,
    [int[]]$Ports = @(21,22,23,25,53,69,80,110,123,139,389,443,445,636,901,902,1433,3260,3306,3389,4333,5800,5900,8080,9100),
    [int]$TimeOut = 100
  )
  Begin {
    $ping = New-Object System.Net.Networkinformation.Ping
  }
  Process {
    foreach($a in ($StartAddress.Split(".")[0]..$EndAddress.Split(".")[0])) {
      foreach($b in ($StartAddress.Split(".")[1]..$EndAddress.Split(".")[1])) {
        foreach($c in ($StartAddress.Split(".")[2]..$EndAddress.Split(".")[2])) {
          foreach($d in ($StartAddress.Split(".")[3]..$EndAddress.Split(".")[3])) {
            write-progress -activity PingSweep -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100)
            $pingStatus = $ping.Send("$a.$b.$c.$d",$TimeOut)
            if($pingStatus.Status -eq "Success") {
              if($ResolveHost) {
                write-progress -activity ResolveHost -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100) -Id 1
                $getHostEntry = [Net.DNS]::BeginGetHostEntry($pingStatus.Address, $null, $null)
              }
              if($ScanPort) {
                $openPorts = @()
                for($i = 1; $i -le $ports.Count;$i++) {
                  $port = $Ports[($i-1)]
                  write-progress -activity PortScan -status "$a.$b.$c.$d" -percentcomplete (($i/($Ports.Count)) * 100) -Id 2
                  $client = New-Object System.Net.Sockets.TcpClient
                  $beginConnect = $client.BeginConnect($pingStatus.Address,$port,$null,$null)
                  if($client.Connected) {
                    $openPorts += $port
                  } else {
                    # Wait
                    Start-Sleep -Milli $TimeOut
                    if($client.Connected) {
                      $openPorts += $port
                    }
                  }
                  $client.Close()
                }
              }
              if($ResolveHost) {
                $hostName = ([Net.DNS]::EndGetHostEntry([IAsyncResult]$getHostEntry)).HostName
              }
              # Return Object
              New-Object PSObject -Property @{
                IPAddress = "$a.$b.$c.$d";
                HostName = $hostName;
                Ports = $openPorts
              } | Select-Object IPAddress, HostName, Ports
            }
          }
        }
      }
    }
  }
  End {
  }
}

# Variables don't change
[int16] $x = 0
[int16] $y = 0


# varialbles change
[string] $outputFile = "c:\temp\output.csv"
[string] $startingIP = "192.x.y.z"
$startingOctave = 1  # If the IP range starts at zero, change this to 0
$endingOctave = 254  # If you want to only go through half a range (why?), limit this upper value
$rangeCheck = 5 # How many ips to check at the start of the range before the range is skipped
[int16] $xStart = 168
[int16] $yStart = 20
[int16] $zStart = $startingOctave




if (Test-Path $outputFile)
{
    Remove-Item $outputFile -Force
}

for ($x = $xStart; $x -le $endingOctave; $x++)
{
    for ($y = $yStart; $y -le $endingOctave; $y++)
    {
        #$ActiveMachinesAndPorts.Clear()
        $startIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$startingOctave)
        $endIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z","5")
        $endCheckIP = $startingIP.Replace("x",$x).Replace("y",$y).Replace("z",$rangeCheck)
        $startIP

        #Check the first 5 addresses for a ping reply
        $quickCheck = Invoke-TSPingSweep -startAddress $startIP -EndAddress $endCheckIP
        if ($quickCheck)
        {
            #If it finds one, check the numbered ports in the entire range
            $ActiveMachinesAndPorts = Invoke-TSPingSweep -startAddress $startIP -EndAddress $endIP -ScanPort

            #Turn the Object into a String
            $ActiveMachinesAndPorts.Ports = $ActiveMachinesAndPorts.Ports -join ","

            #Write the data to a CSV
            $ActiveMachinesAndPorts | Export-Csv $outputFile -Append
        }
    }
}

Tuesday, 23 September 2014

Windows 2012 randomly dropping off the network while running VMWare 5.5


For the last few days while running a Windows 2012 R2 x64 server which was originally built on VMWare 5.1.x,, but moved to a 5.5.0, this servers network card appears to be dropping out and all network traffic stops altogether.


Restarting services wasn't good enough to start the network again, only a complete machine shutdown and restart worked.  This made some of the interested parties quite irate.  And me.

There were a number of thoughts that crossed my mind - recent firmware patch, physical network switches, SAN connectivity, VM (virtual) Hardware, Windows OS, Windows software.  Each were ruled out until VM hardware was left.

Digging through the VM Properties, I'd spotted some settings that I'd disregarded before.
Guest Operating System and Network adapter type.

Guest OS was set to Windows 2008 R2 x64 as there seemed to be a bug in 5.1 for us where the Virtual machine wouldn't even start up to install the OS if W2012x64 was chosen at machine build, but downgrading to W2008R2x64 worked.  Doing that however defaulted the network adapter to be E1000.  The default Adapter for W2012x64 is E1000E.



At the next network halt several steps were made.
1. Removed the Server from the Inventory (***REMOVE NOT DELETE!!!!***)
2. Created the new VM and chose the OS to be W2012x64
3. Moved the virtual hard drive from the SAN to local storage (this machine was supposed to be running locally - not from the SAN).
4. Added the correct IP address back to Windows and unbound it from the network card that is no longer being shown in Windows.
5. Removed the old version of VMWare tools which the machine knew wrongly was Window2008R2x64 and installed the version for Windows 2012 instead


The machine seems more responsive while RDPed onto and has been stable for a good few hours now :/  Or maybe that's some hope from a System Manager



Sunday, 18 May 2014

Fixing a Bosch 2000 AXT Shredder

Fixing a Bosch 2000 AXT Shredder



I bought a shredder from ebay for £1.75 which had a fault on it of it kept blowing fuses when switched on.  At that price, what did I have to loose.

Got it home, sure enough, popped a new 13A fuse in the plug, turned it on and it came on for about a 10th of a second and blew the fuse.  I decided to take it apart to see if there was any visible sign of blackening or physical damage.  Nothing

Undid the side screws

Undid the lid

Pulled the front containing the switches off


There wasn't much in there, just the back of switches, bridge rectifier and a 450v 20uF capacitor.  There was no damage or blackening to any of the components and figured there was no other components further under the casing except for the power to the motor & if that is gone.... game over.



Even though there didn't appear to be any bulging to the capacitor, I bought a new capacitor from ebay for £9.09 and waited a week for it to be delivered.  Turns out I'd ordered the wrong one as this one had 4 tabs on the top, instead of 2.  Hay ho, bought it now.


Opened the case again and checked the capacitor was discharged by shorting the capacitor to prove to myself, there was no charge in it.  Last thing I wanted was a 340V+ DC shock.

Touching both tabs on the capacitor.  First time I did this was with an insulated glove.  Took it off for the photo

Took the old capacitor out by removing the spade plugs and unscrewing the capacitor, then doing the new one back up again.


There is no +ve or -ve/Gnd marks on the capacitor, so I figure the polarity didn't matter.

With the front still hanging off, I turned the switch on at the front, then plugged it in and turned it on at the switch.  Success!  Started turning and making a very weird noise which went away after a few minutes.

Put the front and top on and spent all afternoon using it.

Cost to buy new (currently) £190.  My spend £10.84 + diesel money for the collection.  Bargain!

Thursday, 10 March 2011

Shutting down a VM Machine cleanly




























I've been looking for a way of cloning a Virtual Application Server for disaster recovery, where the machine data files are on a local datastore and attaching the disk again into another datastore which is sat on our LeftHand iSCSI SAN for disaster recovery.  This way any other virtual host could start the host up and after some IP changes on the VM, we could be up and running again in around 15 minutes.

I want to:
  • Shut the VM down CLEANLY (not just equivalent of holding the OFF button)
  • Clone the disk
  • Start the VM up
  • All automated (I like my sleep)
This will be done as a WINDOWS scheduled task rather than a CRON job as windows scheduler in 2008 has many more options than CRON in ESXi can offer.  If you just want a simple weekly/monthyly copy CRON is probably the way forward.

The VM Host I am doing this on is not in vCenter, so I can't do any clever stuff that vCenter offers. 

Cloning the machine

Prerequisites:
I came across this website which had exactly what I wanted in the way of backing up and in the scenario I wanted.

Steps.
1. Logon to SSH
2. Make a new folder for the cloned disk to go to
3. Clone the disk

1. I used PuTTY to connect to the VM Host, but you can choose any SSH Client.
  • Enter the IP address and click Enter



















  • Enter your root username and password.  You are now at a command prompt

















2. As I'd already connected added an additional iSCSI disk to the VM I could browse it. (Click here to see how to add an iSCSI disk to VM Host *ADD)























 There is currently nothing on DataStore VM_TESSITURA_A, so I want to create a new folder to hold my cloned disk from RSCB015SV01C

mkdir /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C

I've differed the folder name to what I would usually call the machines by calling it FO_machinename.

3. Starting a disk clone is by using the command vmkfstools.  Effectively we are copying the vmdk file from one place to another

vmkfstools -i /vmfs/volumes/datastore1/RSCB015SV01C/RSCB015SV01C.vmdk /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C.vmdk

(Note: The above command is all on one line)

This will start the clone.

Destination disk format: VMFS zeroedthick

Cloning disk '/vmfs/volumes/datastore1/RSCB015SV01C/RSCB015SV01C.vmdk'...


Clone: 0% done.
Clone: 1% done.
Clone: 2% done.
etc...
Clone: 99% done.

Clone: 100% done.
 
Excelent!  Right - Arrow up and run the command again to check it works again.  Failed due to the destination already existing.  Not a problem - a simple remove command will do the trick:
 
rm /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C.vmdk
 
This failed... Why!  Checking the destination I was interested to find the cloned disk was now called machinename-flat.vmdk.  Interesting... I checked the source and sure enough the biggest file is machinename-flat.vmdk (the hard disk I just cloned) and there is also a tiny file called machinename.vmdk (around 500 bytes).  Viewing the datastore through the VM Host, it showed the files as machinename.vmdk
 
The command was changed to:
 
rm /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C-flat.vmdk
 
and I could then run the disk clone again successfully.
 
While the original VM was still off, on a second VM Host, I attached the storage VM_TESSITURA_A and created a new machine (*Add Link) and attached the cloned disk I just created.  Pressed the Play button and away we go - Windows starts up, adds new drivers & wants a reboot, then is stays on fine.
 
Shutting down the VM

I now needed a way of shutting the VM's cleanly.  I came across this command:
 
vim-cmd vmsvc/power.shutdown
 
which requires the machine number suffix which can be found by running
 
vim-cmd vmsvc/getallvms


Output:

Vmid Name File Guest OS Version Annotation
32 RSCB015SV01C [datastore1] RSCB015SV01C/RSCB015SV01C.vmx windows7Server64Guest vmx-07
80 RSCB015SV02C [datastore1] RSCB015SV02C/RSCB015SV02C.vmx windows7Server64Guest vmx-07
96 RSCB015SV03C [datastore1] RSCB015SV03C/RSCB015SV03C.vmx windows7Server64Guest vmx-07

So, RSCB015SV01C id is 32, so the command is:

vim-cmd vmsvc/power.shutdown 32
 
Yay.  It shutdown cleanly.  Next bit of thinking was start scripting everything together.  I came up with the individual steps:
 
vim-cmd vmsvc/power.on 32

mkdir /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C

rm /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C-flat.vmdk

 vmkfstools -i /vmfs/volumes/datastore1/RSCB015SV01C/RSCB015SV01C.vmdk /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C.vmdk


vim-cmd vmsvc/power.on 32
 
, which:
  • Shutdown the VM
  • Makes a folder on the destination (should always fail)
  • Remove the old disk clone
  • Reclone the disk
  • Start the VM
Excellent!  Quick trip to google to find out how to send commands to a SSH shell via a script and it suggests PLINK part of PuTTY.  I put the above individual steps into the file "backup_RSCB015SV01C.txt" and ran the command from my windows server:
 
plink root@VM_HOST_IP -ssh -pw password -m .\backup_RSCB015SV01C.txt >> output.txt 2>>&1
 
It ran all the steps, just far too quick.  The issue shutdown worked and the remove the old clone worked, but all the other steps failed as the machine was still shutting down when they were run.  Time for a delay of some sort!  Back to Google.
 
After much searching and trying to figure it out myself I stumbled across VMware: virtual machine shutdown -script for backup.  With my very limited knowledge of Linux scripting, it appeared to shutdown multiple machines based on their machine number.  Copy and Paste into a text file and uploading it to the server using the upload functionality in datastore put the file there and I had to do a chmod to allow execution:
 
chmod 700 ./vmshutdown.sh
 
Copy and Paste from the website to a text file produced a character at the end of each line that looked like ^H.  This was removed from each  line using vi editor as it kept erroring out the script.  Next to fail was the Array section.  I couldn't get this working so I adapted the script to something I knew how to do - command line arguments.  The only real changes I made were to remove the array, remove the array loop and the second shutdown statement.  Everything else as-is
 
The final script now looks like this (open in notepad)
 
The final backup_RSCB015SV01C.txt that gets called from windows now looks like:
 
/vmfs/volumes/datastore1/script/vmshutdown.sh 32

mkdir /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C
rm /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C-flat.vmdk
rm /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C.vmdk
vmkfstools -i /vmfs/volumes/datastore1/RSCB015SV01C/RSCB015SV01C.vmdk /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C.vmdk
sleep 60
vim-cmd vmsvc/power.on 32

As I won't be doing this for every VM we have - just a selected few, I'm happy enough to recreate this answer file each time

--Wayne

2011/03/11 addition:
To clone the disk to a thin disk, the switch -d thin needs adding between the source and destination

 vmkfstools -i /vmfs/volumes/datastore1/RSCB015SV01C/RSCB015SV01C.vmdk -d thin /vmfs/volumes/VM_TESSITURA_A/FO_RSCB015SV01C/RSCB015SV01C.vmdk