Add and Remove Service Entries

This is a quick script I’ve used to add and remove service entries to the windows services file. It ignores commented lines (lines starting with a hash (#)), and it also doesn’t validate the format of the host or port/protocol so use with care!

Add And Remove Service Entries

cscript.exe services.vbs “Add” “localhost” “8080/http”
cscript.exe services.vbs “Remove” “localhost” “8080/http”

Option Explicit
Const ForReading = 1
Const ForWriting = 2
Const ReadOnly = 1
'Usage
'cscript.exe services.vbs "Add" "service" "port/protocol" 
'cscript.exe services.vbs "Remove" "service" "port/protocol"
If (wscript.arguments.count < 3) Then
'need a verb, service and port/protocol
Wscript.quit
End If
'Add/Remove
dim inputAction : inputAction = wscript.arguments(0)
dim inputServiceName : inputServiceName = wscript.arguments(1)
dim inputPortProtocol : inputPortProtocol = wscript.arguments(2)
dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
dim objShell : Set objShell = CreateObject("WScript.Shell")
dim strSystemRoot : strSystemRoot = objShell.ExpandEnvironmentStrings("%systemroot%")
dim pathToServices : pathToServices = strSystemRoot & "\system32\drivers\etc\services"
'make changes in memory first - we need to open it in write mode first otherwise we get 'Bad file mode' error
dim servicesFile : Set servicesFile = oFSO.OpenTextFile(pathToServices, ForReading, true)
'get original read from file.  We'll amend services in memory until we commit changes at the end
dim servicesContent
If Not servicesFile.AtEndOfStream Then servicesContent = servicesFile.ReadAll
dim servicesEntry
if (inputAction = "Add") Then
servicesContent = AddServicesEntry(inputServiceName,inputPortProtocol)
End If
if (inputAction = "Remove") Then
servicesContent = RemoveServicesEntry(inputServiceName,inputPortProtocol)
End If
servicesFile.Close()
'set attribute to read/write if readonly
dim objFile : Set objFile = oFSO.GetFile(pathToServices)
If objFile.Attributes AND ReadOnly Then
objFile.Attributes = objFile.Attributes XOR ReadOnly
End If
'then write changes to actual file
Set servicesFile = oFSO.OpenTextFile(pathToServices, ForWriting, true)
servicesFile.Write servicesContent
servicesFile.Close()
Function RemoveServicesEntry(serviceName, portProtocol)
dim objRegEx : Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Pattern = "^(?!#)(" & serviceName & ")(\s|\t)+" & portProtocol
dim strNewContents : strNewContents = ""
dim servicesContentLines : servicesContentLines = Split(servicesContent,vbCrlf)
For each servicesEntry in servicesContentLines
If NOT objRegEx.Test(servicesEntry) Then	
strNewContents = strNewContents & servicesEntry & vbCrLf		
End If
Next
'remove last carriage return	
If Right(strNewContents, 2) = vbCrLf Then
strNewContents = Left(strNewContents, Len(strNewContents) - 2)
End If
Set objRegEx = Nothing
RemoveServicesEntry = strNewContents
End Function
Function AddServicesEntry(serviceName, portProtocol)
dim objRegEx : Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Pattern = "^(?!#)(" & serviceName & ")(\s|\t)+" & portProtocol
dim strNewContents : strNewContents = ""
dim portProtocolExists : portProtocolExists = false	
dim servicesContentLines : servicesContentLines = Split(servicesContent,vbCrlf)
For each servicesEntry in servicesContentLines
If objRegEx.Test(servicesEntry) Then
portProtocolExists = true	
End If
strNewContents = strNewContents & servicesEntry & vbCrLf
Next
If Not portProtocolExists Then
strNewContents = strNewContents & serviceName & vbTab & portProtocol 
End If
'remove last carriage return	
If Right(strNewContents, 2) = vbCrLf Then
strNewContents = Left(strNewContents, Len(strNewContents) - 2)
End If
Set objRegEx = Nothing
AddServicesEntry = strNewContents
End Function
Set servicesFile = Nothing
Set objFile = Nothing
Set oFSO = Nothing
Set objShell = Nothing

and here’s an example of how it can be called from another vbscript:

Option Explicit
Dim objFSO : Set objFSO = CreateObject("Scripting.FilesystemObject")
Dim objShell : Set objShell = CreateObject("Wscript.Shell")
dim strFolder : strFolder = objFSO.GetParentFolderName(WScript.ScriptFullName) 
dim strScript : strScript = strFolder & "\services.vbs"
If objFSO.FileExists(strScript) Then
'example to add an entry
addEntry "localhost","8080/tcp"
'addEntry "localhost","8080/udp"
'example to remove an entry
'removeEntry "localhost","8080/udp"
End If
Function addEntry(host, portProtocol)
dim commandLine : commandLine = chr(34) & strScript & chr(34) & " " & chr(34) & "Add" & chr(34) & " " & chr(34) & host & chr(34) & " " & chr(34) & portProtocol & chr(34)
objShell.Run "cscript.exe " & commandLine
End Function
Function removeEntry(host, portProtocol)
dim commandLine : commandLine = chr(34) & strScript & chr(34) & " " & chr(34) & "Remove" & chr(34) & " " & chr(34) & host & chr(34) & " " & chr(34) & portProtocol & chr(34)
objShell.Run "cscript.exe " & commandLine
End Function
Set objFSO = Nothing
Set objShell = Nothing