How to improve infrastructure automation with PowerShell and Bolt

Automating your work with PowerShell scripts is simple and empowering with Bolt. If you’re not familiar with Bolt, it’s our agentless multi-platform open source tool that allows you to automate tasks on an as-needed basis or as part of a greater orchestration workflow. You can use Bolt to patch and update systems, troubleshoot servers, deploy applications, or stop and restart services.

In this blog post we’ll share some of the benefits of using PowerShell and Bolt together, and then walk you through restarting a service with a PowerShell script and Bolt.

The power of using PowerShell and Bolt together

If you are a PowerShell user working in a typical Windows domain environment, then much of what you can do with Bolt, you can do with PowerShell. But if you need to perform tasks in a mixed Windows and Linux environment, or if you need to orchestrate various parts of a complex workflow, Bolt can be a powerful addition to your regular scripting.

With Bolt, you have the ability to mix tasks in PowerShell on Windows with tasks in other languages on Linux, all in the same workflow — one that is version controlled and easily distributable. Even if you don't have a mixed environment, Bolt allows you to easily share small reusable tasks written in PowerShell, instead of your team members having to re-implement common functionality in their scripts.

Additionally, Bolt plans — which go beyond the scope of the example in this blog post — allow you to add Puppet module code via Apply manifest blocks, giving you the ability to mix imperative tasks with declarative state configuration, using Puppet supported modules or PowerShell DSC via the dsc_lite module.

Example: Run a PowerShell script that restarts a service

To see Bolt in action, we’ll walk you through a simple example which involves running a script with Bolt, converting the script to a Bolt Task, and then executing the Task. The example script we’ll use, called restart_service.ps1, performs a common task of restarting a service on demand. The process involves these steps:

  1. Run your PowerShell script on a remote Windows node.
  2. Create an inventory file to store information about the node.
  3. Convert your script to a task.
  4. Execute your new task.

Before you begin

Run a PowerShell script on a remote Windows node

First, we’ll use Bolt to run the script as-is on a single target node.

Create a Bolt project directory to work in, called bolt-guide. Copy the [restart_service.ps1](https://gist.github.com/RandomNoun7/03dfb910e5d93fefaae6e6c2da625c44#file-restart_service-ps1) script into bolt-guide. In the bolt-guide directory, run the restart_service.ps1 script with the following command:

bolt script run .\restart_service.ps1 service=W32Time --nodes winrm://uia27aaq2e10fa6 -u Administrator -p 

Note: The -p option prompts you to enter a password.

By running this command, you’ve brought your script under Bolt control and have run it on a remote node. When you ran your script with Bolt, the script was transferred into a temporary directory on the remote node, it ran on that node, and then it was deleted from the node.

Create an inventory file to store information about your nodes

To run Bolt commands against multiple nodes at once, you need to provide information about the environment by creating an inventory file. The inventory file is a YAML file that contains a list of target nodes and node specific data.

  1. Inside the `bolt-guide` directory, use a text editor to create an `inventory.yaml` file.
  2. Inside the new `inventory.yaml` file, add the following content, listing the fully qualified domain names of the target nodes you want to run the script on, and replacing the credentials in the `winrm` section with those appropriate for your node:
~~~ groups: - name: windows nodes: - - config: transport: winrm winrm: user: Administrator Password: config: transport: winrm winrm: user: Administrator Password: ~~~ To have Bolt securely prompt for a password, use the `--password` or `-p` flag without supplying any value. Bolt then prompts for the password, so that it does not appear in a process listing or on the console. Alternatively you can use the `prompt` plugin to set configuration values via a prompt. You now have an inventory file where you can store information about your nodes. You can also configure a variety of options for Bolt in bolt.yaml file, including global and transport options. For more information, see [Bolt configuration options](https://puppet.com/docs/bolt/latest/bolt_configuration_options.html). For more information about configuring Bolt to use WinRM, see [WinRM transport configuration options](https://puppet.com/docs/bolt/1.x/bolt_configuration_options.html#winrm-transport-configuration-options).

Convert your script to a Bolt task

To convert the restart_service.ps1 script to a task, giving you the ability to reuse and share it, you create a task metadata file. Task metadata files describe task parameters, validate input, and control how the task runner executes the task.

Note: This guide shows you how to convert the script to a task by manually creating the .ps1 file in a directory called tasks. Alternatively, you can use Puppet Development Kit (PDK), to create a new task by using the [pdk new task command](https://puppet.com/docs/pdk/1.x/pdk_reference.html#pdk-new-task-command). If you’re going to be creating a lot of tasks, PDK is worth getting to know. For more information, see the PDK documentation.

  1. In the bolt-guide directory, create the following subdirectories:
  2. ~~~ bolt-guide/ └── modules └── gsg └── tasks ~~~
  3. Move the `restart_service.ps1` script into the `tasks` directory.
  4. In the `tasks` directory, use your text editor to create a task metadata file — named after the script, but with a `.json` extension, in this example, `restart_service.json`.
  5. Add the following content to the new task metadata file:
  6. ~~~ { "puppet_task_version": 1, "supports_noop": false, "description": "Stop or restart a service or list of services on a node.", "parameters": { "service": { "description": "The name of the service, or a list of service names to stop.", "type": "Variant[Array[String],String]" }, "norestart": { "description": "Immediately restart the services after start.", "type": "Optional[Boolean]" } } } ~~~
  7. Save the task metadata file and navigate back to the `bolt-guide` directory.
  8. You now have two files in the `gsg` module’s `tasks` directory: `restart_service.ps1` and `restart_service.json` -- the script is officially converted to a Bolt task. Now that it’s converted, you no longer need to specify the file extension when you call it from a Bolt command.
  9. To validate that Bolt recognizes the script as a task, run the following command:
bolt task show gsg::restart_service

Congratulations! You’ve successfully converted the restart_service.ps1 script to a Bolt task.

Execute your new task

To execute your new task, run the following command:

bolt task run gsg::restart_service service=W32Time --nodes windows

Note: --nodes windows refers to the name of the group of target nodes that you specified in your inventory file. For more information, see Specify target nodes.

That’s it! You now have an automated workflow for restarting a service on-demand on multiple target nodes. You can use this same workflow run your other PowerShell scripts on an inventory of remote nodes.

For more information about the commands you used in this guide, see the Bolt command reference.

Next steps

As mentioned at the start of this blog post, if you want to take this automation framework further, you can combine multiple tasks into a Bolt plan. Plans give you the ability to create multi-server workflows involving multiple tasks and Puppet code.

Bolt is a great place to start your automation journey, but if you have a large organization spanning multiple teams, Puppet Enterprise gives you more control over and insight into the automation of your infrastructure, and provides a flexible combined agentless and agent-based approach.

Thanks for reading! Let us know how you use Bolt.

Claire Cadman is a technical writer at Puppet.

Learn more

Puppet sites use proprietary and third-party cookies. By using our sites, you agree to our cookie policy.