On an Update, the Target entity in the context only contains the fields that were actually changed by whatever triggered the update — not the record’s full current state. If your plugin needs to know a field’s previous value, or needs to read a field that wasn’t part of this particular update, the Target alone won’t have it. That’s what images solve.

Pre-Image

A snapshot of the record’s state before this operation applied its changes. Registered on the plugin step itself (in the Plugin Registration Tool), specifying exactly which columns to include. Available at Pre-operation and Post-operation stages.

Post-Image

A snapshot of the record’s state after the operation has applied its changes — only available at Post-operation, since the “after” state doesn’t exist yet any earlier in the pipeline.

A concrete example

Say you need to detect specifically when an Opportunity’s Status changes to “Won” (not just that an update happened). The Target might only contain statuscode if that’s the only field the user changed — but you need to compare it against what it was before:

Entity preImage = context.PreEntityImages.Contains("PreImage")
    ? context.PreEntityImages["PreImage"]
    : null;

var newStatus = target.GetAttributeValue<OptionSetValue>("statuscode");
var oldStatus = preImage?.GetAttributeValue<OptionSetValue>("statuscode");

bool justWon = newStatus?.Value == 3 && oldStatus?.Value != 3;
Only register the columns you actually need. Images are configured per-step to include a specific set of columns, not automatically the whole record. Requesting every column “just in case” adds unnecessary overhead and makes the step harder to reason about later — be deliberate about exactly which fields a given plugin step’s image needs.