Skip to content

Image Version Clarification and potential cloning/copying opportunity.#430

Closed
mbiver wants to merge 1 commit intoMicrosoftDocs:mainfrom
mbiver:patch-13
Closed

Image Version Clarification and potential cloning/copying opportunity.#430
mbiver wants to merge 1 commit intoMicrosoftDocs:mainfrom
mbiver:patch-13

Conversation

@mbiver
Copy link
Copy Markdown
Contributor

@mbiver mbiver commented Mar 5, 2026

The original article talks about "Create an image in one tenant using the source image in another tenant", but that's not really accurate. the guide is showing how to create an image version and doesn't even address the part about creating the image definition. I think we need to add some clarity to this section calling out the differences between image definitions and image versions. Also, is there an opportunity to provide some additional scripting/guidance around "cloning" either a complete gallery, or just specific image definitions/version in the gallery, etc. something like the scripting below might be able to be used, but of course would need to be checked.


# Variables (update as needed)
$SrcSub      = "SOURCE_SUBSCRIPTION_ID"
$SrcRG       = "SOURCE_RG_NAME"
$SrcGallery  = "SOURCE_GALLERY_NAME"
$DstSub      = "DEST_SUB_ID"
$DstRG       = "DEST_RG_NAME"
$DstGallery  = "DEST_GALLERY_NAME"
$DstLocation = "DEST_LOCATION"

# Sign in (if not already) and set destination subscription
az login
az account set --subscription $DstSub

# 1. Create target gallery if it doesn't exist
if (az sig show --resource-group $DstRG --gallery-name $DstGallery --query name -o tsv 2>$null) {
   Write-Output "Target gallery '$DstGallery' already exists in '$DstRG'."
} else {
   Write-Output "Creating target gallery '$DstGallery' in '$DstRG' ($DstLocation)..."
   az sig create --resource-group $DstRG --gallery-name $DstGallery --location $DstLocation --description "Cloned from $SrcGallery"
   Write-Output "Target gallery created."
}

# 2. Switch to source subscription and list image definitions
az account set --subscription $SrcSub
$defs = az sig image-definition list --resource-group $SrcRG --gallery-name $SrcGallery --query "[].name" -o tsv | Where-Object { $_ }

# 3. Loop through each image definition
foreach ($def in $defs) {
   Write-Output "`n*** Cloning Image Definition '$def' ***"

   # Read source properties

   $pub     = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.publisher" -o tsv)
   $offer   = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.offer"     -o tsv)
   $sku     = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.sku"       -o tsv)
   $osType  = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "osType"               -o tsv)
   $osState = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "osState"              -o tsv)
   $hv      = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "hyperVGeneration"     -o tsv)

   # Retrieve all features and format as "Name=Value" pairs
   $featureJson = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "features" -o json)
   $featureJson
   $features    = ($featureJson | ConvertFrom-Json | ForEach-Object { "$($_.name)=$($_.value)" }) -join " "
$features


# Join the array of lines into one JSON string
$json = ($featureJson -join "`n")

# Parse the JSON into objects
$features = ConvertFrom-Json -InputObject $json

# Build "Name=value Name=value" with booleans normalized to lowercase
$featuresString = ($features | ForEach-Object { $sv = [string]$_.value; if ($_.value -is [bool]) { $val = ($_.value).ToString().ToLower() } elseif ($sv -match '^(?i:true|false)$') { $val = $sv.ToLower() } else { $val = $sv }; "$($_.name)=$val" }) -join ' '

# Show the result (e.g., SecurityType=TrustedLaunch DiskControllerTypes=SCSI IsAcceleratedNetworkSupported=true)
$featuresString


   # Create definition in destination with all features
   az account set --subscription $DstSub
   az sig image-definition create --resource-group $DstRG --gallery-name $DstGallery --gallery-image-definition $def --publisher $pub --offer $offer --sku $sku --os-type $osType --os-state $osState --hyper-v-generation $hv --features $featuresString --location $DstLocation
   Write-Output "Created image definition '$def' in target gallery."

   # 4. Loop through versions
   az account set --subscription $SrcSub
   $vers = az sig image-version list --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "[].name" -o tsv | Where-Object { $_ }

   foreach ($ver in $vers) {
       Write-Output " -> Copying version '$ver'..."

       $id        = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "id"                         -o tsv)
       $loc       = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "location"                   -o tsv)
       $saType    = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "publishingProfile.storageAccountType" -o tsv)
       $replicas  = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "publishingProfile.replicaCount"      -o tsv)
       if (-not $saType)   { $saType   = "Standard_LRS" }
       if (-not $replicas) { $replicas = 1 }

       # Create version in destination
       az account set --subscription $DstSub
       az sig image-version create --resource-group $DstRG --gallery-name $DstGallery --gallery-image-definition $def --gallery-image-version $ver --location $loc --image-version $id --storage-account-type $saType --replica-count $replicas
       Write-Output "    Successfully created version '$ver'."
   }
}

The original article talks about "Create an image in one tenant using the source image in another tenant", but that's not really accurate.  the guide is showing how to create an image version and doesn't even address the part about creating the image definition.  I think we need to add some clarity to this section calling out the differences between image definitions and image versions.  Also, is there an opportunity to provide some additional scripting/guidance around "cloning" either a complete gallery, or just specific image definitions/version in the gallery, etc.  something like the scripting below might be able to be used, but of course would need to be checked.

```

# Variables (update as needed)
$SrcSub      = "SOURCE_SUBSCRIPTION_ID"
$SrcRG       = "SOURCE_RG_NAME"
$SrcGallery  = "SOURCE_GALLERY_NAME"
$DstSub      = "DEST_SUB_ID"
$DstRG       = "DEST_RG_NAME"
$DstGallery  = "DEST_GALLERY_NAME"
$DstLocation = "DEST_LOCATION"

# Sign in (if not already) and set destination subscription
az login
az account set --subscription $DstSub

# 1. Create target gallery if it doesn't exist
if (az sig show --resource-group $DstRG --gallery-name $DstGallery --query name -o tsv 2>$null) {
   Write-Output "Target gallery '$DstGallery' already exists in '$DstRG'."
} else {
   Write-Output "Creating target gallery '$DstGallery' in '$DstRG' ($DstLocation)..."
   az sig create --resource-group $DstRG --gallery-name $DstGallery --location $DstLocation --description "Cloned from $SrcGallery"
   Write-Output "Target gallery created."
}

# 2. Switch to source subscription and list image definitions
az account set --subscription $SrcSub
$defs = az sig image-definition list --resource-group $SrcRG --gallery-name $SrcGallery --query "[].name" -o tsv | Where-Object { $_ }

# 3. Loop through each image definition
foreach ($def in $defs) {
   Write-Output "`n*** Cloning Image Definition '$def' ***"

   # Read source properties

   $pub     = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.publisher" -o tsv)
   $offer   = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.offer"     -o tsv)
   $sku     = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "identifier.sku"       -o tsv)
   $osType  = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "osType"               -o tsv)
   $osState = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "osState"              -o tsv)
   $hv      = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "hyperVGeneration"     -o tsv)

   # Retrieve all features and format as "Name=Value" pairs
   $featureJson = (az sig image-definition show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "features" -o json)
   $featureJson
   $features    = ($featureJson | ConvertFrom-Json | ForEach-Object { "$($_.name)=$($_.value)" }) -join " "
$features


# Join the array of lines into one JSON string
$json = ($featureJson -join "`n")

# Parse the JSON into objects
$features = ConvertFrom-Json -InputObject $json

# Build "Name=value Name=value" with booleans normalized to lowercase
$featuresString = ($features | ForEach-Object { $sv = [string]$_.value; if ($_.value -is [bool]) { $val = ($_.value).ToString().ToLower() } elseif ($sv -match '^(?i:true|false)$') { $val = $sv.ToLower() } else { $val = $sv }; "$($_.name)=$val" }) -join ' '

# Show the result (e.g., SecurityType=TrustedLaunch DiskControllerTypes=SCSI IsAcceleratedNetworkSupported=true)
$featuresString


   # Create definition in destination with all features
   az account set --subscription $DstSub
   az sig image-definition create --resource-group $DstRG --gallery-name $DstGallery --gallery-image-definition $def --publisher $pub --offer $offer --sku $sku --os-type $osType --os-state $osState --hyper-v-generation $hv --features $featuresString --location $DstLocation
   Write-Output "Created image definition '$def' in target gallery."

   # 4. Loop through versions
   az account set --subscription $SrcSub
   $vers = az sig image-version list --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --query "[].name" -o tsv | Where-Object { $_ }

   foreach ($ver in $vers) {
       Write-Output " -> Copying version '$ver'..."

       $id        = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "id"                         -o tsv)
       $loc       = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "location"                   -o tsv)
       $saType    = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "publishingProfile.storageAccountType" -o tsv)
       $replicas  = (az sig image-version show --resource-group $SrcRG --gallery-name $SrcGallery --gallery-image-definition $def --gallery-image-version $ver --query "publishingProfile.replicaCount"      -o tsv)
       if (-not $saType)   { $saType   = "Standard_LRS" }
       if (-not $replicas) { $replicas = 1 }

       # Create version in destination
       az account set --subscription $DstSub
       az sig image-version create --resource-group $DstRG --gallery-name $DstGallery --gallery-image-definition $def --gallery-image-version $ver --location $loc --image-version $id --storage-account-type $saType --replica-count $replicas
       Write-Output "    Successfully created version '$ver'."
   }
}
```
@mbiver
Copy link
Copy Markdown
Contributor Author

mbiver commented Mar 5, 2026

@microsoft-github-policy-service agree

@prmerger-automator
Copy link
Copy Markdown
Contributor

@mbiver : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change.

@mbiver
Copy link
Copy Markdown
Contributor Author

mbiver commented Mar 5, 2026

@microsoft-github-policy-service agree company="Microsoft"

@learn-build-service-prod
Copy link
Copy Markdown
Contributor

Learn Build status updates of commit 14e2dbc:

✅ Validation status: passed

File Status Preview URL Details
articles/virtual-machines/image-version.md ✅Succeeded

For more details, please refer to the build report.

@ttorble ttorble requested a review from Copilot March 5, 2026 16:52
@ttorble
Copy link
Copy Markdown
Contributor

ttorble commented Mar 5, 2026

@sandeepraichura

Can you review the proposed changes?

IMPORTANT: When the changes are ready for publication, adding a #sign-off comment is the best way to signal that the PR is ready for the review team to merge.

#label:"aq-pr-triaged"
@MicrosoftDocs/public-repo-pr-review-team

@prmerger-automator prmerger-automator Bot added the aq-pr-triaged C+L Pull Request Review Team label label Mar 5, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions
Copy link
Copy Markdown

This pull request has been inactive for at least 14 days. If you are finished with your changes, don't forget to sign off. See the contributor guide for instructions.
Get Help
Docs Support Teams Channel
Resolve Merge Conflict

@github-actions github-actions Bot added the inactive This PR is inactive for more than 14 days label Mar 19, 2026
@v-dirichards v-dirichards requested a review from Copilot April 7, 2026 21:32
@v-dirichards
Copy link
Copy Markdown
Contributor

@sandeepraichura

Can you review this old PR and determine whether it needs to be closed or merged?

@MicrosoftDocs/public-repo-pr-review-team

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.

## Create an image version in one tenant using the source image version in another tenant

In the subscription where the source image exists, grant reader permissions to the user. Once the user has reader permission to the source image, login to both accounts (source and target).
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target).
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this sentence, “login” is used as a verb. In Microsoft style, use “log in” (verb) / “sign in” instead (for example: “log in to both accounts…”).

Suggested change
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target).
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, log in to both accounts (source and target).

Copilot uses AI. Check for mistakes.
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target).

You will need the `tenantID` of the source image, the `subscriptionID` for the subscription where the new image will be stored (target), and the `resourceID` of the source image. Additionally, you need to ensure that the source image's region or replica and target region are the same.
You will need the tenantID of the source image version, the subscriptionID for the subscription where the new image version will be stored (target), and the resourceID of the source image version. Additionally, you need to ensure that the source image version's region or replica and target region are the same.
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph introduces identifiers like tenantID/subscriptionID/resourceID as literal tokens but doesn’t format them as code. Consider wrapping these identifier names in backticks for readability/consistency with the rest of the article, and explicitly call out that the target gallery image definition must already exist before you can create a version with az sig image-version create / New-AzGalleryImageVersion.

Suggested change
You will need the tenantID of the source image version, the subscriptionID for the subscription where the new image version will be stored (target), and the resourceID of the source image version. Additionally, you need to ensure that the source image version's region or replica and target region are the same.
You will need the `tenantID` of the source image version, the `subscriptionID` for the subscription where the new image version will be stored (target), and the `resourceID` of the source image version. The target gallery image definition must already exist before you create the image version with `az sig image-version create` or `New-AzGalleryImageVersion`. Additionally, ensure that the source image version's region or replica and target region are the same.

Copilot uses AI. Check for mistakes.
Comment on lines 347 to 353
az sig image-version create `
--gallery-image-definition myImageDef `
--gallery-image-version 1.0.0 `
--gallery-name myGallery `
--resource-group myResourceGroup `
--image-version $sourceImageID
--image-version $sourceImageVersionID `
--location myLocation
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI snippet is marked as azurecli-interactive (bash), but it uses PowerShell-style backticks for line continuation. Earlier CLI examples in this file use \ for continuation; as written, this command won’t run in bash. Update the line continuations to bash-compatible syntax (or change the code block/language to match the intended shell).

Copilot uses AI. Check for mistakes.
@github-actions github-actions Bot removed the inactive This PR is inactive for more than 14 days label Apr 8, 2026
## Create an image version in one tenant using the source image version in another tenant

In the subscription where the source image exists, grant reader permissions to the user. Once the user has reader permission to the source image, login to both accounts (source and target).
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, login to both accounts (source and target).
In the subscription where the source image version exists, grant reader permissions to the user. Once the user has reader permission to the source image version, sign in to both accounts (source and target).

@cynthn
Copy link
Copy Markdown
Contributor

cynthn commented Apr 9, 2026

#please-close

Moving to the private repo so we have staging: https://github.com/MicrosoftDocs/azure-compute-docs-pr/pull/3308

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants