Skip to content

adrian1703/powershell-execmanager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

96 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PSCmdManager

PSCmdManager is a PowerShell-based tool designed to manage serialized workflows using a YAML configuration. It provides a modular and repeatable approach to execute tasks and actions, making it ideal for tasks like automating software installations, system setups, or other deterministic workflows.

Motivation

I primarily use GitBash on my Windows PC. However, when trying to formalize a repeatable setup of my development environment, I ran into the issue of the silent flag apparently that rarely works with GitBash. So I continued my work using PowerShell which eventually lead to the creation of this Module.

The module uses YAML files to define tasks and actions, which are executed in a serialized manner. Each task can consist of multiple actions, allowing for configurable and repeatable workflows. It includes predefined functions for downloading files (Invoke-Download) and executing installers (Invoke-Exe) but can be extended with custom commands.

A primary use case for my development was the fresh and repeatable setup of environments, such as installing software on a new machine or configuring a system.


Installation from Gallery

Install-Module -Name PSCmdManager

Features

  • YAML Configuration: Define tasks, actions, and reusable defaults for a flexible setup.
  • Predefined Actions: Comes with built-in functions:
    • Invoke-Download: For downloading files from the internet.
    • Invoke-Exe: For executing installer files with arguments.
  • Serialized Execution:
    • Tasks are executed in order.
    • Actions within a task are executed sequentially.
  • Environment Variables Support: Incorporate dynamic values (e.g., file paths, user environment variables) using ${} syntax in the YAML file. These placeholders are automatically resolved to their current environment variable values at runtime. Define temporary environment variables for the specific execution context in the config YAML.
  • Dry-Run Mode: Simulate the execution without performing actual actions, useful for testing configurations.
  • Repeatable Workflows: Reuse the YAML configuration for consistent and repeatable task executions.
  • (untested) Recursive Workflows: It should be possible to call Start-RunAllTasks from within Start-RunAllTasks.
  • (soon) Implicit Command Invokation Support: Omit the definition process of actions and invoke any command your powershell is equipped with.
  • (soon) Schema Verification: Add a command to verify schema validity

Structure

This project consists of the following critical components:

1. Core Functions

The following functions are used to drive task execution and workflows:

Function Description
Start-RunAllTasks Executes all tasks defined in the YAML configuration.
Start-RunTaskAllActions Executes all actions for a specified task.
Start-RunTaskAction Executes a single action for a specific task.
Invoke-Download Downloads files using a URL.
Invoke-Exe Runs executable files with specified arguments.

2. YAML Configuration

The YAML file defines the schema, tasks, actions, and default configurations for all operations. Example sections include:

  • Actions: Specify reusable commands like file downloads or application installation.
  • Environment: Place for defining environment variables for the execution context
  • Tasks: Define high-level steps consisting of one or more actions.

Environment Variable Support (Using ${})

The configuration file supports placeholder values in the ${VAR_NAME} format. These placeholders will be dynamically resolved at runtime based on the current system's environment variables.

For example:

schema:
  version: 1
  
action-definitions:
  download:
    definition:
      function: "Invoke-Download"
      args:
        -fileName
        -link
        -downloadFolder
    defaults:
      downloadFolder: "${TMP}"
      
environment:
  - env: "FILENAME"
    val: "file.zip"
    
tasks:
  - name: "ExampleTask"
    actions:
      - name: "Download Example Zip"
        cmd: download
        args:
          fileName: "example.zip"
          link: "https://example.com/${FILENAME}" # Resolves to "https://example.com/file.zip"
          downloadFolder: "${MY_CUSTOM_FOLDER}" # Resolves to the value of $env:MY_CUSTOM_FOLDER

How It Works

  • ${} placeholders in the YAML file map to environment variables (e.g., TMP, USERPROFILE).
  • During task execution, placeholders are expanded to their corresponding environment variable values.
  • If a variable is not set, the process throws an error to alert the user.

Tip: To set custom environment variables, define them before running the tasks:

$env:MY_CUSTOM_FOLDER = "C:\MyCustomPath"

Schema Contraints and undefined behavior

For Version 1 the following invariants need to hold true:

  • any tasks._task.actions._action.type used needs to be defined in action-definitions
  • characters that need escaping such as \ should be avoided. They behave poorly
  • any tasks._task need to be uniquely identifiable by name (within tasks)
  • any tasks._task.actions._action need to be uniquely identifiable by name (within actions)
  • defined environment vars must avoid circular references

Configuration Example

Below is an example of a YAML configuration file (config-example.yaml):

schema:
  version: 1
  
action-definitions:
  download:
    definition:
      function: "Invoke-Download"
      args:
        -fileName
        -link
        -downloadFolder
    defaults:
      downloadFolder: "${TMP}"
  callExe:
    definition:
      function: "Invoke-Exe"
      args:
        -fileName
        -fileLocation
        -execArguments
    defaults:
      fileLocation: "${TMP}"

tasks:
  - name: "Rider"
    description: "Download and install Rider IDE"
    actions:
      - name: "Download Installer"
        type: download
        args:
          fileName: "install.exe"
          link: "https://download.jetbrains.com/rider/JetBrains.Rider-2024.3.4.exe"
      - name: "Run Installer Silently"
        type: callExe
        args:
          fileName: "install.exe"
          execArguments:
              - "/S"
              - "/CONFIG=${SETUP_PROJ}/src/rider/silent.config"
              - "/LOG=${TMP}/rider_install.log"
              - "/D=${IDES}/jetbrains/Rider"

In this example:

  • ${TMP} resolves to the system's temporary directory.
  • ${SETUP_PROJ} and ${IDES} must be defined as environment variables.

Getting Started

1. Installation

Import the module into your PowerShell session:

Import-Module .\PSCmdManager.psd1

2. Prepare YAML Configuration

Create or modify a YAML file to define tasks and actions. Use placeholders like ${TMP} or ${SETUP_PROJ} to customize behavior based on environment variables.

3. Execute Tasks

  • Execute all tasks:
    Start-RunAllTasks -configPath "C:\path\to\your\config.yaml"
  • Dry-run to simulate execution:
    Start-RunAllTasks -configPath "C:\path\to\your\config.yaml" -dry
  • Run a specific task:
    Start-RunTaskAllActions -configPath "C:\path\to\your\config.yaml" -taskName "Rider"
  • Run a specific action of a task:
    Start-RunTaskAction -configPath "C:\path\to\your\config.yaml" -taskName "Rider" -actionName "download"

Dry-Run Mode

Test workflows without executing actions using the -dry flag. This is ideal for:

  • Validating YAML configurations and ensuring correctness.
  • Debugging task and action definitions.

Example:

Start-RunAllTasks -configPath "C:\path\to\config.yaml" -dry

Error Handling

  • Validation: The system validates task and action references, resolving placeholders and ensuring proper configuration before execution.
  • Execution Errors: If an action fails (e.g., download fails, executable not found, unresolved environment variables), the system stops and displays the error for troubleshooting.

Extensibility

(Will probably offer better support for this soon)

PSCmdManager can be extended by adding custom actions to the schema or implementing functions to handle new types of tasks. Use these steps:

  1. Define the new action type in the YAML schema.
  2. Implement the corresponding function in your PowerShell scripts.
  3. Configure the arguments and defaults in your YAML file.

Examples

TBD

Command:

Start-RunTaskAllActions -configPath "Examples/download-and-install.yaml" -taskName "Rider"

Tests

Example for invoking certain tests

Invoke-Pester .\Tests\Unit\
Invoke-Pester .\Tests\Component\
Invoke-Pester .\Tests\Acceptance\

License

This project is licensed under the MIT License.


Author

Created by Adrian Kuhn. If you have questions or issues, please open an issue in the repository.


About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors