dwchan
Enthusiast
Enthusiast

Mount a content library iso on a live VM

Jump to solution

We used a content library repo to hold our iso and template.  I am able to mount OS iso during VM creation without issue, something like this

$ConLibName = 'Repo'
$strSQLiso = 'en_win_server_2016_standard_x64_dvd_8701871'
$VMiso = Get-ContentLibraryItem -Name $strSQLiso
VMware.VimAutomation.Core\Get-VM -Name $strVMName | New-CDDrive -ContentLibraryIso $VMiso -Verbose

However, this doesn't seem to work on a power-on VM . (trying to do a SQL install) due to a power-on state

New-CDDrive : 12/11/2020 10:32:35 AM New-CDDrive com.vmware.vapi.std.errors.not_allowed_in_current_state {'messages':
[com.vmware.vapi.std.localizable_message {'id': com.vmware.vdcs.iso-main.invalid_power_state_mount, 'default_message': The
library item (en_sql_server_2016_standard_x64_dvd_8701871) cannot be mounted on the virtual machine (SQL) in the current
state: poweredOn. The virtual machine must be in the state: poweredOff., 'args':

However, I can't use the set-cddrive cmdlet either as it doesn't seem to work with content library.  

Any suggestion or new approach would be appreciated 

 

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

I did some further exploring, the following snippet seems to work for me, in all situations.

$vmName = 'MyVM'
$cLibName = 'MyCl'
$cLibItemName = 'SomeIso'   # The Name as it appears in the CL

$vm = Get-VM -Name $vmName
$cd = Get-CDDrive -VM $vm
$clib = Get-ContentLibrary -Name $cLibName

$ds = Get-Datastore -Name $clib.Datastore
New-PSDrive -Name DS -PSProvider VimDatastore -Root '\' -Location $ds | Out-Null
$isoPath = Get-ChildItem -Path "DS:" -Recurse -Filter "$($cLibItemName)*.iso" | Select -ExpandProperty DatastoreFullPath
Remove-PSDrive -Name DS -Confirm:$false | Out-Null

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$change = New-Object VMware.Vim.VirtualDeviceConfigSpec
$change.Operation = [Vmware.vim.VirtualDeviceConfigSpecOperation]::edit

$dev = $cd.ExtensionData
$dev.Backing = New-Object VMware.Vim.VirtualCdromIsoBackingInfo
$dev.Backing.FileName = $isoPath

$change.Device += $dev
$change.Device.Connectable.Connected = $true

$spec.DeviceChange = $change

$vm.ExtensionData.ReconfigVM($spec)

The difference is that I get the path of the ISO in the Content Library via the VimDatastore provider.
Apparently, the name has to have the UUID of the file in the path used.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
16 Replies
LucD
Leadership
Leadership

That functionality is currently not supported by the cmdlets.
But you can use the API method.

The drawback is that the ISO will be marked as a Datastore ISO, not a Content Library ISO

$vmName = 'MyVM'
$cLibName = 'MyCL'
$cLibItemName = 'someISO'  # The Name as it appears in the CL

$vm = Get-VM -Name $vmName
$cd = Get-CDDrive -VM $vm
$clib = Get-ContentLibrary -Name $cLibName
$cLibItem = Get-ContentLibraryItem -ContentLibrary $cLibName -Name $cLibItemName

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$change = New-Object VMware.Vim.VirtualDeviceConfigSpec
$change.Operation = [Vmware.vim.VirtualDeviceConfigSpecOperation]::edit

$dev = $cd.ExtensionData
$dev.Backing = New-Object VMware.Vim.VirtualCdromIsoBackingInfo
$dev.Backing.FileName = "[$($clib.Datastore)] contentlib-$($clib.Id)/$($cLibItem.Id)/$($cLibItem.Name).$($cLibItem.ItemType)"

$change.Device += $dev
$spec.DeviceChange = $change

$vm.ExtensionData.ReconfigVM($spec)


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dwchan
Enthusiast
Enthusiast

I update my code based on your input

$vm = Get-VM -Name $strVMName
$ConLibName = 'Repo'
$strSQLiso = 'en_sql_server_2016_standard_x64_dvd_8701871'
$CLib = Get-ContentLibrary -Name $ConLibName
$VMiso = Get-ContentLibraryItem -ContentLibrary $ConLibName -Name $strSQLiso
$oCDROM = Get-CDDrive -VM $strVMName
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$change = New-Object VMware.Vim.VirtualDeviceConfigSpec
$change.Operation = [Vmware.vim.VirtualDeviceConfigSpecOperation]::edit
$oDevice = $oCDROM.ExtensionData
$oDevice.Backing = New-Object VMware.Vim.VirtualCdromIsoBackingInfo
$oDevice.Backing.FileName = "[$($CLib.Datastore)] contentlib-$($CLib.Id)/$($VMiso.Id)/$($VMiso.Name).$($VMiso.ItemType)"
$oDevice.Connectable.StartConnected = $true
$oDevice.Connectable.Connected = $true
$change.Device += $oDevice
$spec.DeviceChange = $change
$vm.ExtensionData.ReconfigVM($spec)

However, I can't seem to get the drive actually connect (map to the iso inside the content library, just not connecting.  I tried it with the GUI and it failed.  I even tried with a follow command

Get-CDDrive -vm $strVMName|Set-CDDrive -Connected:$true -Confirm:$false 

PS C:\Users\Administrator> Get-cddrive -vm $strVMName|Set-CDDrive -Connected:$true -Confirm:$false
Set-CDDrive : 12/11/2020 3:38:26 PM Set-CDDrive The operation for the entity "SQL" failed with the following message:
"Connection control operation failed for disk 'ide0:0'.". Connection control operation failed for disk 'ide0:0'.
At line:1 char:28
+ ... t-cddrive -vm $strVMName|Set-CDDrive -Connected:$true -Confirm:$false
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Set-CDDrive], GenericVmConfigFault
+ FullyQualifiedErrorId : Client20_TaskServiceImpl_CheckServerSideTaskUpdates_OperationFailed,VMware.VimAutomation.ViCore
.Cmdlets.Commands.VirtualDevice.SetCDDrive

0 Kudos
LucD
Leadership
Leadership

Is there already an ISO or a drive connected before you run the script?
If yes, try with nothing connected


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dwchan
Enthusiast
Enthusiast

the iso from the content library.  The script did update the path to the iso.  It even show up in the GUI, just will not connect.  

0 Kudos
dwchan
Enthusiast
Enthusiast

I discovered something interesting, but not sure the fix yet.  Per your code from earlier

$oDevice.Backing.FileName = "[$($CLib.Datastore)] contentlib-$($CLib.Id)/$($VMiso.Id)/$($VMiso.Name).$($VMiso.ItemType)"

to build out the actual path to the iso from a datastore point of view, the output were

PS C:\Users\Administrator> echo $CLib.Datastore

Name FreeSpaceGB CapacityGB
---- ----------- ----------
SSD_VM 70.388 223.500

PS C:\Users\Administrator> echo $CLib.Id
e46c6898-9ecc-4fcd-8145-8639bfc7611f

PS C:\Users\Administrator> echo $VMiso.Id
b835b797-a146-4c10-bcbc-537b74e6eb4a

PS C:\Users\Administrator> echo $VMiso.Name
en_sql_server_2016_standard_x64_dvd_8701871

PS C:\Users\Administrator> echo $VMiso.Itemtype
iso

So the code should stitch together the following value

[SSD_VM] contentlib-e46c6898-9ecc-4fcd-8145-8639bfc7611f/b835b797-a146-4c10-bcbc-537b74e6eb4a/en_sql_server_2016_standard_x64_d
vd_8701871.iso

However, when I manually attach the iso through the GUI by using the datastore path (not content library), and I reparse the vm.extensiondata manual, I got the following

[SSD_VM] contentlib-e46c6898-9ecc-4fcd-8145-8639bfc7611f/b835b797-a146-4c10-bcbc-537b74e6eb4a/en_sql_server_2016_standard_x64_d
vd_8701871_1900ce00-de5c-4b91-a526-2af7057ddc3f.iso

the name of the iso actually change after I uploaded it.  It is masked if I try to view from the content library , but it is clearly visible (I also confirmed) if you view it from the datastore view.  So the question is what is this extra data (metadata? ID?) '1900ce00-de5c-4b91-a526-2af7057ddc3f' come from?

0 Kudos
LucD
Leadership
Leadership

I noticed the same when I try with an ISO that I gave another name in the Content Library.
Not sure how to explain that behavior.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dwchan
Enthusiast
Enthusiast

is there a way to use wildcard for a string inside powerCLI?  $a = sql* versus $a = sql-2016-blahblah

0 Kudos
LucD
Leadership
Leadership

Tried that, but since that code is calling the API, no cigar I'm afraid.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dwchan
Enthusiast
Enthusiast

lol, so it seem currently, the best route is to move the SQL ISO into a datastore and mount it that want

0 Kudos
LucD
Leadership
Leadership

I uploaded an ISO to a Content Library without giving it another name.
It then took the name of the ISO.
Then the script I provided seems to work


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dwchan
Enthusiast
Enthusiast

?  Do not understand.  Can you phrase it another way ?

0 Kudos
LucD
Leadership
Leadership

When you import an ISO into a Content Library the Item name field automatically gets the same name as the name of the ISO, minus the filetype.

The snippet works for me when I don't change that Item name field.

cl-item.png


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
dwchan
Enthusiast
Enthusiast

Let me take a quick look. Thanks

0 Kudos
LucD
Leadership
Leadership

I did some further exploring, the following snippet seems to work for me, in all situations.

$vmName = 'MyVM'
$cLibName = 'MyCl'
$cLibItemName = 'SomeIso'   # The Name as it appears in the CL

$vm = Get-VM -Name $vmName
$cd = Get-CDDrive -VM $vm
$clib = Get-ContentLibrary -Name $cLibName

$ds = Get-Datastore -Name $clib.Datastore
New-PSDrive -Name DS -PSProvider VimDatastore -Root '\' -Location $ds | Out-Null
$isoPath = Get-ChildItem -Path "DS:" -Recurse -Filter "$($cLibItemName)*.iso" | Select -ExpandProperty DatastoreFullPath
Remove-PSDrive -Name DS -Confirm:$false | Out-Null

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$change = New-Object VMware.Vim.VirtualDeviceConfigSpec
$change.Operation = [Vmware.vim.VirtualDeviceConfigSpecOperation]::edit

$dev = $cd.ExtensionData
$dev.Backing = New-Object VMware.Vim.VirtualCdromIsoBackingInfo
$dev.Backing.FileName = $isoPath

$change.Device += $dev
$change.Device.Connectable.Connected = $true

$spec.DeviceChange = $change

$vm.ExtensionData.ReconfigVM($spec)

The difference is that I get the path of the ISO in the Content Library via the VimDatastore provider.
Apparently, the name has to have the UUID of the file in the path used.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
dwchan
Enthusiast
Enthusiast

Nice, I see you are using the datastore to parse the name for the full path.  This seem to work, but will do some clean up and further testing to confirm.  Thank you

0 Kudos
dwchan
Enthusiast
Enthusiast

Thank you, that fixed it 😉 

0 Kudos