Skip to main content

Create Table

Data Manipulation

Synopsis

Allocates the named virtual table's backing struct on the entry so $<table>.Field paths — in set, rename, if: conditions, and any other field-path-aware processor — have a typed location to write into. Idempotent: calling it again on a table that already exists leaves the table, and its current contents, untouched.

Schema

- create_table:
name: <string>
from_map: <boolean>
description: <text>
if: <script>
tag: <string>
disabled: <boolean>
ignore_failure: <boolean>
on_failure: <processor[]>
on_success: <processor[]>

Configuration

FieldRequiredDefaultDescription
nameYTable to allocate. Must be one of the 12 registered virtual tables (see Details), matched case-insensitively. Supports templating, e.g. name: "{{table}}".
from_mapNfalseCopies each Map key into the matching column of the table, coercing values to the column's type; keys with no matching column are dropped, and Map itself is left unchanged. Runs whenever Map is non-empty, whether the table was just allocated or already existed — repeating create_table with from_map: true re-copies Map into the table each time.
descriptionNExplanatory note.
ifNCondition that must be true for the processor to run.
tagNIdentifier for this processor instance.
disabledNfalseWhen true, the processor is skipped.
ignore_failureNfalseContinue pipeline processing if the processor fails.
on_failureNSee Handling Failures.
on_successNSee Handling Success.

Details

Virtual Tables

A virtual table is an optional, strongly typed struct an entry can carry alongside its normal untyped Map. Nothing about it is automatic: a table exists on an entry only after create_table runs, a field lands in it only when a processor writes through an explicit $<table>.Field path (set's field, rename's target_field, if: conditions, and every other field-path-aware processor), and the entry marshals from it only after Use Table selects it. The untyped Map always keeps existing alongside any table — writing to $<table>.Field never touches Map, and a bare field name (Facility) always targets Map, even when a table with a same-named column is allocated on the same entry.

The 12 registered tables are Microsoft Sentinel schemas: Syslog, CommonSecurityLog, ASimAuditEventLogs, ASimAuthenticationEventLogs, ASimDhcpEventLogs, ASimDnsActivityLogs, ASimFileEventLogs, ASimNetworkSessionLogs, ASimProcessEventLogs, ASimRegistryEventLogs, ASimUserManagementActivityLogs, ASimWebSessionLogs. name matches any of these case-insensitively.

Multiple tables may be allocated on the same entry at once — create_table for Syslog and create_table for CommonSecurityLog in the same pipeline coexist independently, each addressed by its own $<table>. prefix.

create_table Specifically

create_table only allocates the table's backing struct. It does not select the table as the output source — Use Table does that — and it does not write any fields into it; set, rename, and other field-path-aware processors do that, via $<table>.Field.

Calling create_table on a table that already exists on the entry is a no-op for the table's existing contents — its current values and presence bits are left exactly as they were.

from_map exists to make a create_table-first pipeline work both as a direct ingestion target and as a sub-pipeline. On direct ingestion, typed ingestion decodes the incoming message straight into the table and Map starts empty, so the copy loop has nothing to do. When the same pipeline instead runs as a sub-pipeline, the parent has already parsed the record into Map (the table itself is still empty), so from_map: true copies the matching columns across on creation, letting $<table>.Field conditions resolve either way.

name must resolve to one of the 12 registered tables. Any other value fails the processor with unknown virtual table: "<name>"; set ignore_failure: true to treat that as a soft skip instead.

Examples

Allocating a Table Before Writing Into It

Allocating Syslog before a set step writes into it...

{
"message": "<34>1 2026-07-14T09:12:00Z host1 sshd - - Failed password for invalid user"
}
- create_table:
name: Syslog
- set:
field: $syslog.SyslogMessage
value: "{{{message}}}"
- use_table:
name: Syslog

The table exists so the set step has somewhere to write; selecting it with use_table is what makes the write visible in the shipped output — see Use Table...

{
"SyslogMessage": "<34>1 2026-07-14T09:12:00Z host1 sshd - - Failed password for invalid user"
}

Idempotent Re-creation

Calling create_table a second time on the same table, after a value has already been written...

{}
- create_table:
name: Syslog
- set:
field: $syslog.SyslogMessage
value: "first line"
- create_table:
name: Syslog
- use_table:
name: Syslog

The second call is a no-op — the table's existing contents are left untouched...

{
"SyslogMessage": "first line"
}

Hydrating a Table From Map with from_map

A sub-pipeline receives a record its parent already parsed into Map. from_map: true copies each matching column across on allocation...

{
"SyslogMessage": "hello from sub-pipeline",
"ProcessID": "4821",
"unrelated": "dropped"
}
- create_table:
name: Syslog
from_map: true
- use_table:
name: Syslog

ProcessID coerces from a string to the column's int type; unrelated has no matching column and is dropped. Map itself is left with all three keys — that only becomes invisible once use_table selects the table as the output...

{
"SyslogMessage": "hello from sub-pipeline",
"ProcessID": 4821
}

Failing on an Unknown Table Name

Naming a table that isn't one of the 12 registered schemas...

{}
- create_table:
name: Frobnicate
ignore_failure: true

Frobnicate isn't a registered table, so the processor fails; ignore_failure lets the event continue with no table allocated...

{}