<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Content Library Archives - LucD notes</title>
	<atom:link href="https://www.lucd.info/tag/content-library/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.lucd.info/tag/content-library/</link>
	<description>My PowerShell ramblings</description>
	<lastBuildDate>Sat, 19 Dec 2020 13:15:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://www.lucd.info/wp-content/uploads/2018/12/cropped-120px-Tibetan_Dharmacakra-32x32.png</url>
	<title>Content Library Archives - LucD notes</title>
	<link>https://www.lucd.info/tag/content-library/</link>
	<width>32</width>
	<height>32</height>
</image> 
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/><atom:link rel="hub" href="https://websubhub.com/hub"/>	<item>
		<title>How to Mount a Content Library ISO on a VM</title>
		<link>https://www.lucd.info/2020/12/13/how-to-mount-a-content-library-iso-on-a-vm/</link>
					<comments>https://www.lucd.info/2020/12/13/how-to-mount-a-content-library-iso-on-a-vm/#comments</comments>
		
		<dc:creator><![CDATA[LucD]]></dc:creator>
		<pubDate>Sun, 13 Dec 2020 13:53:20 +0000</pubDate>
				<category><![CDATA[Content Library]]></category>
		<category><![CDATA[ISO]]></category>
		<category><![CDATA[mount]]></category>
		<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[Mount]]></category>
		<guid isPermaLink="false">https://www.lucd.info/?p=7356</guid>

					<description><![CDATA[While Content Libraries are becoming more and more used, there are still some [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>While <a href="https://blogs.vmware.com/vsphere/2019/12/the-evolution-of-content-library.html" target="_blank" rel="noopener">Content Libraries</a> are becoming more and more used, there are still some features that are not yet implemented in PowerCLI. So is it for example not possible to mount an ISO file located in a Content Library on a VM. The <a href="https://vdc-repo.vmware.com/vmwb-repository/dcr-public/f17594eb-bbe1-44a7-b7ac-b2da546936c2/21da7740-996d-481e-83e4-05d8fa7db18d/doc/Set-CDDrive.html" target="_blank" rel="noopener">Set-CDDrive</a> cmdlet is currently <a href="https://powercli.ideas.aha.io/ideas/PCLI-I-172" target="_blank" rel="noopener">lacking this functionality</a>, while the <a href="https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-BE1C18D2-8FF0-4F41-AA35-A4BA71D62EB4.html" target="_blank" rel="noopener">Web Client</a> offers this option.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="621" height="250" src="https://www.lucd.info/wp-content/uploads/2020/12/cl-iso-mount-1.png" alt="" class="wp-image-7369" srcset="https://www.lucd.info/wp-content/uploads/2020/12/cl-iso-mount-1.png 621w, https://www.lucd.info/wp-content/uploads/2020/12/cl-iso-mount-1-300x121.png 300w" sizes="(max-width: 621px) 100vw, 621px" /></figure>



<p>Like often, and one of the <a href="https://code.vmware.com/web/tool/vmware-powercli" target="_blank" rel="noopener">VMware PowerCLI</a> features I absolutely like, when a cmdlet is missing a feature, you can fall back on the API to solve the issue.</p>



<span id="more-7356"></span>



<h2>Introduction</h2>



<p>Like so often, the reason I had a closer look at this issue was due to a <a href="https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Mount-a-content-library-iso-on-a-live-VM/td-p/2816413/jump-to/first-unread-message" target="_blank" rel="noopener">question</a> in <a href="https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/bd-p/2805" target="_blank" rel="noopener">PowerCLI Community</a> on VMTN.</p>



<p>My first step in such cases is always to have a look at the <a href="https://code.vmware.com/apis/968/vsphere" target="_blank" rel="noopener">vSphere Web Services API</a>.</p>



<p>But unfortunately, the <a href="https://vdc-download.vmware.com/vmwb-repository/dcr-public/b50dcbbf-051d-4204-a3e7-e1b618c1e384/538cf2ec-b34f-4bae-a332-3820ef9e7773/vim.VirtualMachine.html#reconfigure" target="_blank" rel="noopener">ReconfigVM_Task</a> method documentation didn&#8217;t make me any wiser. There is apparently no object, property, or method to mount an ISO from a Content Library onto a VM.</p>



<p>In the next step I had a look at the <a href="https://developer.vmware.com/docs/vsphere-automation/latest/" target="_blank" rel="noopener">vSphere REST API Reference</a>. But in there I could also not find anything specific about Content Library ISOs and VM CD drives.</p>



<p>When all else fails, <strong>look at the code</strong>!</p>



<p>And with <a href="https://blogs.vmware.com/PowerCLI/2018/08/introducing-code-capture.html" target="_blank" rel="noopener">Code Capture</a> we have just that option!</p>



<p>The first thing I noticed while looking at the generated code, there are no &#8216;special&#8217; object, properties, or method used. Just a plain <strong>ReconfigVM_Task</strong> call with an <strong>edit</strong> action on the CD drive device.</p>



<p>The only special feature was the value in the FileName property.</p>



<p>That value definitely pointed to the ISO file in the Content Library. At first I tried to compose that value by hand/script. But it turned out that some parts of the value were not obtainable via normal ways.</p>



<p>I found out then when I use the <a href="https://vdc-repo.vmware.com/vmwb-repository/dcr-public/f17594eb-bbe1-44a7-b7ac-b2da546936c2/21da7740-996d-481e-83e4-05d8fa7db18d/doc/about_vimdatastore.html" target="_blank" rel="noopener">vimdatastore</a> provider, the returned <strong>FullDatastorePath</strong> contained exactly the value I neededd.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="172" src="https://www.lucd.info/wp-content/uploads/2020/12/CL-ISO-1024x172.png" alt="" class="wp-image-7374" srcset="https://www.lucd.info/wp-content/uploads/2020/12/CL-ISO-1024x172.png 1024w, https://www.lucd.info/wp-content/uploads/2020/12/CL-ISO-300x50.png 300w, https://www.lucd.info/wp-content/uploads/2020/12/CL-ISO-768x129.png 768w, https://www.lucd.info/wp-content/uploads/2020/12/CL-ISO-720x121.png 720w, https://www.lucd.info/wp-content/uploads/2020/12/CL-ISO.png 1493w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">The Code</h2>



<pre class="lang:ps decode:true  ">
function Set-CDDriveCLIso {

    <#
    .SYNOPSIS
      Mount an ISO from a Content Library
      .DESCRIPTION
      This function will mount an ISO located on a Content Library
      on a CDDrive of a VM
    .NOTES
      Author:  Luc Dekens
      Version:
      1.0 24/12/20  Initial release
    .PARAMETER VM
      Specifies the virtual machines on whose guest operating systems
      you want to run the script.
    .PARAMETER CDDrive
      Specifies the CDDrive on which the ISO will be mounted
    .PARAMETER ContentLibrary
      Specifies the Content Library on which the ISO is located.
    .PARAMETER ContentLibraryIso
      Specifies the ISO item on the Content Library
    .EXAMPLE
      $cl = Get-ContentLibrary -Name MyCL
      $iso = Get-ContentLibraryItem -ContentLibrary $cl -Name MyISO
      Get-VM -Name 'MyVM' | Get-CDDrive -Name 'CD/DVD drive 0' |
      Set-CDDriveCLIso -ContentLibraryIso $iso -Confirm:$false
    .EXAMPLE
      $cd = Get-VM -Name MyVM | Get-CDDrive
      Set-CDDriveCLIso -CDDrive $cd -ContentLibraryIso $iso -Confirm:$false
    #>
    
    [cmdletbinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param(
        [parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.CDDrive]$CDDrive,
        [parameter(Mandatory = $true)]
        [VMware.VimAutomation.ViCore.Types.V1.ContentLibrary.ContentLibraryItem]$ContentLibraryISO
    )
    
    $target = "VM:$($CDDrive.Parent.Name) CD:$($CDDrive.Name)"
    $action = "Mount ISO $($ContentLibraryISO.Name) from $($ContentLibraryISO.ContentLibrary.Name)"
        
    if ($PSCmdlet.ShouldProcess($target, $action)) {
        $driveName = -join ((65..90) | 
                Get-Random -Count 3 | 
                ForEach-Object -Process { [char]$_ })
        $filter = "$($ContentLibraryISO.Name)*.iso" 
        
        $ds = Get-Datastore -Name $ContentLibraryISO.ContentLibrary.Datastore
        
        New-PSDrive -Name $driveName -PSProvider VimDatastore -Root '\' -Location $ds | Out-Null
        $clPath = Get-ChildItem -Path "$($driveName):" -Filter "$($ContentLibraryIso.Id)" -Recurse |
            Select-Object -ExpandProperty FolderPath
        $isoPath = Get-ChildItem -Path "$($driveName):\$($clPath.Split(' ')[1])" -Filter $filter -Recurse | 
            Select-Object -ExpandProperty DatastoreFullPath
        Remove-PSDrive -Name $driveName -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)
    
        Get-CDDrive -Id $CDDrive.Id
    }
}
</code></pre>



<h3 class="wp-block-heading">Annotations</h3>



<p><strong>Line 34-37</strong>: The parameters that the function requires are objects returned by the <a href="https://vdc-repo.vmware.com/vmwb-repository/dcr-public/f17594eb-bbe1-44a7-b7ac-b2da546936c2/21da7740-996d-481e-83e4-05d8fa7db18d/doc/Get-CDDrive.html" target="_blank" rel="noreferrer noopener">Get-CDDrive</a> and <a href="https://vdc-repo.vmware.com/vmwb-repository/dcr-public/f17594eb-bbe1-44a7-b7ac-b2da546936c2/21da7740-996d-481e-83e4-05d8fa7db18d/doc/Get-ContentLibraryItem.html" target="_blank" rel="noreferrer noopener">Get-ContentLibraryItem</a> cmdlets. The function does not implement <a href="https://vdc-repo.vmware.com/vmwb-repository/dcr-public/f17594eb-bbe1-44a7-b7ac-b2da546936c2/21da7740-996d-481e-83e4-05d8fa7db18d/doc/about_obn.html" target="_blank" rel="noreferrer noopener">OBN</a> support.</p>



<p><strong>Line 40-41</strong>: This provides meaningful content for the message returned when the <strong>WhatIf</strong> switch is used.</p>



<p><strong>Line 44-46</strong>: To avoid conflicts with PSDrives the user might already have defined, the function generates a <strong>3-letter, random string</strong> that will be used as the drivename.</p>



<p><strong>Line 52-53</strong>: To avoid a situation where the same ISO file might be uploaded to two different Content Libraries, the function first finds the path to the folder that corresponds with the requested Content Library.</p>



<p><strong>Line 54-55</strong>: This search finds the actual path to the desired ISO file.</p>



<p><strong>Line 60-72</strong>: A &#8216;regular&#8217; call to the ReconfigVM_Task method.</p>



<p><strong>Line 74</strong>: The function returns the CDDrive object, just like the regular Set-CDDrive cmdlet does. But since there is currently not yet support for ISO files from a Content Library, the filepath looks like a regular path to an ISO file. The Web Client does show that this is an ISO from a Content Library.</p>



<h2 class="wp-block-heading">Sample Run</h2>



<p>Using the function is rather straightforward.</p>



<pre class="lang:ps decode:true  ">
$vmName = 'photonps'
$cdName = 'CD/DVD drive 1'
$cLibName = 'ConLib1'
$cLibItemName = 'photon-minimal-3.0-a0f216d'
    
$vm = Get-VM -Name $vmName
    
$cl = Get-ContentLibrary -Name $cLibName
$iso = Get-ContentLibraryItem -Name $cLibItemName -ContentLibrary $cl
    
Get-CDDrive -VM $vm -Name $cdName |
Set-CDDriveCLISO -ContentLibraryISO $iso -Confirm:$false
</code></pre>



<p>The Web Client shows that an ISO from a Content Library is loaded.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="780" height="207" src="https://www.lucd.info/wp-content/uploads/2020/12/wc-cl-iso.png" alt="" class="wp-image-7378" srcset="https://www.lucd.info/wp-content/uploads/2020/12/wc-cl-iso.png 780w, https://www.lucd.info/wp-content/uploads/2020/12/wc-cl-iso-300x80.png 300w, https://www.lucd.info/wp-content/uploads/2020/12/wc-cl-iso-768x204.png 768w, https://www.lucd.info/wp-content/uploads/2020/12/wc-cl-iso-720x191.png 720w" sizes="(max-width: 780px) 100vw, 780px" /></figure>



<p>Enjoy!</p>


]]></content:encoded>
					
					<wfw:commentRss>https://www.lucd.info/2020/12/13/how-to-mount-a-content-library-iso-on-a-vm/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
