Appveyor build status

Beam me up, Scotty!


Beam is a Powershell build/deploy utility that was designed to handle .NET projects.

The problem

When creating a reasonably sized web-based application that consist of multiple microservices, websites and additional tools, each of those application types can have different deployment methods and tools. If we add support for branding and multiple clients, all of these are further multiplied.

We want to:

  • automate deployments
  • be able to deploy manually from commandline
  • store deployment config (a.k.a. publish profiles) outside of main code repository
  • define some global properties per environment instead of repeating them for all applications (i.e build configuration, target server name, etc.)
  • do not store credentials in config files


Beam provides a model for describing applications and environments, as well as scripts that understand that model and call other appropriate tools that do deployment.

Main Features

  • Describe deployment environments and application profiles through declarative, JSON-like Powershell maps
  • Supports inheritance to avoid repeating same properties for different applications
  • Multiple publishing targets, including:
    • Azure Websites
    • IIS Webdeploy
    • Task Scheduler tasks
  • Leverage staging - test - swap deployment flow


  1. Clone this repository in your repository root:

    hg clone beam

  2. Create profiles dir in your repository root and copy sample config file publishmap.sample.config.ps1 there:

    mkdir profiles cp beam/samples/publishmap.sample.config.ps1 profiles/

  3. Test it:

    PS> beam/publish.ps1 -help
    info: publish CLI        
    help:   Get last operation status
    help:     status
    help:   Commands:
    help:     sample

    PS> beam/publish.ps1

Getting Started

Profile file are stored in profiles dir and should be named according to the following template: publishmap.{xxx}.config.ps1 (where {xxx} is your project name). A minimal config file publishmap.my_project_group.config.ps1 for a website looks like this:

    my_project_group = @{
        global_profiles = @{
            dev = @{
                    Config = "Debug"
                    Server =  "phobos"                    
                    BaseAppPath = "devserver-dev"
        site1 = @{ 
            sln = "Site1.sln"
            proj = "src\Site1\Site1.csproj"


> ./publish.ps1

You can always add -help to get some help and a list of available commands.


Configuration maps consist of three levels: project -> application -> profiles.

  • Application is the base unit of work. Each Application may have multiple profiles (think of evironments, like dev, prod, beta, etc.).

  • Project: Applications are grouped into projects to facilitate managing multiple high-level projects (i.e. multiple companies or clients).

   project = @{
      application = @{
          profiles = @{
              dev = @{
              prod = @{

When calling publish.ps1 you pass it a full profile path, i.e:

Special keys

Project Level:

  • global_profiles - describe global profiles that are inherited by all applications.

Application/Profile level:

  • csproj - path to csproj file
  • sln - path to sln file
  • SkipMissingProjects - if sln or csproj is missing, skip this application instead of throwing an error

Scheduled tasks:

  • task_interval - for scheduled task. Determines the interval between task scheduler runs (i.e. 10m - run each 10 minutes)
  • task_force - force task creation and config update, even if it already exists