capture powershell variable from step output and pass it to next step

488 views
Skip to first unread message

mezam

unread,
Jan 8, 2023, 2:08:59 PM1/8/23
to rundeck-discuss
Hello,

I'm trying to capture a PowerShell script output (a PS array) in a step, and pass it to step2 for more work. Here below my job definition. As per another thread I'm using the multi regex plugin, but unsuccessful so far. Nothing is being captured. I'd like to understand how this works. If it is a simple string a standard key/value filter works fine. But if a script outputs a variable $report, what is it that I have to capture? The variable name or the content of it? In this case we need the whole content of it. 

  <joblist>
  <job>
    <context>
      <options preserveOrder='true'>
        <option enforcedvalues='true' name='ciList' required='true' values='First,Fourth,Last,TEST,Third' valuesListDelimiter=','>
          <label>Select the servers list</label>
        </option>
      </options>
    </context>
    <defaultTab>nodes</defaultTab>
    <description><![CDATA[This job checks each server in the selected list for its last reboot time:

- user is prompted to select a specific batch name (equivalent to a list of servers)
- the script checks on each server of the selected list for its last reboot time (step1)
- writes output to a json file and lay it in an Apache web server directory (where a JS script will parse and render) (Step2) ]]></description>
    <dispatch>
      <excludePrecedence>true</excludePrecedence>
      <keepgoing>true</keepgoing>
      <rankOrder>ascending</rankOrder>
      <successOnEmptyNodeFilter>true</successOnEmptyNodeFilter>
      <threadcount>1</threadcount>
    </dispatch>
    <executionEnabled>true</executionEnabled>
    <group>Operations</group>
    <id>76b79511-1346-4ab5-9d1b-27c3cf45220b</id>
    <loglevel>INFO</loglevel>
    <name>Servers Last Reboot Test</name>
    <nodeFilterEditable>false</nodeFilterEditable>
    <nodefilters>
      <filter>tags: Roll</filter>
    </nodefilters>
    <nodesSelectedByDefault>true</nodesSelectedByDefault>
    <plugins />
    <scheduleEnabled>true</scheduleEnabled>
    <sequence keepgoing='false' strategy='node-first'>
      <command>
        <description>Gathering Server Last Reboot Time</description>
        <fileExtension>ps1</fileExtension>
        <plugins />
        <script><![CDATA[

$report = @()
$dump = "" | Select-Object 'ServerName', "LastBoot"
$dump.ServerName = [System.Net.Dns]::GetHostByName($env:computername).HostName
$dump.LastBoot = Get-CimInstance -ClassName win32_operatingsystem | Select-Object -expandproperty lastbootuptime
$report += $dump
$report]]></script>
        <scriptargs />
        <scriptinterpreter>PowerShell</scriptinterpreter>
      </command>
      <command>
        <description>Receiving Data from Servers</description>
        <fileExtension>ps1</fileExtension>
        <script><![CDATA[# print the data values
Write-Host "Testing the data value..."
Write-Host "@data.report@"]]></script>
        <scriptargs>${data.report}</scriptargs>
        <scriptinterpreter>PowerShell</scriptinterpreter>
      </command>
      <pluginConfig>
        <LogFilter type='key-value-data-multilines'>
          <config>
            <captureMultipleKeysValues>true</captureMultipleKeysValues>
            <hideOutput>false</hideOutput>
            <logData>true</logData>
            <name>report</name>
            <regex>.*report(.*).*</regex>
          </config>
        </LogFilter>
      </pluginConfig>
    </sequence>
    <uuid>76b79511-1346-4ab5-9d1b-27c3cf45220b</uuid>
  </job>
</joblist>

rac...@rundeck.com

unread,
Jan 9, 2023, 7:38:31 AM1/9/23
to rundeck-discuss
Hi Mezam,

Take a look at this Windows/PS example.

Regards.

mezam

unread,
Jan 9, 2023, 9:41:45 AM1/9/23
to rundeck-discuss
Many thanks, I've already looked at that (and many others actually), but it does not work in my case. That example is for a string, I've tried it and it works (with a string output). In my case I need to capture and array object. When I use that example the variable is not captured. That is why I was asking, if a script outputs a variable $report (which contains an array), what is it that I have to capture? The variable name or?

rac...@rundeck.com

unread,
Jan 9, 2023, 10:39:14 AM1/9/23
to rundeck-discuss

Hi Mezam,

In any case the Log Output filters just generates a ${data.xxx} based on the result of your step/script (and that is the variable that you need on the next steps), that variable name is defined in the Data Capture “Name Data” textbox. If you want to use it on inline-script use the @data.xxx@ format.

So, it works in the following way: the command/script generates a result, then the filter gets that result and save it on a ${data.xxx} variable.

I made an basic example that I tested locally. Just a tip: If you want to capture a data step, the best way is to “attach” the filter on the step (not globally).Check the example:

ultTab: nodes
  description: ''
  executionEnabled: true
  id: 76b79511-1346-4ab5-9d1b-27c3cf45220b
  loglevel: INFO
  name: Servers Last Reboot Test
  nodeFilterEditable: false
  plugins:
    ExecutionLifecycle: null
  scheduleEnabled: true
  sequence:
    commands:
    - description: Gathering Server Last Reboot Time
      fileExtension: .ps1
      interpreterArgsQuoted: false
      plugins:
        LogFilter:
        - config:
            captureMultipleKeysValues: 'true'
            hideOutput: 'false'
            logData: 'true'
            name: myreport
            regex: (.*)
          type: key-value-data-multilines
      script: |
        $report = @()
        $dump = "" | Select-Object 'ServerName', "LastBoot"
        $dump.ServerName = [System.Net.Dns]::GetHostByName($env:computername).HostName
        $dump.LastBoot = Get-CimInstance -ClassName win32_operatingsystem | Select-Object -expandproperty lastbootuptime
        $report += $dump
        $report
      scriptInterpreter: powershell.exe
    - fileExtension: .ps1
      interpreterArgsQuoted: false
      script: echo "@data.myreport@"
      scriptInterpreter: powershell.exe
    keepgoing: false
    strategy: node-first
  uuid: 76b79511-1346-4ab5-9d1b-27c3cf45220b

Check the result.

Also, I made some changes in my example (I used the “powershell.exe” interpreter instead of “PowerShell”, “.ps1” instead of Ps1).

You can see more complex/interesting Multiline Data Capture Pilter plugin examples here.

Hope it helps!

mezam

unread,
Jan 9, 2023, 12:08:53 PM1/9/23
to rundeck-discuss
it definitely did help, many thanks! The problem was the regex. But it is weird, in regex101 site my regex:

.*report(.*).*

did match the @data.report@ variable. While your regex:   

(.*) 

grabs everything. And it works!
Thanks again!

rac...@rundeck.com

unread,
Jan 9, 2023, 12:22:56 PM1/9/23
to rundeck-discuss
Awesome Mezam! Happy to help!
Reply all
Reply to author
Forward
0 new messages