5

I need a batch file to add a record to hosts file in windows, however I do not need just a file append writing because I would like to check if this record is already present. Is it possibile?

Tobia
  • 9,165
  • 28
  • 114
  • 219

3 Answers3

8
type "%SystemRoot%\system32\drivers\etc\hosts" | find "my_record" ||echo my_record>>"%SystemRoot%\system32\drivers\etc\hosts"

try this.You'll need administrator permissions to add something in hosts file

npocmaka
  • 55,367
  • 18
  • 148
  • 187
  • Wonderful,is it better to add a new line before file append? – Tobia May 27 '13 at 13:32
  • 1
    An IP address can have a false match. This is not reliable. A record can also have TAB characters which make the compare more complicated. – foxidrive May 27 '13 at 13:44
  • ahhmm...yes...Will think for version with `FINDSTR` – npocmaka May 27 '13 at 13:46
  • 1
    @ Tobia if you want to add an empty line you can use: `echo\>>"%SystemRoot%\system32\drivers\etc\hosts&&echo my_record>>"%SystemRoot%\system32\drivers\etc\hosts""` .Take in mind the foxidrive's mention and use the whole line to find a record – npocmaka May 27 '13 at 13:51
  • This answer doesn't work on Windows 8.1, seems that there is some access denied problem.... maybe we should first change file permissions? – Tobia Aug 25 '14 at 08:22
  • @Tobia - if the the command prompt/batch is started "as Administrator" it works (as it's described in answer). If you want to automate this , you can try trough `SCHTASKS`, or to create a shortcut to the `bat` file with admin permissions or to turn off UAC... – npocmaka Aug 25 '14 at 08:31
  • I added this script to my inno setup installer (this worked for win7), I'm sure this installer runs as administrator, but still doesn't work. If I change hosts file permission it works again. – Tobia Aug 25 '14 at 08:36
  • @Tobia - what file permissions need to be changed? Can `ATTRIB` or `CACLS` be used? – npocmaka Aug 25 '14 at 08:42
  • I tried to change permissions by windows GUI before your script call, I added fullcontrol to everyone (I know it is unsafe, but it was just a test). – Tobia Aug 25 '14 at 09:01
  • @Tobia you try to execute first `echo y | cacls "%SystemRoot%\system32\drivers\etc\hosts" /g Administrator:c` – npocmaka Aug 25 '14 at 09:12
2

hmmm tricky one that.

First thing I would say is forget about trying to do this with a batch file.

Batch files alone lack the power to do anything like this unless used with external tools.

While it's certainly possible, unless you know exactly what command line tools you need to install and how you'll end up experimenting endlessly to find a good combination.

If you do want to go this route however, then I would suggest you take a look at the GnuWin32 project on sourceforge where they've ported all the standard unix command line tools to windows, and which include Sed, Grep, Awk and many more that are perfect for what you're trying to do.

I would however strongly suggest that you look at using Powershell, or even better if you have any .NET experience a command line tool in C#.

I can't off the top of my head think of a powershell example, but you could do it in C# with something like:

using System;
using System.Collections.Generic;
using System.IO;

class Program
{
  static void Main()
  {
    const string filename = "path\to\your\hosts\file";

    List<string> lines = new List<string>();
    using (StreamReader reader = new StreamReader(filename))
    {
      string line;
      while ((line = reader.ReadLine()) != null)
      {
        lines.Add(line);
      }
    }

    string newLineToAdd = "127.0.0.1  somedomain.com"
    bool found = false;

    foreach(string line in lines)
    {
      if(line.Equals(newLineToAdd))
      {
        found = true;
      }
    }

    if(!found)
    {
      lines.Add(newLineToAdd);
    }

    using (StreamWriter writer = new StreamWriter(filename))
    {
      foreach(string line in lines())
      {
        writer.WriteLine(line);
      }
    }
  }
}

Please note, that's not a full example, and I've certainly not had time to test compile it, but in theory what you need to do (Irrespective of the language you choose) is:

1) Load all the lines of the file into an array 2) Scan each line in the array check to see if it equals the line you want to add 3) If it does not already exists in the array, add the new line to the array 4) Write all the lines in the array back to disk, completely overwriting the old file.

Some things to note about my example:

1) I've hard coded everything, you'll want to pass in some parameters (Unfortunately I don't have time at the moment to type up a full featured sample)

2) Modifying the host file MUST have admin privileges, therefore you will either need to run the program from a shortcut marked to run as admin, or you will need to set your .NET project up to compile and be executed as an admin program by adding some extra code to it to use the UAC functions in windows. (The first method is the quickest and easiest)

Hopefully however my notes here should get you started in the right direction.

If I get time later on (and I remember....) I'll come back and see if I can improve things a bit more.

shawty
  • 5,729
  • 2
  • 37
  • 71
1

suggestion based on the code by npocmaka:

for /f "tokens=1*" %%i in ("%my_record%") do type "%SystemRoot%\system32\drivers\etc\hosts" | find "%%i" | find "%%j" >nul||echo %my_record%>>"%SystemRoot%\system32\drivers\etc\hosts"

This solves not the issue of the false IP match.

Community
  • 1
  • 1
Endoro
  • 37,015
  • 8
  • 50
  • 63