Bash Script: Auto Configure vmware-tools at Boot time

This post is originally posted on my colleague Michel aka ‘HighKing’ blog:

When you install a new kernel on a RHEL/CentOS VM, you need to reconfigure the vmware-tools using the ‘’ script. I have created a simple script that does this automatically, so you don’t have to be there when the kernel is updated (handy for automatically updating machines).

Place this in a script called ‘check-vmware-tools’ in /etc/init.d:

# check-vmware-tools
# chkconfig:   - 00 99
# description: Check whether or not the vmware-tools are installed at boot time.
# processname: check-vmware-tools

loadvmxnet() {
  if [ "`uname -i`" != "x86_64" ]; then 
        echo -n "Reloading vmxnet driver... "
        /sbin/rmmod pcnet32
        /sbin/rmmod vmxnet
        /sbin/depmod -a
        /sbin/modprobe vmxnet
        echo "done"

case $1 in
    echo -n $"Checking VMware-tools: "
   if [ ! -e /lib/modules/`/bin/uname -r`/misc/vmci.ko ]; then
      echo "Not available, running vmware-config-tools..."
      /usr/bin/ --default && loadvmxnet
     echo "OK"
    echo "Usage: $0 start"
    exit 1

Make it writeable with:

chmod +x /etc/init.d/check-vmware-tools

Next is to make it known by chkconfig with:

chkconfig --add check-vmware-tools

Now we have done that, we can simply enable it with:

chkconfig check-vmware-tools on

On the next boot, this script checks whether or not the vmware-tools are configured for the running kernel (by checking if vmmemctl.ko is in place). If not, it runs ‘ and reboots after that.

You can download the file here: check-vmware-tools


PowerCLI: Export, Import and Create DRS Rules


I was trying to create a DRS Rule creation script but after a short search on the PowerCLI communities, I found some excellent stuff from @LucD. These are two scripts for Exporting and importing DRS rules.

To export your DRS-Rules, you can run the next script. The only thing you have to change is <cluster-name> to your cluster name.

$outfile = "C:\rules.txt" Remove-Item $outfile $clusterName = <cluster-name> $rules = get-cluster -Name $clusterName | Get-DrsRule foreach($rule in $rules){ $line = (Get-View -Id $rule.ClusterId).Name $line += ("," + $rule.Name + "," + $rule.Enabled + "," + $rule.KeepTogether) foreach($vmId in $rule.VMIds){ $line += ("," + (Get-View -Id $vmId).Name) } $line | Out-File -Append $outfile }


The import script looks like this:


$file = "C:\rules.txt"
$rules = Get-Content $file

foreach($rule in $rules){
  $ruleArr = $rule.Split(",")
  if($ruleArr[2] -eq "True"){$rEnabled = $true} else {$rEnabled = $false}
  if($ruleArr[3] -eq "True"){$rTogether = $true} else {$rTogether = $false}
  get-cluster $ruleArr[0] | `
    New-DrsRule -Name $ruleArr[1] -Enabled $rEnabled `
    -KeepTogether $rTogether `
    -VM (Get-VM -Name ($ruleArr[4..($ruleArr.Count - 1)])) 


If you want to create a new DRS-Rules, you only have to create your own rules.txt file like this:



Now run the Import DRS-Rules script and in a blink of an eye, the new rules are created.



Powershell: Export Installed Software to Excel


I created the next script to inventory the installed software on my servers. The only thing you need to create is a text file with all your servers in it and save it to Servers.txt.

#Create a new Excel object using COM
$Excel = New-Object -ComObject Excel.Application
$Excel.visible = $True
$Excel.SheetsInNewWorkbook = @(get-content "C:\Scripts\PS\Servers.txt").count

#Counter variable for rows
$i = 1

#Read thru the contents of the Servers.txt file
foreach ($server in get-content "C:\Scripts\PS\Servers.txt")
    $Excel = $Excel.Workbooks.Add()
    $Sheet = $Excel.Worksheets.Item($i++)
    $Sheet.Name = $server

    $intRow = 1

    # Send a ping to verify if the Server is online or not.
    $ping = Get-WmiObject `
    -query "SELECT * FROM Win32_PingStatus WHERE Address = '$server'"
       if ($Ping.StatusCode -eq 0) {

         #Create column headers
         $Sheet.Cells.Item($intRow,1) = "NAME:"
         $Sheet.Cells.Item($intRow,2) = $server.ToUpper()
         $Sheet.Cells.Item($intRow,1).Font.Bold = $True
         $Sheet.Cells.Item($intRow,2).Font.Bold = $True


         $Sheet.Cells.Item($intRow,1) = "APPLICATION"
         $Sheet.Cells.Item($intRow,2) = "VERSION"

             #Format the column headers
             for ($col = 1; $col –le 2; $col++)
                  $Sheet.Cells.Item($intRow,$col).Font.Bold = $True
                  $Sheet.Cells.Item($intRow,$col).Interior.ColorIndex = 48
                  $Sheet.Cells.Item($intRow,$col).Font.ColorIndex = 34


             $software = Get-WmiObject `
             -ComputerName $server -Class Win32_Product | Sort-Object Name 

             #Formatting using Excel

             foreach ($objItem in $software){
                $Sheet.Cells.Item($intRow, 1) = $objItem.Name
                $Sheet.Cells.Item($intRow, 2) = $objItem.Version

                   $intRow ++



The following Excel file will be created. For each server in Servers.txt, there will be added a worksheet with the name of the server.


Powershell: Remove a Folder from every Home Directory


I had to remove a folder from every home directory. So I thought this is a nice thing to do with Powershell.

So I created the Remove-Folder function to do this for me :-).

The function will go through the following steps:

The begin part will browse to all the folders within the E:\users and export the full path to a CSV file. The path will look like this: E:\users\username\test\foldername.

In the process part it will remove all the folders which are saved in the CSV file.

Warning: The folders will be removed without a warning. So be sure you want to do this!!

function Remove-Folder{

        Get-Childitem $path -Recurse `
        | Where-Object { $_.Name -eq $folder } `
        | Select FullName `
        | Export-Csv -NoTypeInformation "$env:temp\remove.csv"
        $import = Import-Csv "$env:temp\remove.csv"
        foreach($folder in $import){
            Remove-Item $folder.FullName -Recurse -Force
    Remove-Item "$env:temp\remove.csv"

You can use the function with the following command:

Remove-Folder E:\users foldername

Via the following one-liner, you can validate the removal job:

Get-Childitem E:\users -Recurse `
| Where-Object { $_.Name -eq "foldername" } `
| Select FullName `
| Export-Csv -NoTypeInformation "$env:temp\remove.csv" 

Open the remove.csv file to verify the changes.

Powershell: Set Logon Hours for all the users in an OU


With the script in this post you’re able to set logon hours to a bunch of users. All you have to do is to setup logon hours for a “template” user and define this “template” user into the $template variable.


The other step is to define the $ou variable with the path to the OU. In my case this was ict-freak/Gebruikers.

The script will now read the default logon hours and will apply them to the users in the OU.

$template = "" # This is a user with the default logon hours
$ou = "" # the full path to your ou "domainname/ouname1/ouname2"

# Get the logonhours from the template user
$template = Get-QADUser $template -IncludedProperties logonhours
[array]$logonHours = $template.DirectoryEntry.logonHours

# Get all users
$users = Get-QADUser -OrganizationalUnit $ou

# Loop through all the users
foreach($user in $users){
    Set-QADUser $user.Name -oa @{logonHours = $logonHours}


I found this trick here:

Xtravirt: VMware Documentation Downloader


Paul Buckle van has released an awesome script called VMware Documentation Downloader. 


  • Microsoft Windows
  • GetVMwareDocs.bat script (download latest version below)
  • wget.exe utility (wiki available here and download utility at
  • Minimum of 650MB free disk space (this requirement will increase over time as VMware publish new documentation)
  • Internet access (direct, or via an HTTP proxy)
  • .txt files have been associated with a document viewer
  • .html files have been associated with a web browser


  • Create a folder to contain the script and the downloaded files (eg. C:\VMwarePDFs).
  • Download GetVMwareDocs.bat and wget.exe and save them to this folder.

Alternatively, copy an existing “installation” from another machine.

So if you want an offline copy of the VMware documents, grab a copy of the script here: (you have to sign in). Download wget,exe and you’re ready to download the docs.

The script in action:


Posh: Run gpupdate on Multiple Computers


I created a Powershell script that will get all the computers from a certain OU and run GPUpdate /force on these machines. This script uses the Quest Active Directory cmdlets and PsExec.exe. You need to install the Quest cmdlets first. If PsExec doesn’t exist, the script will download it to the c:\tools directory.

When you start the script, you have to enter the FQDN and the OU name:


The script creates a text file with al the computer names in it. This text file will be used with the PsExec.exe command.


You can find the script on

Restart VMware Tools on all Windows VM’s


After reading the post on about the VMware Tools status “not running” and in particular the part about the preferred work around:

I find that restarting the VMware Tools Service in the guest OS always gets by the problem, but loggin into every single VM that reports the wrong status for it’s VMware Tools could be a bit of a drag. So I choose to do this remotely rather that logging on to each VM.

From any Windows workstation/server, open a command pompt and run:

sc \\{vm-name-or-ip-address} stop "VMTools"
sc \\{vm-name-or-ip-address} start "VMTools"

I thought that can be done via Powershell and the VI Toolkit. So I created the following script that will restart the VMware Tools service on every running Windows VM.

$vCenter = Read-Host "Enter the vCenter servername"

Connect-VIServer $vCenter

$Service = "VMtools"
$VMs = Get-VM | Where-Object {
        $_.PowerState -eq "PoweredON" `
        -and `
        $_.Guest.OSFullName -match "Windows"
foreach($VM in $VMs)
    Write-Host "-------------------------------------------"
    Write-Host "Restarting the VMware Tools Service on" $VM
        $Svc = Get-WmiObject -Computer $VM win32_service `
        -filter "name='$Service'"
            $Result = $Svc.StopService()
            sleep 5
            $Result = $Svc.StartService()
    Write-Host "Done.. "
    Write-Host "-------------------------------------------"

Disconnect-VIServer -Confirm:$false

This script generates the following output:


Other useful blog posts or kb articles on this subject:

Source for the restart service part in my script:

Veeam FastSCP3 on Windows 7 X64


If you try to install Veeam FastSCP3 on Windows 7 X64. You’ll get the following error:


I asked a question about this error in the Veeam Forums:

Gostev suggested the following:

the workaround is to hack installation package and remove OS version check (if you know how to do this) :wink:

So this is exactly what i did. I found a script on this page: This script does exactly what i needed. It removes the OS Version Check from the MSI.

These are the steps:

  1. Download Veeam FastSCP 3 from here:
  2. Extract the zip file.
  3. Download winrar and extract the veeam_fastscp_3.0.exe.
  4. Get the scrtipt from: and save it on the desktop.
  5. Grab the extracted FastSCPSetup.msi and drop it on the script. After a couple of seconds, the following screens will popup: 
    image     image  image image
  6. You can install FastSCP 3 by running the FastSCPSetup.msi.

Remove files older than x days with PoSH


One of the Symantec Live Update Servers started to complain about low disk space. So I started Treesize Pro to see what files or folders where eating my disk space.  After a couple of seconds Treesize Pro showed me that the liveupdate files, in the c:\LiveUpdate folder where the problem.

I created the following Powershell Script (after reading the source) and scheduled this script to run once a week.

Warning: This script will remove everything that matches the remove-item cmdlet!

$Now = Get-Date
$Days = "3"
$TargetFolder = "C:\LiveUpdate"
$LastWrite = $Now.AddDays(-$days)
$Files = get-childitem $TargetFolder -include *.zip, *.x86 -recurse `
    | Where {$_.LastWriteTime -le "$LastWrite"} 

foreach ($File in $Files)
{write-host "Deleting File $File" -foregroundcolor "Red"; `
    Remove-Item $File | out-null}

Just change the $Days, $TargetFolder variables and the file extensions (*.zip, *.x86) for you environment.
Source of this script: powershell-script-to-delete-files-older-than-certain-days.aspx