Skip to content

Set PowerBrick Parameters Dynamically

A value you type into a PowerBrick parameter is applied unchanged to every device the package runs on. When devices need different values — depending on location, model, serial number, or what’s already installed — you can calculate the value on the device instead. One package then covers every variant, and you don’t have to maintain one package per site or model.

The pattern has two parts:

  1. An Execute PowerShell Snippet brick works out the value and stores it in a global variable, for example $global:WifiProfilePath.
  2. A later brick in the same sequence uses that variable as its parameter value.

The pattern works with any PowerBrick.

CapaOne combines all the bricks in an Install sequence into one PowerShell script and runs them in order, in the same PowerShell session. A global variable that one brick sets is still there when the next brick runs. The Uninstall sequence is a separate script, so a variable set during Install isn’t available during Uninstall.

Each snippet runs inside its own PowerShell function. Use the $global: prefix every time you set the variable — a variable without it is gone as soon as the snippet ends.

You can use a variable in any parameter where you type free text, such as a path, name, or value field. CapaOne writes the parameter value into the script in double quotes, so PowerShell replaces the variable with its value when the brick runs.

A variable doesn’t work in these parameter types:

  • On/off switches — the value is always on or off.
  • Number fields — the field accepts digits only.
  • Drop-down lists — you can only pick one of the listed values.
  • Password fields — the text you type is encoded and passed to the brick as it is, so a variable name is never replaced with its value. Type the password directly in the field.

Type the variable name on its own, for example $global:MsiPath. These forms aren’t replaced with a value:

  • A property or index, such as $global:Device.Name or $global:Paths[0]. Store the exact value in its own variable in the snippet instead.
  • A subexpression or braces, such as $($global:MsiPath) or ${global:MsiPath}.

You can combine a variable with fixed text, for example $global:SiteFolder\Setup.msi.

  1. Open the Script or Company App and go to the PowerBricks editor.
  2. Add an Execute PowerShell Snippet brick to the sequence.
  3. In PowerShell Snippet, write the logic and assign the result to a global variable. If the snippet can’t find a value for the device, stop the package with Exit-PSScript so the log shows why.
  4. Add the brick that needs the value below the snippet. Bricks run from top to bottom, so the snippet must come first.
  5. In the parameter that should get the value, type the variable name exactly as you set it, for example $global:WifiProfilePath.
  6. Save the package.

When the package runs, the later brick receives the value the snippet calculated on that device.

The snippet has the full CapaSystems PowerShell Scripting Library ($cs.* helpers) and the PowerPack global variables. Files you upload to the package are in the folder $Packageroot. Add the Download Content brick before the snippet if the snippet or a later brick uses those files.

One package deploys the right Wi-Fi profile to devices at three offices. Each office has its own exported profile file, and the office is identified by the first letters of the computer name.

  1. Create a Script and upload the three profile files: Copenhagen.xml, Aarhus.xml, and Odense.xml.

  2. Add a Download Content brick to the Install sequence.

  3. Add an Execute PowerShell Snippet brick below it, with this code:

    Terminal window
    # Map the computer name prefix to the office profile file
    switch -Wildcard ($env:COMPUTERNAME) {
    'CPH-*' { $global:WifiSite = 'Copenhagen' }
    'AAR-*' { $global:WifiSite = 'Aarhus' }
    'ODE-*' { $global:WifiSite = 'Odense' }
    }
    if ([string]::IsNullOrWhiteSpace($global:WifiSite)) {
    Exit-PSScript -exitcode 1 -exitmessage "No Wi-Fi profile is defined for device $env:COMPUTERNAME."
    }
    $global:WifiProfilePath = "$Packageroot\$global:WifiSite.xml"
    $cs.Job_WriteLog("Selected Wi-Fi profile: $global:WifiProfilePath")
  4. Add an Import Wifi Profile brick below the snippet.

  5. In Profile File Path, replace the default value with $global:WifiProfilePath.

  6. Save the Script and assign it to the devices.

Order PowerBrick Parameter value
1 Download Content —
2 Execute PowerShell Snippet The code above
3 Import Wifi Profile Profile File Path: $global:WifiProfilePath

Each device imports the profile for its own office. A device whose name doesn’t match a prefix stops with exit code 1, and the log names the device. To support a new office, upload its profile file and add one line to the switch block.

One domain-join package places each computer in the organizational unit (OU) for its site. The site is identified by the IP address the device has on the local network.

  1. Add an Execute PowerShell Snippet brick to the Install sequence, with this code:

    Terminal window
    # Find the IPv4 address on the adapter that has a default gateway
    $IpAddress = (Get-NetIPConfiguration |
    Where-Object { $_.IPv4DefaultGateway } |
    Select-Object -First 1).IPv4Address.IPAddress
    switch -Wildcard ($IpAddress) {
    '10.1.*' { $global:DomainOU = 'OU=Copenhagen,OU=Computers,DC=contoso,DC=local' }
    '10.2.*' { $global:DomainOU = 'OU=Aarhus,OU=Computers,DC=contoso,DC=local' }
    }
    if ([string]::IsNullOrWhiteSpace($global:DomainOU)) {
    Exit-PSScript -exitcode 1 -exitmessage "No OU is defined for IP address $IpAddress."
    }
    $cs.Job_WriteLog("Selected OU: $global:DomainOU")
  2. Add a Join Domain brick below the snippet.

  3. Fill in the domain account, Password, Domain Name, and Preferred Domain Controller as usual.

  4. In OU Path, type $global:DomainOU.

Order PowerBrick Parameter value
1 Execute PowerShell Snippet The code above
2 Join Domain OU Path: $global:DomainOU

Each computer object is created in the OU for the site the device is on when the package runs.

Install the MSI that matches the processor architecture

Section titled “Install the MSI that matches the processor architecture”

One Company App installs the 64-bit MSI on 64-bit Windows and the 32-bit MSI on 32-bit Windows.

  1. Create a Company App and upload both installers: Setup-x64.msi and Setup-x86.msi.

  2. Add a Download Content brick to the Install sequence.

  3. Add an Execute PowerShell Snippet brick below it, with this code:

    Terminal window
    if ([Environment]::Is64BitOperatingSystem) {
    $global:MsiPath = "$Packageroot\Setup-x64.msi"
    } else {
    $global:MsiPath = "$Packageroot\Setup-x86.msi"
    }
    $cs.Job_WriteLog("Selected installer: $global:MsiPath")
  4. Add an Install MSI brick below the snippet.

  5. In MSI Path, replace the default value with $global:MsiPath.

Order PowerBrick Parameter value
1 Download Content —
2 Execute PowerShell Snippet The code above
3 Install MSI MSI Path: $global:MsiPath

Write the department to the registry from an asset list

Section titled “Write the department to the registry from an asset list”

One package writes each device’s department to the registry, so other tools and scripts can read it. The department comes from a CSV file that maps serial numbers to departments.

  1. Create a Script and upload Assets.csv with the columns SerialNumber and Department:

    SerialNumber,Department
    5CD1234ABC,Finance
    5CD5678DEF,Sales
  2. Add a Download Content brick to the Install sequence.

  3. Add an Execute PowerShell Snippet brick below it, with this code:

    Terminal window
    $SerialNumber = (Get-CimInstance -ClassName Win32_BIOS).SerialNumber.Trim()
    $Asset = Import-Csv -Path "$Packageroot\Assets.csv" |
    Where-Object { $_.SerialNumber -eq $SerialNumber }
    if (-not $Asset) {
    Exit-PSScript -exitcode 1 -exitmessage "Serial number $SerialNumber is not in Assets.csv."
    }
    $global:Department = $Asset.Department
    $cs.Job_WriteLog("Department for $SerialNumber`: $global:Department")
  4. Add a Set Registry Value brick below the snippet, with these values:

    • Registry Hive: HKEY_LOCAL_MACHINE
    • Registry Variable Type: String
    • Registry Key: SOFTWARE\Contoso\Asset
    • Registry Variable Name: Department
    • Registry Variable Value: $global:Department
Order PowerBrick Parameter value
1 Download Content —
2 Execute PowerShell Snippet The code above
3 Set Registry Value Registry Variable Value: $global:Department

When a device changes department, update Assets.csv in the package and redeploy it.