← Back to list

SIF: Teaching JSON to Think — Skip, Requires, Validate, and ConfigFunctions Magic

Beyond Basics: Adding Intelligence and Validation to SIF Configurations

Sergey Solomentsev · 2025-11-04 17:53 · 0 claps · 7.0 min read
#sitecore #sitecore-tips #automation #learning-sitecore #sif-tutorial
Open on Medium ↗
Wiki topics: EDU · Education & Learning

SIF: Teaching JSON to Think — Skip, Requires, Validate, and ConfigFunctions Magic

Introduction

If you’ve been following this series, you already know that Sitecore Installation Framework (SIF) is much more than “just another installer.” Over the past articles, we’ve explored how SIF can structure, extend, and automate complex deployments with surprising elegance.

Here’s a quick recap in case you missed any:

So, what’s next?

Now that SIF can execute your custom logic, it’s time to teach it to think.

In this chapter, we’ll look at:

  • how to skip tasks that don’t meet specific conditions,
  • how to make tasks conditional with the Requires property,
  • how to make parameters self-validating with Validate,
  • and how to bring real PowerShell logic into JSON through ConfigFunctions — your new secret weapon for “smart automation.”

By the end, your JSON files won’t just run tasks — they’ll start making decisions.

Automation becomes powerful only when it starts to think.

🚦 The “Skip” Property — Skipping Tasks Gracefully

Not every task needs to run every time. Sometimes a step is only required on a fresh environment, or maybe it should be skipped entirely if something already exists.

That’s where the **Skip* property comes in. It tells SIF: “If this condition is true, don’t bother running this task.”*

Here’s a simple example:

{
  "Tasks": {
    "CreateSiteFolder": {
      "Type": "mkdir",
      "Params": {
        "Path": "C:\\inetpub\\wwwroot\\MySite"
      },
      "Skip": "[TestPath('C:\\inetpub\\wwwroot\\MySite')]"
    }
  },
  "Settings": {
    "AutoRegisterExtensions": true
  }
}

In plain English: “If this folder already exists — skip the task.”

That’s it. No errors, no warnings, no wasted effort — just a clean, conditional skip.

💡 When to Use Skip

Skip is great for idempotent installs and uninstalls, where running the same configuration multiple times should not break anything. You can think of it as a lightweight guard — a way to make your SIF scripts safe to re-run without destroying or duplicating resources.

🧠 How It Works

You can use ConfigFunctions inside Skip (we’ll cover them later in this article). These functions let you embed real PowerShell logic inside JSON conditions — so your “skip logic” can be as simple or as smart as you want.

"Skip": "[equal(parameter('DEPLOY_ENV'), 'Dev')]"

This example tells SIF to skip the task entirely when running in a Dev environment.

🧩 The “Requires” Property — Handling Prerequisites Interactively

Sometimes skipping a task isn’t enough. There are cases when a task simply cannot run until specific prerequisites are met — for example, when a required file doesn’t exist or a service isn’t installed.

That’s exactly what the **Requires property is for. It allows you to define prerequisite checks** that must pass before the task is executed.

🧠 How It Works

The Requires block is placed inside a task and contains one or more Config Functions that return a boolean ($true or $false).

These checks are performed after the Skip section. If a Requires condition returns $false, the task doesn’t start — instead, SIF opens an interactive PowerShell shell inside the current host.

This isn’t an error. The shell is a way to fix the problem manually before continuing. Inside it, you can run any PowerShell commands you need — install a missing module, copy a file, restart a service, or anything else. Once done, type:

exit

SIF will recheck all Requires conditions, and if they now return $true, the task will proceed. If they still return $false, the shell opens again, giving you another chance to resolve the issue.

⏭️Skipping the requirement

If you decide to bypass the requirement and continue the installation, you can type:

SkipRequire

This command closes the interactive shell and tells SIF to skip only the requirement check, not the entire task. The task will then continue to run as if the condition had passed successfully.

👉 The key difference from Skip

The main difference between Skip and Requires lies in what happens when the condition fails.

  • Skip silently omits a task when its condition is false.
  • Requires interrupts execution and gives you an interactive opportunity to fix the problem before continuing.

In other words, Skip says “don’t run this,” while Requires says “you must fix this before running.”

⚠️ A word of caution

The Requires property should be used with care. In CI/CD environments like Azure DevOps, GitHub Actions, or TeamCity, there’s no way to type into an interactive shell — which means if a Requires condition fails, the entire process will hang indefinitely waiting for input.

That’s why Requires is mainly suitable for development-time installations, when you can interact directly with SIF. Even then, it’s a good idea to inform the user about what’s happening and what they need to do — otherwise, the unexpected shell prompt can be confusing or alarming.

💡 Example

Here’s a simple example of how Requires can be used to check that a license file exists before continuing:

{
  "Tasks": {
    "CheckLicense": {
      "Type": "Check-SitecoreLicense",
      "Params": {
        "Path": "variable('SitecoreLicense')"
      },
      "Requires": "[testpath(variable('SitecoreLicense'))]"
    }
  }
}

In this example, the task won’t run until the specified license file is found. If it’s missing, SIF opens an interactive shell, allowing you to copy or create the file and then type exit to retry.

🛡️ The “Validate” Property — Teaching Parameters to Protect Themselves

If Requires gives tasks the power to decide whether to run, then Validate gives parameters the ability to defend themselves before the process even starts.

The Validate property lets you define rules that check whether a parameter’s value is acceptable — long before it’s used by a task. Think of it as a small firewall for your configuration: if something looks wrong, SIF will stop and let you know exactly what failed and why.

🧠 How it works

Each parameter in your JSON file can include a Validate array that contains one or more validation rules. These rules define what kind of check should be performed.

{
  "Parameters": {
    "AdminUsername": {
      "Type": "string",
      "DefaultValue": "admin",
      "Validate": "[and(ValidateNotNullOrEmpty(parameter('AdminUsername')), ValidatePattern('^[a-zA-Z0-9]+$', parameter('AdminUsername')))]"
    }
  },
  "Settings": {
    "AutoRegisterExtensions": true
  },
  "Tasks": {
    "Say": {
      "Type": "WriteOutput",
      "Params": {
        "InputObject": "[parameter('AdminUsername')]"
      }
    }
  }
}

In this example, SIF will ensure:

  1. The value is not empty, and
  2. It matches the allowed pattern (a–z, A–Z, 0–9 only).

If either check fails, the installation will stop and show the corresponding error message.

💡Why this matters

Parameters are often defined once and reused across dozens of tasks. If an incorrect value slips through, it might break the process much later — sometimes halfway through a 15-minute install.

Validate helps you catch problems early, right where they originate. It turns your JSON into a self-checking system that protects itself before something goes wrong.

⚙️ Writing Your Own ConfigFunction — Giving JSON Real Logic

So far, we’ve seen how Skip, Requires, and Validate allow SIF to react to conditions — but where do those conditions come from?

That’s where ConfigFunctions enter the scene. They’re the real brain cells behind SIF’s “smart JSON.” Whenever you write something like [testpath('C:\\inetpub\\wwwroot')] or [ValidateNotNullOrEmpty(...)], you’re actually calling a PowerShell function that was registered as a ConfigFunction.

🧩 Creating your own ConfigFunction

Creating a new ConfigFunction feels almost the same as writing a custom task — you define a PowerShell function, then register it with SIF.

Here’s a simple example:

// file C:\SIF\Custom.SIF.ConfigFunctions.psm1
function Test-IsEven {
    param($value)
    return ($value % 2 -eq 0)
}

Register-SitecoreInstallExtension -Command Test-IsEven -As IsEven -Type ConfigFunction

Now you can use your new logic directly inside a JSON file:

{
  "Parameters": {
    "Number": {
      "Type": "Int32",
      "DefaultValue": 4
    }
  },
  "Tasks": {
    "EvenCheck": {
      "Type": "WriteHost",
      "Params": {
        "Message": "Even number confirmed!"
      },
      "Skip": "[not(IsEven(parameter('Number')))]"
    }
  },
  "Modules": [
    "C:\\SIF\\Custom.SIF.ConfigFunctions.psm1"
  ],
  "Settings": {
    "AutoRegisterExtensions": true
  }
}

This tells SIF to skip the task if the number is not even. It’s a trivial example, but it shows the power: your JSON can now execute your own PowerShell logic.

🔌 Using existing PowerShell functions as ConfigFunctions

You don’t always have to reinvent the wheel. Any existing PowerShell function can be registered as a ConfigFunction — even those from other modules.

For instance, let’s consider the Carbon library that we installed in the previous articles:

{
  "Modules": [
    "~\\Documents\\PowerShell\\Modules\\Carbon\\2.15.1\\Carbon.psm1"
  ],
  "Register": {
    "ConfigFunction": {
      "Is64Bit": "Test-OSIs64Bit"
    }
  },
  "Tasks": {
    "InstallLogger": {
      "Type": "WriteHost",
      "Params": {
        "Message": "Installing logger x64"
      },
      "Skip": "[not(Is64Bit())]"
    }
  },
  "Settings": {
    "AutoRegisterExtensions": true
  }
}

That’s it — your SIF configuration can now access the entire Carbon ecosystem.

ConfigFunctions are the foundation of SIF’s intelligence. They make features like Skip, Requires, and Validate possible, and they let you extend JSON logic far beyond static configuration.

🧭 Summary

Config Functions are a powerful way to embed logic and flexibility directly into your JSON. They enable you to compute parameter values, evaluate conditions, access external data, and even influence task behavior — without the need to write a new Task. Creating and debugging a ConfigFunction is nearly identical to working with custom tasks, making the process intuitively familiar. You can register functions from other modules and build your own reusable libraries.

🎯 Mini Challenge

Try creating a ConfigFunction that returns true if a specific version of .NET is installed on the system, and use it in the Requires property.

Tip: use Get-Command and Select-String to check the version.

Simplicity is the ultimate sophistication.


메타데이터
post_id
62700b8a124c
slug
sif-teaching-json-to-think-skip-requires-validate-and-configfunctions-magic-62700b8a124c
url
https://medium.com/@serg-at/sif-teaching-json-to-think-skip-requires-validate-and-configfunctions-magic-62700b8a124c
canonical_url
https://medium.com/@serg-at/sif-teaching-json-to-think-skip-requires-validate-and-configfunctions-magic-62700b8a124c
author_url
https://medium.com/@serg-at
status
ok
fetched_at
2026-06-15 20:49:54