Over a million developers have joined DZone.

Using PowerShell Scripts to Deploy Your Software

Simplifying packaging and deployment of your software by scripting it with PowerShell.

· DevOps Zone

The DevOps zone is brought to you in partnership with Sonatype Nexus. The Nexus suite helps scale your DevOps delivery with continuous component intelligence integrated into development tools, including Eclipse, IntelliJ, Jenkins, Bamboo, SonarQube and more. Schedule a demo today

I often use PowerShell scripts to package a “release” of a software during a build because it gives me a lots of flexibility.

The advantage of using PowerShell is complete control over what will be included in the “release” package. It allows you to manipulate configuration files, remove unnecessary files, copy files from somewhere else in the repository, etc.

The aim of using PowerShell in a build is to create a single archive that contains everything needed to deploy a new release.

This is the first paradigm, all the artifacts needed to install the software should be included in one or more zip archives. Once you have this, the only step that separates you from Continuous Deployment is creating another scripts that is capable of using that archive to install the software in the current system. This is an example of the minimal parameter set in a typical script.

    [string] $deployFileName,
    [string] $installationRoot

This scripts the name of the package file and the path where the software should be installed. More complex program accepts other configuration parameteres, but this is the simplest situation for a simple piece software that runs as a service in Windows and needs no configuration. The script does some preparation and then start the real installation phase.

$service = Get-Service -Name "Jarvis - Configuration Service" -ErrorAction SilentlyContinue 
if ($service -ne $null) 
    Stop-Service "Jarvis - Configuration Service"

Write-Output 'Deleting actual directory'

if (Test-Path $installationRoot) 
    Remove-Item $installationRoot -Recurse -Force

Write-Output "Unzipping setup file"
Expand-WithFramework -zipFile $file.FullName -destinationFolder $installationRoot

if ($service -eq $null) 
    Write-Output "Starting the service in $finalInstallDir\Jarvis.ConfigurationService.Host.exe"

    & "$installationRoot\Jarvis.ConfigurationService.Host.exe" install

The first step is obtaining a reference to a Windows service called “Jarvis – Configuration Service”, if the service is present the script tells it to stop and waits while it stops. Once the service has stopped it deletes the current directory, and then, extracts all the files contained in the zipped archive to the same directory. If the service was not present (it is the very first installation) it invokes the executable with the install option (we are using TopShelf).

The goal of the script is to be able to work for a first time installation, as well of subsequent installations.

A couple of aspect are interesting in this approach: first, the software does not have any specific configuration in the installation directory, when it is time to update, the script deletes everything, and then copies the new version to the same path. Secondly, the script is made to work if the service was already installed, or if this is the very first installation.

Since this simple software indeed uses some configuration in the app.config file, it is the duty of the scripts to reconfigure the software after the deployment.

$configFileName = $installationRoot + "\Jarvis.ConfigurationService.Host.exe.config"
$xml = (Get-Content $configFileName)

Edit-XmlNodes $xml -xpath "/configuration/appSettings/add[@key='uri']/@value" -value "http://localhost:55555"
Edit-XmlNodes $xml -xpath "/configuration/appSettings/add[@key='baseConfigDirectory']/@value" -value "..\ConfigurationStore"


This snippet of code uses an helper function to change the configuration file with XPath. Here there is another assumption: no-one should change the configuration file, because it will be overwritten on the next installation. All the configurations that are contained in configuration file should be passed to the installation script.

The installation script should accept any configuration that needs to be stored in application configuration file. This is necessary to allow for a full overwrite approach, where the script deletes all previous file and overwrites them with the new version.

In this example we change the port the service is listening on and change the directory where this service will store configuration files (it is a configuration file manager). The configuration store is set to ..\ConfigurationStore, a folder outside the installation directory. This will preserve content of that folder on the next setup.

To simplify updates, you should ensure that it is safe to delete the old installation folder and overwrite it with a new one during upgrade. No configuration or no modification must be necessary in files that are part of the installation.

The script uses hardcoded values: port 55555 and ..\ConfigurationStore folder, if you prefer, you can pass these values as parameter of the installation script. The key aspect here is: Every configuration file that needs to be manipulated and parametrized after installation, should be placed in another directory. We always ensure that the installation folder can be deleted and recreated by the script.

This assumption is strong, but avoids complicating installation scripts, where the script needs to merge default settings of the new version of the software with the old settings of previous installation. For this reason, the Configuration Service uses a folder outside the standard installation to store the configuration.

All scripts can be found in Jarvis Configuration Service project.

Related Refcard:

The DevOps zone is brought to you in partnership with Sonatype Nexus. Use the Nexus Suite to automate your software supply chain and ensure you're using the highest quality open source components at every step of the development lifecycle. Get Nexus today


Published at DZone with permission of Ricci Gian Maria, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}