Jump to content
Updated Privacy Statement
  • 0

Add disk to VM PowerShell script issue


Question

Hello,

I want to use a PowerShell script, to each VM whose name starts with W10PRD, to add a 10 Gb disk that will be used as a persistent disk in an MCS scenario and expand the RAM to 16 Gb and the vCPU to 4.
 I created the script below for this purpose. This script works fine until creating the disks. So things start to go wrong from line 76 onwards.

I then get this error:
Error occurred while processing VM W10PRD1003: Cannot bind parameter 'SR'. Cannot convert the "@{uuid=<UUID of Local Storage SR>; name_label=Local storage}" value of type "Selected.XenAPI.SR" to type "XenAPI.XenRef`1[XenAPI.SR]".

# Variables
$hostName = "xenserver host name"
$Username = "admin_account"
$Password = "admin_password"
$vmPrefix = "W10PRD"
$storageRepoName = "Local storage"
$diskSize = 10GB # 10 GB disk
$diskLabel = "Persistent-disk"
$RAMinGB = 16
$RAMinBytes = $RAMinGB*1073741824
$vCPU = 4
$vCPUatStartup = 4
$vCPUMax = 4

# Import XenServer module and connect
Import-Module XenServerPSModule
  Try {
        $Session = Connect-XenServer -Url https://$hostName -UserName $username -Password $password -NoWarnCertificates -SetDefaultSession
    } Catch [XenAPI.Failure] {
        [string]$PoolMaster = $_.Exception.ErrorDescription[1]  
        Write-Host -ForegroundColor Red "$($Pools.$Pool) is slave, Master was identified as $PoolMaster, trying to connect"
        $Pools.Pool = $PoolMaster
        $Session = Connect-XenServer -url "https://$PoolMaster" -UserName $username -Password $password -NoWarnCertificates -SetDefaultSession
    }

# Search for XenServer host with specified name
$xenHost = Get-XenHost | Where-Object {
    $_.name_label -eq $hostName
} | Select-Object uuid, name_label

# Show saved Host UUID and name
$xenHost


if ($host -eq $null) {
    Write-Output "XenServer host not found."
    return
}

# Get all VM's on speciefied host that starts with the VMPrefix
$vms = Get-XenVM | Where-Object {
    $_.is_a_template -eq $False -and 
    $_.is_a_snapshot -eq $False -and
    $_.name_label -like "$vmPrefix*"
} | Select-Object uuid, name_label

# Show saved VM UUIDs and Names
$vms

# Get the storage repository by name
$storageRepoUUID = Get-XenSR | Where-Object {
    $_.name_label -like "$storageRepoName"
} | Select-Object uuid, name_label -First 1

if ($storageRepoUUID -eq $null) {
    Write-Output "Storage repository not found."
    return
}

# Show  saved SR UUID and Name
$storageRepoUUID

foreach ($vm in $vms) {
    $dynamicMin = $RAMinBytes
    $dynamicMax = $RAMinBytes
    $staticMin = $RAMinBytes
    $staticMax = $RAMinBytes

    Set-XenVM -Name $vm.name_label -Memory $RAMinBytes
 }

foreach ($vm in $vms) {
    Set-XenVM -Name $vm.name_label -VCPUsAtStartup $vCPUatStartup -VCPUsMax $vCPUMax
}

foreach ($vm in $vms) {
    # Create a new virtual disk (VDI)
    try {
    $vdi = New-XenVDI -NameLabel $diskLabel -VirtualSize $diskSize -SR $storageRepoUUID -ReadOnly $false

        if ($vdi -eq $null) {
            throw "Failed to create VDI for VM: $($vm.name_label)"
        }
      

        # Create a virtual disk drive (VBD) connecting the VDI to the VM
        $vbd = New-XenVBD -VM $vm.uuid -VDI $vdi.uuid -Device 2 -Bootable $false -Mode RW -Type Disk

        if ($vbd -ne $null) {
            Write-Output "Added a 2GB disk to VM: $($vm.name_label) on repository: $storageRepoName"
        } else {
            Write-Output "Failed to attach VDI to VM: $($vm.name_label)"
        }
    } catch {
        Write-Output "Error occurred while processing VM $($vm.name_label): $($_.Exception.Message)"
    }
}

# Close XenServer Connection
Disconnect-XenServer


Who knows what is wrong with this script, or knows a better option for creating 400 disks on 400 VMs?

Link to comment

6 answers to this question

Recommended Posts

  • 0
Posted (edited)

Hi Konstantina, thank you for your response.
Do you mean that I have to adjust the script block under this "# Get the storage repository by name"?
# Get the storage repository by name
$storageRepoUUID = Get-XenSR | Where-Object {
 $_.name_label -like "$storageRepoName"
} | Select-Object uuid, name_label -First 1
if ($storageRepoUUID -eq $null) {
Write-Output "Storage repository not found."
return }

What will be the correct syntax if I don't want to enter the UUID but want to get it from the $storageRepoName variable?

Thanx in advance!
Also thanks for pointing to the right forum, I'll put it there next time ;-)

Edited by Marcel Zunnebeld1709163163
Link to comment
  • 0

Hi Marcel

Quote

Do you mean that I have to adjust the script block under this  "# Get the storage repository by name"?

Yes you'll need to update it so it fetches the reference of the SR, as opposed to its UUID.

Quote

What will be the correct syntax if I don't want to enter the UUID but want to get it from the $storageRepoName variable?

You can do so using the -Name switch of the Get-XenSR call 👇

So instead of

$storageRepoUUID = [...]

You can write the following:

[...]
# We use the -Name switch to fetch the SR using the value of its name_label field. This also works for other `Get-Xen...` calls!
# We then fetch its opaque_ref, which is what's needed by the New-XenVDI call further down
$storageRepository = Get-XenSR -Name $diskLabel | Select-Object opaque_ref, uuid, name_label
if ($null -eq $storageRepository) {
    Write-Output "Storage repository not found."
    return
}

# Show saved SR reference, UUID, and Name
$storageRepository

[...]
# Here we're now passing the _reference_ to the SR, as opposed to its UUID. The New-XenVDI requires the former as a parameter
$vdi = New-XenVDI -NameLabel $diskLabel -VirtualSize $diskSize -SR $storageRepository.opaque_ref -ReadOnly $false
[...]



Note I didn't use ConvertTo-XenRef because I saw you were logging out the contents of your Get-XenSR call. If in the future you only need the opaque_ref value, you can just do what Konstantina suggested, and run this instead:

$storageRepositoryReference = Get-XenSR -Name $diskLabel | ConvertTo-XenRef



Hope this helps!

  • Like 1
Link to comment
  • 0

Hi Danilo, I have adjusted the script but it does not work yet. This is now the script:
 

#Variables
$hostName = "xenserver host name"
$Username = "admin_account"
$Password = "admin_password"
$vmPrefix = "VDIPRD"
$storageRepoName = "Local storage"
$diskSize = 10GB # 10 GB disk
$diskLabel = "Persistent-disk"

# Import XenServer module and connect
Import-Module XenServerPSModule
  Try {
        $Session = Connect-XenServer -Url https://$hostName -UserName $username -Password $password -NoWarnCertificates -SetDefaultSession
    } Catch [XenAPI.Failure] {
        [string]$PoolMaster = $_.Exception.ErrorDescription[1]  
        Write-Host -ForegroundColor Red "$($Pools.$Pool) is slave, Master was identified as $PoolMaster, trying to connect"
        $Pools.Pool = $PoolMaster
        $Session = Connect-XenServer -url "https://$PoolMaster" -UserName $username -Password $password -NoWarnCertificates -SetDefaultSession
    }

# Search for XenServer host with specified name
$xenHost = Get-XenHost | Where-Object {
    $_.name_label -eq $hostName
} | Select-Object uuid, name_label

# Show saved Host UUID and name
$xenHost

if ($host -eq $null) {
    Write-Output "XenServer host not found."
    return
}

# Get all VM's on speciefied host that starts with the VMPrefix
$vms = Get-XenVM | Where-Object {
    $_.is_a_template -eq $False -and 
    $_.is_a_snapshot -eq $False -and
    $_.name_label -like "$vmPrefix*"
} | Select-Object uuid, name_label

# Show saved VM UUIDs and Names
$vms

# We use the -Name switch to fetch the SR using the value of its name_label field. This also works for other `Get-Xen...` calls!
# We then fetch its opaque_ref, which is what's needed by the New-XenVDI call further down
$storageRepository = Get-XenSR -Name $diskLabel | Select-Object opaque_ref, uuid, name_label
if ($null -eq $storageRepository) {
    Write-Output "Storage repository not found."
    return
}

# Show saved SR reference, UUID, and Name
$storageRepository

foreach ($vm in $vms) {
    # Create a new virtual disk (VDI)
    $vdi = New-XenVDI -NameLabel $DiskLabel -VirtualSize $diskSize -SR $storageRepository.opaque_ref -ReadOnly $false

        if ($vdi -eq $null) {
            throw "Failed to create VDI for VM: $($vm.name_label)"
        }
      
        # Create a virtual disk drive (VBD) connecting the VDI to the VM
        $vbd = New-XenVBD -VM $vm.uuid -VDI $vdi.uuid -Device 2 -Bootable $false -Mode RW -Type Disk

        if ($vbd -ne $null) {
            Write-Output "Added a 2GB disk to VM: $($vm.name_label) on repository: $storageRepoName"
        } else {
            Write-Output "Failed to attach VDI to VM: $($vm.name_label)"
        }
    } catch {
        Write-Output "Error occurred while processing VM $($vm.name_label): $($_.Exception.Message)"
    }
# Close XenServer Connection
Disconnect-XenServer


Could it be that in line 46, instead of $diskLabel, there should be $storageRepoName? (this is a variable at the beginning of the script). It should retrieve the 'Local Storage' repository opaque_ref, right?

If I make it $StorageRepoName I get an error:

Failed to create VDI for VM: VDIPRD2005
At D:\Temp\ADD disk to XenServer VMs on XenServer host.ps1:61 char:13
+             throw "Failed to create VDI for VM: $($vm.name_label)"
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Failed to create VDI for VM: VDIPRD2005:String) [], RuntimeException
    + FullyQualifiedErrorId : Failed to create VDI for VM: VDIPRD2005


Do you have any suggestions?
Thank you in advance!





 

Link to comment

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...