<?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>unmount Archives - LucD notes</title>
	<atom:link href="https://www.lucd.info/tag/unmount/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.lucd.info/tag/unmount/</link>
	<description>My PowerShell ramblings</description>
	<lastBuildDate>Wed, 05 Apr 2023 10:49:57 +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>unmount Archives - LucD notes</title>
	<link>https://www.lucd.info/tag/unmount/</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>Answer the question!</title>
		<link>https://www.lucd.info/2015/10/02/answer-the-question/</link>
					<comments>https://www.lucd.info/2015/10/02/answer-the-question/#comments</comments>
		
		<dc:creator><![CDATA[LucD]]></dc:creator>
		<pubDate>Fri, 02 Oct 2015 09:48:44 +0000</pubDate>
				<category><![CDATA[Background]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Question]]></category>
		<category><![CDATA[unmount]]></category>
		<category><![CDATA[Virtual Machine]]></category>
		<category><![CDATA[background]]></category>
		<category><![CDATA[cd]]></category>
		<category><![CDATA[dvd]]></category>
		<category><![CDATA[job]]></category>
		<category><![CDATA[question]]></category>
		<category><![CDATA[VM]]></category>
		<guid isPermaLink="false">http://www.lucd.info/?p=4970</guid>

					<description><![CDATA[An automation scripts that prompts you is a letdown, to say the least. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>An automation scripts that prompts you is a letdown, to say the least.</p>
<p><a href="https://www.lucd.info/2015/10/02/answer-the-question/cdlock/" rel="attachment wp-att-4978"><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-4978" src="https://lucd.info/wp-content/uploads/2015/10/cdlock.png" alt="cdlock" width="608" height="186" srcset="https://www.lucd.info/wp-content/uploads/2015/10/cdlock.png 608w, https://www.lucd.info/wp-content/uploads/2015/10/cdlock-300x92.png 300w" sizes="(max-width: 608px) 100vw, 608px" /></a></p>
<p>A typical example of such an event is the question you get when you try to unmount a CD or DVD drive from a VM. Some Linux guest OS will place a lock on the CD or DVD, and vSphere will ask you if you want to bypass this lock. And your script just hangs there, waiting for you to reply <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>I have been looking for some time to come up with a solution for this automation &#8220;issue&#8221;. And finally I came up with a working solution <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br /><span id="more-4970"></span></p>
<h2>The Problem</h2>
<p>The problem is quite simple to recreate. Execute the following code for a VM that is running a Linux guest OS, and that has an ISO mounted.</p>
<pre class="urvanov-syntax-highlighter-plain-tag">$vmName = 'MyVM'
$vm = Get-VM -Name $vmName
$cd = Get-CDDrive -VM $vm

Set-CDDrive -CD $cd -NoMedia -Confirm:$false</pre>
<p>The following question will appear, provided you have the vSphere Client open.</p>
<p><a href="https://www.lucd.info/2015/10/02/answer-the-question/question/" rel="attachment wp-att-4976"><img decoding="async" class="alignnone size-full wp-image-4976" src="https://lucd.info/wp-content/uploads/2015/10/question.png" alt="question" width="536" height="191" srcset="https://www.lucd.info/wp-content/uploads/2015/10/question.png 536w, https://www.lucd.info/wp-content/uploads/2015/10/question-300x107.png 300w" sizes="(max-width: 536px) 100vw, 536px" /></a></p>
<p>My initial idea was to use asynchronous events on a <a href="https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx" target="_blank" rel="noopener noreferrer">Timer</a> object to answer the question. But that didn&#8217;t work, since for the action code attached to such a Timer event to fire, the code has to pass through the .Net  framework. Which in case of such an outstanding question, it didn&#8217;t.</p>
<p>An alternative solution that I got working, was with a background job that is started just before the unmount is attempted.</p>
<h2>The Script</h2>
<pre class="urvanov-syntax-highlighter-plain-tag">function Set-CDDriveAndAnswer
{
&lt;#
.SYNOPSIS  Unmounts a CD/DVD from a VM and answers an outstanding question
.DESCRIPTION The function will unmount a CD/DVD from a DVD.
  If the unmount causes a question, the function will answer the question.
.NOTES  Author:  Luc Dekens
.PARAMETER Name
  The DisplayName of the VM
.PARAMETER Server
  The vSphere Server on which the VM is located.
  The default is $global:defaultviserver
.EXAMPLE
  PS&gt; Set-CDDriveAndAnswer -Name MyVM -Server $global:DefaultVIServer
.EXAMPLE
  PS&gt; Get-VM | Set-CDDriveAndAnswer
#&gt;
  [CmdletBinding()]
  param(
  [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
  [string[]]$Name,
  [PSObject]$Server
  )

  Begin
  {
    $cdQuestion = {
      param($VmName,$vServer)
    
      $maxPass = 5
      $pass = 0
    
      Add-PSSnapin VMware*
      Connect-VIServer -Server $vServer.Name  -Session $vServer.SessionSecret | Out-Null
      while($pass -lt $maxPass){
        $question = Get-VM -Name $VmName | Get-VMQuestion -QuestionText "*locked the CD-ROM*"
        if($question){
          Set-VMQuestion -VMQuestion $question -Option Yes -Confirm:$false
          $pass = $maxPass + 1
        }
        $pass++
        sleep 1
       }
    }

    if(!$Server){
      $Server = $global:DefaultVIServer
    }
  }

  Process
  {
    $Name | %{
      $vm = Get-VM -Name $_
      $cd = Get-CDDrive -VM $vm
      $job = Start-Job -Name Check-CDQuestion -ScriptBlock $cdQuestion -ArgumentList $_,$Server
      Set-CDDrive -CD $cd -NoMedia -Confirm:$false -ErrorAction Stop
    }
  }
}</pre>
<h3>Annotation</h3>
<p><strong>Line 20</strong>: the function can accept the VM(s) from the pipeline</p>
<p><strong>Line 27-45</strong>: the background job that will check if the unmount has caused a question. If yes, the background job will answer the question with &#8220;<em>Yes</em>&#8220;. The background job times out after <strong>5 seconds</strong>.</p>
<p><strong>Line 34</strong>: In a background job, you can reuse an open vSphere Server connection by using the <strong>SessionSecret</strong> property.</p>
<p><strong>Line 36-38</strong>: The function looks for an outstanding &#8220;<em>locked CD rom door</em>&#8221; question for the specific VM. If such a question is found, the function will reply with &#8220;Yes&#8221;</p>
<p><strong>Line 46-48</strong>: If no vSphere Server was passed on the Server parameter, the script will use the default vSphere Server connection that is to be found in <strong>$global:defaultviserver</strong></p>
<p><strong>Line 57</strong>: The actual unmount command. It will remove the mounted CD/DVD by using the <strong>NoMedia</strong> switch.</p>
<h2>Sample Usage</h2>
<p>The usage of the function is quite simple. You can call the function for a single VM</p>
<pre class="urvanov-syntax-highlighter-plain-tag">Set-CDDriveAndAnswer -Name LinuxBox</pre>
<p>This will unmount the CD/DVD from the specific VM. The VM needs to be on the currently connected vSphere Server ($global:defaultviserver)</p>
<p>Or you can use it in a pipeline construct.</p>
<pre class="urvanov-syntax-highlighter-plain-tag">Get-VM | where{Get-CDDrive -VM $_} | Set-CDDriveAndAnswer</pre>
<p>This will find all the VMs that have a CD/DVD mounted, and will unmount the CD/DVD</p>
<p>Enjoy!</p>

]]></content:encoded>
					
					<wfw:commentRss>https://www.lucd.info/2015/10/02/answer-the-question/feed/</wfw:commentRss>
			<slash:comments>31</slash:comments>
		
		
			</item>
		<item>
		<title>Test if the datastore can be unmounted</title>
		<link>https://www.lucd.info/2012/04/15/test-if-the-datastore-can-be-unmounted/</link>
					<comments>https://www.lucd.info/2012/04/15/test-if-the-datastore-can-be-unmounted/#comments</comments>
		
		<dc:creator><![CDATA[LucD]]></dc:creator>
		<pubDate>Sun, 15 Apr 2012 21:29:48 +0000</pubDate>
				<category><![CDATA[datastore]]></category>
		<category><![CDATA[PowerCLI]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[SDRS]]></category>
		<category><![CDATA[SIOC]]></category>
		<category><![CDATA[unmount]]></category>
		<guid isPermaLink="false">http://www.lucd.info/?p=3980</guid>

					<description><![CDATA[Lately I have been playing around with the new Storage related features in [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Lately I have been playing around with the new Storage related features in vSphere 5. One of the novelties is that you can now <strong>unmount</strong> a VMFS datastore and <strong>detach</strong> a SCSI LUN through the API.<br />
To be able to unmount a datastore, some <strong>conditions</strong> have to be met. In the vSphere Client you get an informative popup that tells what is prohibiting the datastore unmount. If not all conditions are met, you can not continue with the unmount.</p>
<p><a href="https://lucd.info/wp-content/uploads/2012/04/Datastore-unmount.png"><img decoding="async" class=" wp-image-3906 alignnone" title="DS unmount" src="https://lucd.info/wp-content/uploads/2012/04/Datastore-unmount.png" alt="" width="421" height="316" /></a></p>
<p>Nice feature, but what for those of us that want to automate this ?</p>
<p><span style="background-color: #ffff00;"><strong>Update October 28th 2012</strong></span>: Take into account that the datastorecluster is not connected to a host that is part of a cluster. Skip the HA heartbeat test.</p>
<p><span style="background-color: #ffff00;"><strong>Update April 23th 2012</strong></span>: Use the <a href="https://pubs.vmware.com/vsphere-50/topic/com.vmware.wssdk.apiref.doc_50/vim.ClusterComputeResource.html#retrieveDasAdvancedRuntimeInfo" target="_blank">RetrieveDasAdvancedRuntimeInfo</a> method to find the actual datastores that are used for the heartbeat.</p>
<p><span id="more-3980"></span></p>
<h2>What to look for ?</h2>
<p>From the popup, it is quite obvious what specific feature can prohibit the unmount of a datastore.</p>
<p>But if you look at Cormac&#8217;s post called <a href="https://blogs.vmware.com/vsphere/2012/02/what-could-be-writing-to-a-vmfs-when-no-virtual-machines-are-running.html" target="_blank">What could be writing to a VMFS when no Virtual Machines are running?</a>, there are a couple of other settings that might influence the ability to unmount a datastore.</p>
<p>In Cormac&#8217;s post you&#8217;ll find that a <strong>Distributed Virtual Switch configuration file</strong> or the presence of a <strong>scratch partition</strong> might also cause IO that would prevent a datastore unmount.</p>
<p>So I decided to expand the function with a check for those 2 additional causes.</p>
<h2>The script</h2>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">function Get-DatastoreUnmountStatus{
  &lt;#
.SYNOPSIS  Check if a datastore can be unmounted.
.DESCRIPTION The function checks a number of prerequisites
  that need to be met to be able to unmount a datastore.
.NOTES  Author:  Luc Dekens
.PARAMETER Datastore
  The datastore for which you want to chekc the conditions.
  You can pass the name of the datastore or the Datastore
  object returned by Get-Datastore
.EXAMPLE
  PS&gt; Get-DatastoreUnmountStatus -Datastore DS1
.EXAMPLE
  PS&gt; Get-Datastore | Get-DatastoreUnmountStatus
#&gt;
  param(
    [CmdletBinding()]
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)]
    [PSObject[]]$Datastore
  )

  process{
    foreach($ds in $Datastore){
      if($ds.GetType().Name -eq &quot;string&quot;){
        $ds = Get-Datastore -Name $ds
      }
      $parent = Get-View $ds.ExtensionData.Parent
      New-Object PSObject -Property @{
        Datastore = $ds.Name
        # No Virtual machines
        NoVM = $ds.ExtensionData.VM.Count -eq 0
        # Not in a Datastore Cluster
        NoDastoreClusterMember = $parent -isnot [VMware.Vim.StoragePod]
        # Not managed by sDRS
        NosDRS = &amp;{
          if($parent -is [VMware.Vim.StoragePod]){
            !$parent.PodStorageDrsEntry.StorageDrsConfig.PodConfig.Enabled
          }
          else {$true}
        }
        # SIOC disabled
        NoSIOC = !$ds.StorageIOControlEnabled
        # No HA heartbeat
        NoHAheartbeat = &amp;{
          $hbDatastores = @()
          $cls = Get-View -ViewType ClusterComputeResource -Property Host |
          where{$_.Host -contains $ds.ExtensionData.Host[0].Key}
          if($cls){
            $cls | %{
              (                $_.RetrieveDasAdvancedRuntimeInfo()).HeartbeatDatastoreInfo | %{
                $hbDatastores += $_.Datastore
              }
            }
            $hbDatastores -notcontains $ds.ExtensionData.MoRef
          }
          else{$true}
        }
        # No vdSW file
        NovdSwFile = &amp;{
          New-PSDrive -Location $ds -Name ds -PSProvider VimDatastore -Root '\' | Out-Null
          $result = Get-ChildItem -Path ds:\ -Recurse |
          where {$_.Name -match '.dvsData'}
          Remove-PSDrive -Name ds -Confirm:$false
          if($result){$false}else{$true}
        }
        # No scratch partition
        NoScratchPartition = &amp;{
          $result = $true
          $ds.ExtensionData.Host | %{Get-View $_.Key} | %{
            $diagSys = Get-View $_.ConfigManager.DiagnosticSystem
            $dsDisks = $ds.ExtensionData.Info.Vmfs.Extent | %{$_.DiskName}
            if($dsDisks -contains $diagSys.ActivePartition.Id.DiskName){
              $result = $false
            }
          }
          $result
        }
      }
    }
  }
}</pre><p></p>
<h4>Annotations</h4>
<p><strong>Line 24-26</strong>: A simple Object By Name implementation. It allows to pass the datastores by name or by object to the function.</p>
<p><strong>Line 27</strong>: The parent of the datastore is used in a couple of tests further on in the script</p>
<p><strong>Line 31</strong>: Test if there are any VMs or Templates present on the datastore</p>
<p><strong>Line 33</strong>: Test if the datastore belongs to a Storage Cluster</p>
<p><strong>Line 35-40</strong>: Test if the datastore is managed by Storage DRS. The Enabled property in the <a href="https://pubs.vmware.com/vsphere-50/topic/com.vmware.wssdk.apiref.doc_50/vim.storageDrs.PodConfigInfo.html" target="_blank">StorageDrsPodConfigInfo</a> object is used as the indicator.</p>
<p><strong>Line 42</strong>: Test if SIOC is enabled for the datastore</p>
<p><strong>Line 44-57</strong>: Test if the datastore is one of the Heartbeat Datastores. The test first gets all the clusters known in vCenter and then filters out those clusters that have hosts on which the datastore is visible.</p>
<p><strong>Line 48,56</strong>: If the host is not part of a cluster, the HA heartbeat test is considered as successful.</p>
<p><strong>Line 59-65</strong>: Test to see if the is a Distributed Virtual Switch configuration file present on the datastore.</p>
<p><strong>Line 67-77</strong>: Test if the datastore is used as a scratch partition.</p>
<h2>Sample usage</h2>
<p>The function can be used in a stand-alone or in a pipeline construct.</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-DatastoreUnmountStatus -Datastore DS1</pre><p></p>
<p>The pipeline construct could look like this</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Get-Datastore DS* | Get-DatastoreUnmountStatus</pre><p></p>
<p>The function produces 1 object per datastore. Each of the properties in the object represents 1 test that the function executes. Something like this.</p>
<p><a href="https://lucd.info/wp-content/uploads/2012/04/dsUnmountout.png"><img loading="lazy" decoding="async" class=" wp-image-3906 alignnone" title="DS unmount output" src="https://lucd.info/wp-content/uploads/2012/04/dsUnmountout.png" alt="" width="576" height="130" /></a></p>
<p>The output shows us that we will probably not be able to unmount datastore DS1, because:</p>
<ul>
<li>the datastore is part of a Datastore Cluster</li>
<li>the datastore is managed by Storage DRS</li>
<li>there are VMs (or Templates) on the datastore</li>
<li>the datastore is used by the Datastore Heartbeat</li>
<li>the datastore has SIOC enabled</li>
</ul>
<p>The functions to solve this and allow an unmount of the datastore will follow in some future posts.</p>
<p>Enjoy !</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.lucd.info/2012/04/15/test-if-the-datastore-can-be-unmounted/feed/</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
	</channel>
</rss>
