Again, we want to have a way to setup our environments while easily maintaining the mechanism. Separating the configuration settings and scripts is very important since eventually we would like to have our end-users can maintain their data without worrying the code/scripts and vise versa.

First is the template of configuration files.

<Server id="MyServer">
    <Service id="MyService1">
      <DisplayName>My Service 1</DisplayName>
    <Service id="MyService2">
      <DisplayName>My Service 2</DisplayName>

Second, let’s make a PS script to do the work

function SetupAService ($serviceName, $displayName, $binaryPath, $serviceActName, $serviceActPasswd, $startType) 
	# verify if the service already exists, and if yes remove it first
	if (Get-Service $serviceName -ErrorAction SilentlyContinue)
		# using WMI to remove Windows service because PowerShell does not have CmdLet for this
		$serviceToRemove = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"
		"service removed: $serviceName"
		# just do nothing
		"service does not exists"

	"installing service"
	# creating credentials which can be used to run my windows service

	$secpasswd = ConvertTo-SecureString $serviceActPasswd -AsPlainText -Force
	$mycreds = New-Object System.Management.Automation.PSCredential ($serviceActName, $secpasswd)

	# creating widnows service using all provided parameters
	New-Service -name $serviceName -binaryPathName $binaryPath -displayName $displayName -startupType Automatic -credential $mycreds
	if ([string]::Compare($startType,"delayed-auto", $True) -eq 0)
        $scCommand = "sc.exe config '$serviceName' start= delayed-auto"
        write-host "scCommand: $scCommand"
        Invoke-Expression -Command $scCommand -ErrorAction Stop

	"Installation Completed"

Then of course, let’s have another PS script to loop through the config file and setup them one by one.

# Source in SetupAService.ps1
. ".\SetupAService.ps1"

### Read the config XML
# [xml]$thisServer = Get-Content $scriptRoot\Config\UAT\MyServer.xml
$configFile = $args[0]
[xml]$thisServer = Get-Content $configFile

### Create a service for each element in the xml file (under services)
$thisServer.Server.Services.Service| foreach {SetupAService $ $_.DisplayName $_.BinaryPath $_.LogonAsAccount $_.LogonAsPassword $_.StartType}

OK, from now on, just try to keep the config files up-to-date. If you really committed to this, you can use it to refresh your existing environments as well. next time, I will try to have another script to do the audit.