Jump to content
  • Citrix App Layering PVS vDisk Merge Script


    Rob Zylowski

    Overview 

    Citrix App Layering Publishes new versions of PVS images to a PVS Server as a Full vDisk.  Some customers prefer to manage vDisk changes using PVS versioning. This sample script will convert App Layering Published image vDisks into a versioning format on the PVS server using the Image Name as the vDisk Name.

    When using this script, your vDisk Store will resemble this, showing a single entry for each App Layering Image that you publish to PVS:

    image.png

    Then, if you open versioning, each App Layered vDisk will be shown as a version with a type of “Merged base”.

    image.png

    This then allows administrators to update targets by just promoting the new version.

    The script is designed to run as necessary, and it will process all vDisks only by modifying vDisks named using the App Layering Date_Time format that is also not assigned to a device or locked.

    Therefore, the following vDisk:

    Win10PVSUser_2022-01-20_18-17-58 

    Would become a version of a VDisk named:

    Win10PVSUser

    This script should work fine for customers that previously used the Citrix App Layering 4.x: PVS Connector Script to Convert VHD to VHDX script to perform the same process along with VHD to VHDX conversion.  

    This provides a mechanism to support versioning now that connector scripts have been removed from App Layering.

    Limitations

    To use this script, there are several important limitations to be aware of:

    • The full path of the vDisk cannot be longer than 127 characters. This includes the store path.

    Warning

    Citrix Solution Architects provide this example script as a useful extension to Citrix App Layering. This script has been tested in our labs but not by our QA department, and it is not supported as part of the Citrix App Layering Product. Please test thoroughly and implement with care.

    Be aware that the script is designed to process all vDisks on a PVS Server that conforms to the App Layering standard for naming.  For example:

    Win2016PVS_2023-12-15_08-57-35

    The disk will be processed if the vDisk name matches the Date_Time format.  The script will check to ensure no device targets have the disk assigned.  If there is an assignment, the vDisk will be skipped,

    LEGAL DISCLAIMER

    This software/sample code is provided to you “AS IS” with no representations, warranties, or conditions of any kind. You may use, modify, and distribute it at your own risk. CITRIX DISCLAIMS ALL WARRANTIES WHATSOEVER, EXPRESS, IMPLIED, WRITTEN, ORAL OR STATUTORY, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NONINFRINGEMENT. Without limiting the generality of the foregoing, you acknowledge and agree that (a) the software/sample code may exhibit errors, design flaws or other problems, possibly resulting in loss of data or damage to property; (b) it may not be possible to make the software/sample code fully functional; and (c) Citrix may, without notice or liability to you, cease to make available the current version and/or any future versions of the software/sample code. In no event should the software/code be used to support of ultra-hazardous activities, including but not limited to life support or blasting activities. NEITHER CITRIX NOR ITS AFFILIATES OR AGENTS WILL BE LIABLE, UNDER BREACH OF CONTRACT OR ANY OTHER THEORY OF LIABILITY, FOR ANY DAMAGES WHATSOEVER ARISING FROM USE OF THE SOFTWARE / SAMPLE CODE, INCLUDING WITHOUT LIMITATION DIRECT, SPECIAL, INCIDENTAL, PUNITIVE, CONSEQUENTIAL OR OTHER DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Although the copyright in the software/code belongs to Citrix, any distribution of the code should include only your own standard copyright attribution and not that of Citrix. You agree to indemnify and defend Citrix against any and all claims arising from your use, modification or distribution of the code.

    Infrastructure Requirements

    The following infrastructure components/configurations are required:

    • PowerShell Execution Policy must be set to remote-signed or unrestricted.
    • The account used to run the script must be a local administrator and PVS administrator, and it must have modified rights to the script folder and the PVS store.

    Setting Up the Script

    1. The first step when setting up the script is to create a folder on the PVS server. A folder off the root with no spaces in the name is recommended but not required.
    2. If the script file is blocked, unblock it.

    Test

    Testing the script on test vDisks on a test PVSServer is critical. Test all the way to deploying targets using the versioned vDisk.

    The script creates a detailed log.  Review the log after each test.

    Summary of Script Logic

    The following high-level logic is used in the script

    1. Load the PVS PowerShell Module
    2. Get All The vDisks on the Server (Disk Locators)
    3. Process each vDisk
      1. Get Disk Information and any Device Targets with the disk assigned
        1. If the disk is assigned or locked, then skip it
      2. Figure out if it’s a VHD or VHDX
      3. Determine the Image Name from the vDisk name using REGEX
        1. "_([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})$"
      4. Look for an Existing vDisk name matching our Image Name
      5. If there is none, then create one using this first vDisk
        1. Capture the vDisk properties
        2. Remove the vDisk from the console (Do not delete the vDisk)
          1. If it can't be removed, skip it
        3. Delete any pvp and lok files for this vDisk
        4. Rename the VHD file to the format
          1. ImageName.vhd/vhdx
        5. Make sure the rename worked
          1. If not, skip this vDisk
        6. Create a new Disk Locator (vDisk in Console) for the ImageName vDisk
          1. If this fails, skip this vDisk
        7. Set the saved properties on the new vDisk
        8. Check to make sure the settings were saved and log the results
      6. If there was already a vDisk for the ImageName, then add this new vDisk as a new version
        1. Export the new vDisks info
          1. This creates a manifest xml file
        2. Get the vDisk’s current versions
        3. Find the next available version number
        4. Modify the manifest with the new disk name and set the settings to Merged Base and Test
        5. Copy existing vDisk Settings
        6. Remove the vDisk
          1. Format ImageName.VersionNumber.vhd/vhdx
          2. If the remove fails skip to next vDisk
        7. Delete the lok,PVP, and XML files for the old name of the vDisk
        8. Rename the vDisk to the new format
        9. Add a PVS Versions using the new vDisk name (ImageName)
          1. This is the merge
          2. If the add fails skip this vDisk
        10. Delete the manifest file
      7. Log any PowerShell Errors found during processing

    I have provided the script here below so that it can be copied and saved for your use.

    #Script file vdisk_merge.ps1
    #This script was developed as an example script by Citrix Solution Architect Rob Zylowski
    #This script allows app layered images published to PVS to be merged as versions within a PVS vDisk
    #This allows admins to manage new versions of vDisks as PVS versions
    
    <# *****************************************   LEGAL DISCLAIMER   *****************************************
    This software / sample code is provided to you “AS IS” with no representations, warranties or conditions of any kind. 
    You may use, modify and distribute it at your own risk. CITRIX DISCLAIMS ALL WARRANTIES WHATSOEVER, EXPRESS, IMPLIED, 
    WRITTEN, ORAL OR STATUTORY, INCLUDING WITHOUT LIMITATION WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, 
    TITLE AND NONINFRINGEMENT. Without limiting the generality of the foregoing, you acknowledge and agree that (a) the 
    software / sample code may exhibit errors, design flaws or other problems, possibly resulting in loss of data or damage to 
    property; (b) it may not be possible to make the software / sample code fully functional; and (c) Citrix may, without notice 
    or liability to you, cease to make available the current version and/or any future versions of the software / sample code. 
    In no event should the software / code be used to support of ultra-hazardous activities, including but not limited to life 
    support or blasting activities. NEITHER CITRIX NOR ITS AFFILIATES OR AGENTS WILL BE LIABLE, UNDER BREACH OF CONTRACT OR ANY 
    OTHER THEORY OF LIABILITY, FOR ANY DAMAGES WHATSOEVER ARISING FROM USE OF THE SOFTWARE / SAMPLE CODE, INCLUDING WITHOUT 
    LIMITATION DIRECT, SPECIAL, INCIDENTAL, PUNITIVE, CONSEQUENTIAL OR OTHER DAMAGES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 
    DAMAGES. Although the copyright in the software / code belongs to Citrix, any distribution of the code should include only 
    your own standard copyright attribution, and not that of Citrix. You agree to indemnify and defend Citrix against any and all
    claims arising from your use, modification or distribution of the code.
    ********************************************************************************************************** #>
    
    #Version 1.0 2-1-2024
    
    function Get-ScriptDirectory
    {
      $Invocation = (Get-Variable MyInvocation -Scope 1).Value
      Split-Path $Invocation.MyCommand.Path
    }
    
    Function LogLine($strLine)
    {
    	Write-Host $strLine
    	$global:StrTime = Get-Date -Format "MM-dd-yyyy-HH-mm-ss-tt"
    	"$global:StrTime - $strLine " | Out-file -FilePath $LogFile -Encoding ASCII -Append
    }
    
    Function FormatErrors()
    {
    	$NumToProcess = $Error.Count - 1
    	For ($i = $NumToProcess; $i -gt -1; $i-- )
    	{
    		If (!($Error[$i] -Contains "disklocatorTest"))
    		{
    			logline "========================================================================" 
    			$MyError = "Error: " + $Error[$i].InvocationInfo.PositionMessage + "Exception: " + $Error[$i]
    			logline $MyError
    		}
    	}
    	$Error.Clear()
    }
    
    
    function IsDateTime {
        param(
            [string]$vdiskname
        )
    
        $pattern = '\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}'
        if ($vdiskname -match $pattern) {
            $returnvalue = $true
        } else {
            $returnvalue = $false
        }
        $returnvalue
    }
    
    
    #Get the directory where the script is installed
    $ScriptSource = Get-ScriptDirectory
    
    #Create a logline folder and file
    $LogFileQualifier = Get-Date -Format "MM-dd-yyyy-HH-mm-tt"
    $LogFolder = "$ScriptSource\Logs"
    If (!(Test-Path "$LogFolder"))
    {
    	mkdir "$LogFolder" >$null
    }
    $LogFile = "$LogFolder\vDiskMerge-$LogFileQualifier-log.txt"
    
    logline "========================================================================"
    logline "           Running vDisk Merge Script Version 1.0"
    logline "========================================================================"
    logline ""
    
    $FormatedErrors = ""
    
    #=========================================================================
    #Import PowerShell Module
    #=========================================================================
    
    $PVS_Server = $env:computername
    Logline "Script is running on PVS Server [$PVS_Server]"
    
    Try{
        Import-Module 'C:\Program Files\Citrix\Provisioning Services console\Citrix.PVS.SnapIn.dll' -ErrorAction Stop
    } Catch {
        logline "The vDisk Merge script has failed because the PVS PowerShell module could not be loaded"
        logline "PVS PowerShell Snap-In Not Found on $env:computername.  Script terminated."
    	exit
    }
    
    #Now Lets get all the disk locators on the server so we can look for vDisks with the App Layering Format
    Logline "Getting all the vDisks on this server"
    $VHDDiskLocators = Get-PVSDisklocator -ServerName $PVS_Server
    Logline "The number of vDsks found was [$($VHDDiskLocators.count)]"
    
    Foreach ($MyVHDDiskLocator in $VHDDiskLocators)
    {
        
        #First lets determine if this vDisk is in the App Layeirng Format.  This means it has a date_time label on the vdisk.
        #If it is not app layerd format we will skip
        $vDiskName = $MyVHDDiskLocator.Name
        if(!(isDateTime $vdiskName))
        {
            Logline "vDisk named [$vdiskName] does not need to be processed and will be skipped"
            continue
        }
    
    	logline "Processing vDisk [$vdiskName]"
    
    	$VHDX_DiskLocator = $MyVHDDiskLocator.diskLocatorId
    	Logline "Using DiskLocatorId [$VHDX_DiskLocator]"
    
        #Lets make sure ths vDisk has not already been assigned.  If it has we can do nothing with it.
        $DiskInfo = Get-PvsDiskInfo -DiskLocatorId $VHDX_DiskLocator
        $AssignedDevices = Get-PVSDevice -DiskLocatorId $VHDX_DiskLocator.guid
        if (($AssignedDevices.Count -gt 0) -or ($DiskInfo.Locked))
        {
            Logline "vDisk named [$vdiskName] is assigned to at least one device and will be skipped"
            continue 
        }
        else
        {
             Logline "vDisk named [$vdiskName] is NOT assigned and it will be merged"
        }
    
        #Is it a vhd or vhdx
        if ($DiskInfo.VHDX -eq $true)
        {
            $DiskType="vhdx"
        }
        else
        {
            $DiskType="vhd"
        }
        Logline "vDisk type is [$DiskType]"
    
        #Lets Get the image Name from the disk file name
        $dateTimeRegex = "_([0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})$"
        $ImageName = $vDiskName -replace $dateTimeRegex,""
    
        Logline "The Image Name is [$ImageName]"
    
    	$storePath = (Get-PvsStore -StoreId $MyVHDDiskLocator.StoreId).Path
    
    	logline "Changing to the store directory: $storePath"
    	Push-Location $storePath -StackName $LOCATION_STACK_NAME
    		
    	#First lets see if there is a vDisk disklocator with our image name already
    	$siteId = $MyVHDDiskLocator.SiteId
    	$storID = $MyVHDDiskLocator.StoreId
        $disklocatorTest  = $null
        
        $bvDiskIsFirstImage = $false
    
        #If we cant get the ImageName as a vDisk we assume its the first time we are trying to add the image
        Try {
    	    $disklocatorTest = Get-PvsDiskLocator -DiskLocatorName "$imageName" -SiteId $siteId -StoreId $storID -ErrorAction:Ignore
        }
        Catch {
            $bvDiskIsFirstImage = $true
        }
    
        #======================
        #If this is the first vDisk for this image Template we need to convert to the Image Template and set the first version
        #======================
    
    	if ($bvDiskIsFirstImage)
    	{
    		logline "No vDisk found matching our image name [$imageName].  This will be the first version."
    		
            #Now need to remove the vDisk, rename the vhd and add it back in to PVS.
            #First we capture the vDisk settings so we can put them back
    		$bRebaseVersion = $false
    				
    		$dl_Name = $imageName 
    		$dl_Site = $MyVHDDiskLocator.SiteName
    		$dl_Store = $MyVHDDiskLocator.StoreName
    		$dl_Description = $MyVHDDiskLocatorr.Description
    		$dl_MenuText = $MyVHDDiskLocator.MenuText
    		$dl_ServerName = $MyVHDDiskLocator.ServerName
    		$dl_RebalanceEnabled = $MyVHDDiskLocator.RebalanceEnabled
    		$dl_RebalanceEnabledPercent = $MyVHDDiskLocator.RebalanceTriggerPercent
    		$dl_SubnetAffinity = $MyVHDDiskLocator.SubnetAffinity
    				
    		#Delete the original disklocator
    		logline "Removing the Disk Locator with ID $VHDX_DiskLocator"
            Try {
    		    Remove-PvsDiskLocator -DiskLocatorId $VHDX_DiskLocator -Confirm:$false
            }
            Catch
            {
                Logline "We coudl not remove the existing vDsik Disklocator"
                Logline $error[0]
                Logline "Skipping this vDisk"
                Continue
            }
    				
    		#Delete the PVP and lok files
    		$delFileBase = $MyVHDDiskLocator.DiskLocatorName
            if (test-path "$storePath\$delFileBase.lok")
            {
    		    logline "Removing $storePath\$delFileBase.lok"
    		    Remove-Item "$storePath\$delFileBase.lok"
            }
            if (test-path "$storePath\$delFileBase.pvp")
            {
    		    logline "Removing $storePath\$delFileBase.pvp"
    		    Remove-Item "$storePath\$delFileBase.pvp"
    		}
    	
    		#Now rename the vhd file to imagename.vhd or imagename.vhdx
    		logline "Changing to directory: $storePath"
    		Push-Location $storePath -StackName $LOCATION_STACK_NAME
    		$MyVHDXpath = "$storePath\$vdiskName.$DiskType"
            $MyNewDiskPath = "$storePath\$imageName.$DiskType"
    				
    		logline "Renaming the disk file from [$MyVHDXpath] to [$MyNewDiskPath]"
    		ren $MyVHDXpath $MyNewDiskPath
    		
            #Make sure the rename worked
    		if (!(Test-Path $MyNewDiskPath))
    		{
    			logline "***Warning the rename failed.  skipping this vDisk"
    			continue
    		}
    				
    		#Now  add the new one
    		logline "Creating a disk locator for our VHD/VHDX file"
            if ($diskType -eq "vhdx")
            {
    		    if ($dl_MenuText -eq $null){$dl_MenuText=""}
    		    if ($dl_Description -eq $null){$dl_Description=""}
    		    if ($dl_ServerName -eq $null){$dl_ServerName=""}
    		    if ($dl_ServerName -eq "")
    		    {
    			    New-PvsDiskLocator `
    			    -DiskLocatorName "$dl_Name" `
    			    -SiteName "$dl_Site" `
    			    -StoreName "$dl_Store" `
    			    -VHDX 
    		    }
    		    else
    		    {
    			    New-PvsDiskLocator `
    			    -DiskLocatorName "$dl_Name" `
    			    -SiteName "$dl_Site" `
    			    -StoreName "$dl_Store" `
    			    -ServerName "$dl_ServerName" `
    			    -VHDX 
                }
    		}
            else
            {
                if ($dl_MenuText -eq $null){$dl_MenuText=""}
    		    if ($dl_Description -eq $null){$dl_Description=""}
    		    if ($dl_ServerName -eq $null){$dl_ServerName=""}
    		    if ($dl_ServerName -eq "")
    		    {
    			    New-PvsDiskLocator `
    			    -DiskLocatorName "$dl_Name" `
    			    -SiteName "$dl_Site" `
    			    -StoreName "$dl_Store" `
    		    }
    		    else
    		    {
    			    New-PvsDiskLocator `
    			    -DiskLocatorName "$dl_Name" `
    			    -SiteName "$dl_Site" `
    			    -StoreName "$dl_Store" `
    			    -ServerName "$dl_ServerName" `
    		    }
            }
    		if (!($?))
    		{
    			logline "***Warning the new disk created for our image was could not be added as a vDisk.  Exiting Script"
    			logline "using settings dl_name:$dl_Name dl_site:$dl_Site dl_store:$dl_store dl_server:$dl_ServerName"
    			continue
    		}
    				
    		$NewDiskLocator = Get-PvsDiskLocator -DiskLocatorName $dl_Name -SiteName $dl_Site -StoreName $dl_Store
    		$newDiskLocatorId = $NewDiskLocator.DiskLocatorId
    		logline "The new DiskLocator Id for the renamed image [$imageName] is $newDiskLocatorId"
    		$storePath = (Get-PvsStore -StoreId $NewDiskLocator.StoreId).Path
    
            #Now lets put back the settings we saved
    				
    		$o = Get-PvsDisk -DiskLocatorId $newDiskLocatorId 
    		$o.ActivationDateEnabled = $VD_ActivationEnabled 
    		$o.HaEnabled = $VD_HAEnabled 
    		$o.AdPasswordEnabled = $VD_ADPasswordEnabled 
    		$o.PrinterManagementEnabled = $VD_PrinterManagementEnabled 
    		$o.WriteCacheType = $VD_WritecacheType 
    		$o.WriteCacheSize = $VD_WriteCacheSize 
    		$o.LicenseMode = $VD_LicenseMode
            #WriteCacheType = 9 is standard mode.  use 0 for private mode
            $o.WriteCacheType = 9
    		if ($DiskType -eq "vhdx")
    		{
    			$o.VHDX = $true
    		}
    				
    		#get the vhd/vhdx path
    		$OriginalFileO = $o.OriginalFile
    		if ($OriginalFileO -eq $null){$OriginalFileO = ""}
    		if ($OriginalFileO.Contains("."))
    		{
    			$MyVHDXPath = $OriginalFileO
    			logline "The new VHDX path for our vDisk is [$MyVHDXPath]"
    		}
    		else
    		{
    			logline "We were not able to find the imported vDisk after the VHDX conversion -- skipping to next vDisk"
    			logline "========================================================================"
                continue
    		}
    				
    		logline "We will now update the vDisk settings to match previous settings"
    		#Change the disk to use the new disk locator
    		Set-PvsDisk $o 
    
    		#Check to make sure it changed
    		$NewDiskAfterChange2 = Get-PvsDisk -DiskLocatorId $NewDiskLocator.DiskLocatorId
    		logline "Checking new path for VHDXPath [$MyVHDXPath]"
    				
    		$OriginalFileNew2 = $NewDiskAfterChange2.OriginalFile
    		if ($OriginalFileNew2 -eq $null){$OriginalFileNew2 = ""}
    		if (!($OriginalFileNew2.Contains(".")))
    		{
    			logline "We were not able to find the vDisk after converting to VHDX -- skipping to next vDisk"
    			logline "========================================================================"
                continue
    		}
    				
    		logline "Internal Name:$OriginalFileNew2"
    		if ($OriginalFileNew2 -ne $MyVHDXPath)
    		{
    			#We failed
    			logline "The vDisk was imported as $OriginalFileNew2.  Please remove the vDisk and add it back in"
    			continue
    		}
    		else
    		{
    			#We succeeded
    			logline "Success - The new vDisk was imported as $ImageName."
    		}
    	}		
        else
    	{
    		$bRebaseVersion = $true
    	}
    	
        #=======================
        #If we already hasd the image version we need to add this vDisk to it as a new version
        #=======================
    
    	if ($bRebaseVersion)
    	{
            Logline "Rebasing vDisk [$vDiskName] to ImageName [$ImageName]"
    
    		Export-PvsDisk -DiskLocatorId $MyVHDDiskLocator.DiskLocatorId
    
    		$existingDiskLoc = Get-PvsDiskLocator -SiteId $MyVHDDiskLocator.SiteId -StoreId $MyVHDDiskLocator.StoreId -DiskLocatorName $ImageName
    			
    		logline "Getting existing Disk Versions"
            $ExistingDiskBaseName = $ImageName
    		$existingDiskVersions = Get-PvsDiskVersion -DiskLocatorId $existingDiskLoc.DiskLocatorId
    		$nextVersionNum = ($existingDiskVersions | Measure -Property Version -Maximum).Maximum + 1
    
    		#Edit the disk manifest for our versiosn import of the new version
    		$ManifestFile = "$($MyVHDDiskLocator.Name).xml"
    			
    		logline "Editing disk manifest file [$ManifestFile] to use version [$NextVersionNum]"
    
    		[xml]$manifest = Get-Content -Path "$ManifestFile"
    
    		$newDesc = "Created from published disk $($manifest.versionManifest.version.diskFileName)"
    
    		$manifest.versionManifest.version.type = "4"        # Merged Base - necessary so previous versions can be deleted
    		$manifest.versionManifest.version.access = "7"      # Test - as opposed to Production (0) or Maintenance
    		$manifest.versionManifest.version.versionNumber = "$NextVersionNum"
    		if ($DiskType -eq "vhdx")
    		{
    			$manifest.versionManifest.version.diskFileName = "$ExistingDiskBaseName.$NextVersionNum.vhdx"
    		}
    		else
    		{
    			$manifest.versionManifest.version.diskFileName = "$ExistingDiskBaseName.$NextVersionNum.vhd"
    		}
    		$manifest.versionManifest.version.description = "$newDesc"
    
    		$outPath = "$(Convert-Path -Path ".")\$ImageName.xml"
    		logline "Writing new disk manifest file '$outPath'"
    
    		$manifest.Save($outPath)
    		    
    		# Copy settings from the vDisk
    		$diskLocks = Get-PvsDiskLocatorLock -DiskLocatorId $existingDiskLoc.DiskLocatorId
    		if ($diskLocks.Length -le 0) {
    		    logline "Copying configuration settings to existing vDisk: $existingDiskBaseName"
    
    		    $newDisk = Get-PvsDisk -DiskLocatorId $MyVHDDiskLocator.DiskLocatorId
    		    $existingDisk = Get-PvsDisk -DiskLocatorId $existingDiskLoc.DiskLocatorId
    
    		    $existingDisk.PrinterManagementEnabled = $newDisk.PrinterManagementEnabled
    		    $existingDisk.AdPasswordEnabled = $newDisk.AdPasswordEnabled
    		    $existingDisk.WriteCacheType = $newDisk.WriteCacheType
    		    $existingDisk.LicenseMode = $newDisk.LicenseMode
    			$OriginalFileED = $existingDisk.OriginalFile
    			if ($OriginalFileED -eq $null){$OriginalFileED = $existingDisk.OriginalFile}
    			if ($OriginalFileED -eq $null){$OriginalFileED = ""}
    			if (!($OriginalFileED.Contains(".")))
    			{
    				logline "We were not able to find the vDisk file name for versioning -- skipping vDisk"
    				continue
    			}
    			
    		} else {
    		    logline "WARNING: vDisk '$existingDiskBaseName' is locked, configuration settings will not be changed!"
    		}
    			
    		logline "Removing the disk locator with id [" + $MyVHDDiskLocator.DiskLocatorId + "]"
    		Try {
                Remove-PvsDiskLocator -DiskLocatorId $MyVHDDiskLocator.DiskLocatorId
            }
            Catch
            {
                logline "We could not remove the vDisk with disk locator [$($MyVHDDiskLocator.DiskLocatorId)] -- skipping vDisk"
                Logline $error[0]
    			continue
            }
    
    		#Now lets rename the pvp and vhdx to our version numbering naming scheme
    		$NewDiskBaseName = $MyVHDDiskLocator.Name
    		logline "Renaming vDisk files to use version number [$NextVersionNum]"
    
    		if (Test-Path "$NewDiskBaseName.lok")
            {
                Remove-Item "$NewDiskBaseName.lok"
            }
            if (Test-Path "$NewDiskBaseName.xml")
            {
    		    Remove-Item "$NewDiskBaseName.xml"
            }
            if (Test-Path "$NewDiskBaseName.pvp")
            {
    		    copy-Item "$NewDiskBaseName.pvp" "$ExistingDiskBaseName.$NextVersionNum.pvp" -Force
                remove-item "$NewDiskBaseName.pvp"
            }
            if (Test-Path "$NewDiskBaseName.$DiskType")
            {
                if (!(Test-Path "$ExistingDiskBaseName.$NextVersionNum.$DiskType"))
                {
    		        rename-Item "$NewDiskBaseName.$DiskType" "$ExistingDiskBaseName.$NextVersionNum.$DiskType"
                }
            }
    					
    		Try {
                Add-PvsDiskVersion -DiskLocatorId $existingDiskLoc.DiskLocatorId.guid
            }
            Catch
            {
                logline "vDisk $($MyVHDDiskLocator.Name) could not be added with version $nextVersionNum of vDisk $existingDiskBaseName"
            }
            logline "vDisk $($MyVHDDiskLocator.Name) successfully converted to version $nextVersionNum of vDisk $existingDiskBaseName"
    		Remove-Item "$existingDiskBaseName.xml" -ErrorAction Continue
    	}
    }
    Push-Location -Path $ScriptSource
    logline "========================================================================"
    logline "Errors During Script"
    logline "========================================================================"
    FormatErrors
    logline "========================================================================"

     

     


    User Feedback

    Recommended Comments

    There are no comments to display.



    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

×
×
  • Create New...