Modify Windows HOSTS file using SCCM (System Center Configuration Manager) and Powershell

Introduction

I was just doing some work today where I needed to modify the content of the HOSTS file in Windows on a good bunch of devices. (This is the file being located in C:\Windows\System32\drivers\etc)

I figured this is something anybody might find useful, so I wanted to share the Powershell script I ended up creating for the purpose.

For your convenience, I’m also illustrating how this can be used in combination with ConfigMgr as this was a requirement for automation purposes 🙂

Powershell

The use of the script is pretty straightforward. It’s created to accept parameters, so you don’t have to modify the content of the actual script on a need to need basis.

Adding a new entry to the hosts file is done by running the script with the -AddHost parameter:

  • .\Edit-HostsFile.ps1 -AddHost -IP 192.168.1.1 -Hostname ftw.imab.dk

Removing an existing entry from the hosts file is done by running the script with the -RemoveHost parameter:

  • .\Edit-HostsFile.ps1 -RemoveHost -Hostname ftw.imab.dk

Configuration Manager

Using the script with ConfigMgr is easy as well.

Create a package with a program running following command line:

  • powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File .\Edit-HostsFile.ps1 -AddHost -IP 127.0.0.1 -Hostname ftw.imab.dk

Deploy it to the desired devices. In this example, this is done as an available deployment displaying in the Software Center.

You can also run the script directly in your task sequence as illustrated below.

End result

The end result is a delicious HOSTS file now including your new modifications.

Download

PowerShell/Edit-HostsFile.ps1 at master · imabdk/PowerShell (github.com)

16 thoughts on “Modify Windows HOSTS file using SCCM (System Center Configuration Manager) and Powershell”

  1. Hello,

    Really nice tool. One issue though:

    If there is no blank line at the end of HOSTS file then the first entry that you add with the command is appended to the last entry of the hosts file, making both entries (old and new) useless.

    Perhaps you could add a `n character in the script so that it leaves a blank line by design?
    The script does the trick fine for multiple lines because you make sure that a blank line is added after each entry you add.

    The issue starts when someone edits the HOSTS file manually and leaves no blank line at the end of the file.

    Reply
    • Thanks! I can see that. Let me see what I can come up with 🙂 One quick workaround would be to remove the host that was manually entered and add it back using the script, seeing that my script always include a new line (Out-File does that automatically)

      Reply
  2. For now, the easiest work around for me was this.

    Change line 45 from $fIP + “`t” + $fHostname | Out-File -Encoding ASCII -Append $File to “`n” + $fIP + “`t” + $fHostname | Out-File -Encoding ASCII -Append $File.

    So now i’m sure that a blank line is left before each entry. This leads of course to new entries being separated by a blank line but i don’t mind. Sometimes it makes it easier to read them. 🙂

    Reply
    • Yeah, that was my first approach as well, but I don’t like the additional new line. I’ll see if I can come up with something else 🙂

      Reply
  3. how do you deal with the elevated privilegs that are necessary to edit the host file.
    i’m stuck on this one.

    on the other hand , very decent script!

    Reply
    • Hi, if you run the script with system privileges (whether or not a user is logged on), you should be able to modify the hosts file 🙂

      Reply
  4. Here’s a modified version for the “services” file in the same “\windows\system32\drivers\etc” folder.

    param(
    [Parameter(Mandatory=$false)]
    [string]$Service,

    [Parameter(Mandatory=$false)]
    [string]$Port,

    [parameter(Mandatory=$false)]
    [ValidateNotNullOrEmpty()]
    [switch]$AddService,

    [parameter(Mandatory=$false)]
    [ValidateNotNullOrEmpty()]
    [switch]$RemoveService
    )

    # Path to local services file
    $File = “$env:windir\System32\drivers\etc\services”

    # function to add new service to services file
    function Add-Service([string]$fService, [string]$fPort) {
    Write-Verbose -Verbose -Message “Running Add-Services function…”
    $Content = Get-Content -Path $File | Select-String -Pattern ([regex]::Escape(“$fService”))
    if(-NOT($Content)) {
    Write-Verbose -Verbose -Message “Adding $Service $Port to services file”
    $fService + “`t” + $fPort | Out-File -Encoding ASCII -Append $File
    }
    else {
    Write-Verbose -Verbose -Message “$Service already exists in the SERVICES file”
    }
    }

    # function to remove service from services file
    function Remove-Service([string]$fService) {
    Write-Verbose -Verbose -Message “Running Remove-Service function…”
    # Get content of current services file
    $Content = Get-Content -Path $File
    # Create empty array for existing content
    $newLines = @()

    # Loop through each line in services file and determine if something needs to be kept
    $LineCount = 0
    foreach ($Line in $Content) {
    $LineCount = $LineCount + 1
    $Bits = [regex]::Split($Line, “\t+”)
    # Troubleshooting variables
    # $Bits0 = $Bits[0]
    # $BIts1 = $Bits[1]
    if ($Bits.count -eq 2) {
    if ($Bits[0] -ne $fService) {
    # Add existing content of services file back to array
    $newLines += $Line
    }
    # Commented out for verification/troubleshooting

    }
    else {
    $newLines += $Line
    }
    }
    # Clearing the content of the services file
    Write-Verbose -Verbose -Message “Clearing content of SERVICES file”
    try {
    Clear-Content $File
    }
    catch {
    Write-Verbose -Verbose -Message “Failed to clear the content of the SERVICES file”
    }

    # Add back entries which is not being removed
    foreach ($Line in $newLines) {
    Write-Verbose -Verbose -Message “Adding back each entry which is not being removed: $Line”
    $Line | Out-File -Encoding ASCII -Append $File
    }
    }

    # Run the functions depending on choice when running the script
    # Add services to file
    if ($PSBoundParameters[“AddService”]) {

    Add-Service $Service $Port

    }
    # Remove services from file
    if ($PSBoundParameters[“RemoveService”]) {

    Remove-Service $Service

    }

    Reply
  5. If you swap the order of “RemoveHost” and “AddHost” at the end of the script, then you can include both switches in the command line to replace the hosts entry if it already exists.

    Reply

Leave a Reply to kjell Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.