diff --git a/.pipelines/PowerShell-Docker-Image-Build-Official.yml b/.pipelines/PowerShell-Docker-Image-Build-Official.yml
index 2272dba3c..9fb0ed9a2 100644
--- a/.pipelines/PowerShell-Docker-Image-Build-Official.yml
+++ b/.pipelines/PowerShell-Docker-Image-Build-Official.yml
@@ -5,6 +5,10 @@ parameters:
   default: 'v7.4.0-preview.5'
 - name: 'releaseChannel'
   default: 'preview'
+- name: 'whatIf'
+  displayName: 'Skip publishing to MCR, but show what would get published and attached'
+  type: boolean
+  default: false  
 variables:
 - name: POWERSHELL_TELEMETRY_OPTOUT
   value: 1
@@ -16,6 +20,8 @@ variables:
   value: ${{ parameters.releaseChannel }}
 - name: releaseChannelPath
   value: ''
+- name: whatIf
+  value: ${{ parameters.whatIf }}
 - name: runCodesignValidationInjection
   value: false
 - name: DisableDockerDetector
@@ -129,6 +135,7 @@ extends:
             $info = @{}
             $info.Add("channel", $env:RELEASECHANNEL)
             $info.Add("releaseVersionTag", $env:RELEASEVERSIONTAG)
+            $info.Add("whatIf", $env:WHATIF)
             $info | ConvertTo-Json | Out-File -Encoding utf8NoBOM -FilePath ./BuildInfo.json
           displayName: 'Write build info to file'
         - task: CopyFiles@2
diff --git a/.pipelines/PowerShell-Docker-Image-Release-Official.yml b/.pipelines/PowerShell-Docker-Image-Release-Official.yml
index c3498c8be..29c8fd32c 100644
--- a/.pipelines/PowerShell-Docker-Image-Release-Official.yml
+++ b/.pipelines/PowerShell-Docker-Image-Release-Official.yml
@@ -63,9 +63,11 @@ extends:
             $currentChannel = $($buildMetadata.channel)
             $currentVersion = $($buildMetadata.releaseVersionTag)
             $finalVersion = $currentVersion.Trim("v")
-            Write-Verbose -Verbose "version: $finalVersion and channel: $currentChannel"
+            $whatIfSwitch = $($buildMetadata.whatIf)
+            Write-Verbose -Verbose "version: $finalVersion and channel: $currentChannel and whatIf: $whatIf"
             Write-Host "##vso[task.setvariable variable=channel;isOutput=true]$currentChannel"
             Write-Host "##vso[task.setvariable variable=version;isOutput=true]$finalVersion"
+            Write-Host "##vso[task.setvariable variable=whatIf;isOutput=true]$whatIfSwitch"
           displayName: 'Get channel from buildInfo.json'
           name: setChannelStep
       - job: DownloadImageArtifactFromBuild
@@ -275,6 +277,8 @@ extends:
           value: $[ stageDependencies.GetBuildArtifacts.DownloadMetaArtifactFromBuild.outputs['setChannelStep.channel'] ]
         - name: version
           value: $[ stageDependencies.GetBuildArtifacts.DownloadMetaArtifactFromBuild.outputs['setChannelStep.version'] ]
+        - name: whatIf
+          value: $[ stageDependencies.GetBuildArtifacts.DownloadMetaArtifactFromBuild.outputs['setChannelStep.whatIf'] ]
         pool:
           timeoutInMinutes: 30
           type: windows
@@ -299,6 +303,7 @@ extends:
             $pathToImageMetadataFile = Join-Path -Path $pathToParametersFolder -ChildPath 'ImageMetadata.json'
             $pathToChannelJsonFile = Join-Path -Path $pathToParametersFolder -ChildPath 'ChannelInfo.json'
             $currentChannel = '$(channel)'
+            $currentWhatIfSwitch = '$(whatIf)'
 
             $channelHash = @{channel=$currentChannel}
             $channelHash | ConvertTo-Json | Out-File $pathToChannelJsonFile
diff --git a/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1 b/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1
index 07df55c65..edd4c4665 100644
--- a/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1
+++ b/EV2Specs/ServiceGroupRoot/Shell/Run/Run.ps1
@@ -123,11 +123,15 @@ try {
     Write-Verbose -Verbose "Getting channel info"
     $channelJsonFileContent = Get-Content -Path $pathToChannelJson | ConvertFrom-Json
     $channel = $channelJsonFileContent.channel
+    $whatIf = $channelJsonFileContent.whatIf
 
     Write-Verbose -Verbose "Getting image info"
     $imgJsonFileContent = Get-Content -Path $pathToImgMetadataJson | ConvertFrom-Json
     $images = $imgJsonFileContent.$channel
 
+    # Create variables for lifecycle annotations
+    $endOfLifeDate = Get-Date -Format "yyyy-MM-ddTHH:mm:00Z"
+
     Write-Verbose -Verbose "Push images to ACR"
     foreach ($image in $images)
     {
@@ -151,11 +155,63 @@ try {
                 foreach ($tag in $tags)
                 {
                     Write-Verbose -Verbose "tag: $tag"
+
+                    # check if this rolling tag is associated with an image
+                    $mcrImageFullName = "mcr.microsoft.com/powershell:$tag"
+                    oras manifest fetch $mcrImageFullName > $null
+                    $rollingTagExists = $?
+
+                    if ($rollingTagExists)
+                    {
+                        # If the lineage's rolling tag is already associated with an existing image, then only attach lifecycle metadata to the existing image to indicate that it is outdated
+                        # Resolve image's digest
+                        $imageDigest = oras resolve $mcrImageName
+
+                        # Import (old) image by digest from MCR into our ACR
+                        $mcrImageNameDigest = "mcr.microsoft.com/powershell@$imageDigest"
+                        $acrEOLImageTag = "$tag-EOL"
+                        if (!$whatIf)
+                        {
+                            az acr import --name $env:DESTINATION_ACR_NAME --source $mcrImageNameDigest --image $acrEOLImageTag
+                        }
+                        else {
+                            Write-Verbose -Verbose "az acr import --name $env:DESTINATION_ACR_NAME --source $mcrImageNameDigest --image $acrEOLImageTag"
+                        }
+
+                        # Attach lifecycle annotation, which will eventually get synced to MCR
+                        $acrImageNameDigest = "$env:DESTINATION_ACR_NAME.azurecr.io/public/powershell@$imageDigest"
+                        if (!$whatIf)
+                        {
+                            oras attach --artifact-type "application/vnd.microsoft.artifact.lifecycle" --annotation "vnd.microsoft.artifact.lifecycle.end-of-life.date=$endOfLifeDate" $acrImageNameDigest
+                        }
+                        else {
+                            Write-Verbose -Verbose "oras attach --artifact-type `"application/vnd.microsoft.artifact.lifecycle`" --annotation `"vnd.microsoft.artifact.lifecycle.end-of-life.date=$endOfLifeDate`" $acrImageNameDigest"
+                        }
+                        
+                        if (!$whatIf)
+                        {
+                            $imageAnnotation = oras discover --format json --artifact-type "application/vnd.microsoft.artifact.lifecycle" $acrImageNameDigest
+                            $imageAnnotationJson = $imageAnnotation | ConvertFrom-Json
+                            $eolDateAttached = $imageAnnotationJson.manifests.annotations."vnd.microsoft.artifact.lifecycle.end-of-life.date".ToString("yyyy-MM-ddTHH:mm:00Z")
+                            Write-Verbose -Verbose "date attached: $endOfLifeDate, date found in annotation: $eolDateAttached, match: $($eolDateAttached -eq $endOfLifeDate)"
+                        }
+                        else {
+                            Write-Verbose -Verbose "oras discover --format json --artifact-type `"application/vnd.microsoft.artifact.lifecycle`" $acrImageNameDigest"
+                        }
+                    }
+
                     # Need to push image for each tag
                     $destination_image_full_name = "$env:DESTINATION_ACR_NAME.azurecr.io/public/powershell:${tag}"
                     Write-Verbose -Verbose "dest img full name: $destination_image_full_name"
                     Write-Verbose -Verbose "Pushing file $tarballFilePath to $destination_image_full_name"
-                    ./crane push $tarballFilePath $destination_image_full_name
+                    if (!$whatIf)
+                    {
+                        ./crane push $tarballFilePath $destination_image_full_name
+                    }
+                    else {
+                        Write-Verbose "./crane push $tarballFilePath $destination_image_full_name"
+                    }
+                    
                     Write-Verbose -Verbose "done pushing for tag: $tag"
                 }
             }