I am attempting to run a CustomScriptExtension through terraform that will mount the data disks, and extend the C drive if need be. However, i cannot seem to get the file to pass and execute on the VM.
The customscript powershell script is located in a folder in the same directory as the terraform configuration files, below is the custom script to grab the data disks and mount them on a windows VM.
./CustomScripts/CustomScriptDataDisks.ps1
#Custom script to perform format on data disks, assign letter and name based on disk lun
Set-StrictMode -Version 3
try {
Write-Output "Change CD drive letter to W"
Write-Verbose -Message "[Start]::Changing CD drive letter to W..."
$CDDrive = Get-WmiObject -Class Win32_volume -Filter "DriveType = '5'"
if ($CDDrive) {$CDDrive | Set-WmiInstance -Arguments @{DriveLetter = 'W:'}}
Write-Verbose -Message "[Finish]::Changed CD drive letter to W"
#Extend C drive if necessary
$CPartition = Get-Partition -DriveLetter C
$CSupportedSize = Get-PartitionSupportedSize -DriveLetter C
if ($CSupportedSize.SizeMax -gt $CPartition.Size) {
Resize-Partition -DriveLetter C -Size $CSupportedSize.SizeMax
}
Write-Output "Initializing Disks"
$disks = Get-Disk | Where-Object partitionstyle -eq 'raw' | Sort-Object number
if ($disks) {
#Format disks
$i = 70
$DiskCount = 1
foreach ($disk in $disks) {
$DiskLUN = [int]([regex]::Match($disk.Path, "[#]{1}\d{1,}[#]{1}").Value.Replace("#", ""))
if ($DiskLUN -lt 19 -or $DiskLUN -gt 39) {
$diskID = [string]$DiskCount
$diskLabel = $env:COMPUTERNAME + "-DataDisk-" + $DiskID
$diskLetter = [char]$i
#Mount Disks
$disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter $diskLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $diskLabel -Confirm:$false -Force
$i++; $DiskCount++
}
if ($DiskLUN -gt 19 -and $DiskLUN -lt 30) {
$i = 76
$DiskCount = 1
$diskID = [string]$DiskCount
$diskLabel = $env:COMPUTERNAME + "-LogDisk-" + $DiskID
$diskLetter = [char]$i
#Mount Disks
$disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter $diskLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $diskLabel -Confirm:$false -Force
$i++; $DiskCount++
}
if ($DiskLUN -gt 29 -and $DiskLUN -lt 40) {
$i = 83
$DiskCount = 1
$diskID = [string]$DiskCount
$diskLabel = $env:COMPUTERNAME + "-BackupDisk-" + $DiskID
$diskLetter = [char]$i
#Mount Disks
$disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter $diskLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $diskLabel -Confirm:$false -Force
$i++; $DiskCount++
}
}
}
} #end try
catch {
Write-Error -Message "Caught an exception:"
Write-Error -Message "Exception Type: $($_.Exception.GetType().FullName)"
Write-Error -Message "Exception Message: $($_.Exception.Message)"
}
Here is the azurerm_virtual_machine_extension, to which i seem to not be able to pass through to the extension, i've also tried sending the -File parameter as a path to the powershell script.
resource "azurerm_virtual_machine_extension" "CustomScriptDisks" {
name = "${azurerm_windows_virtual_machine.win-vm.name}-CustomScriptDisks"
virtual_machine_id = azurerm_windows_virtual_machine.win-vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
settings = <<SETTINGS
{
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File ./CustomScripts/CustomScriptDataDisks.ps1"
}
SETTINGS
}
Error:
Command execution finished, but failed because it returned a non-zero exit code of: '-196608'. The command had an error output of: 'The argument './CustomScripts/CustomScriptDataDisks.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter. '
I have also tried to encode the protected settings, not sure what else this could be doing. Any help would be greatly appreciated.
resource "azurerm_virtual_machine_extension" "CustomScriptDisks" {
name = "${azurerm_windows_virtual_machine.win-vm.name}-CustomScriptDisks"
virtual_machine_id = azurerm_windows_virtual_machine.win-vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
protected_settings = <<SETTINGS
{
"commandToExecute": "powershell -encodedCommand ${textencodebase64(file("./CustomScripts/CustomScriptDataDisks.ps1"), "UTF-16LE")}"
}
SETTINGS
}
Error:
Command execution finished, but failed because it returned a non-zero exit code of: '1'. The command had an error output of: 'The command line is too long. '
I am attempting to run a CustomScriptExtension through terraform that will mount the data disks, and extend the C drive if need be. However, i cannot seem to get the file to pass and execute on the VM.
The customscript powershell script is located in a folder in the same directory as the terraform configuration files, below is the custom script to grab the data disks and mount them on a windows VM.
./CustomScripts/CustomScriptDataDisks.ps1
#Custom script to perform format on data disks, assign letter and name based on disk lun
Set-StrictMode -Version 3
try {
Write-Output "Change CD drive letter to W"
Write-Verbose -Message "[Start]::Changing CD drive letter to W..."
$CDDrive = Get-WmiObject -Class Win32_volume -Filter "DriveType = '5'"
if ($CDDrive) {$CDDrive | Set-WmiInstance -Arguments @{DriveLetter = 'W:'}}
Write-Verbose -Message "[Finish]::Changed CD drive letter to W"
#Extend C drive if necessary
$CPartition = Get-Partition -DriveLetter C
$CSupportedSize = Get-PartitionSupportedSize -DriveLetter C
if ($CSupportedSize.SizeMax -gt $CPartition.Size) {
Resize-Partition -DriveLetter C -Size $CSupportedSize.SizeMax
}
Write-Output "Initializing Disks"
$disks = Get-Disk | Where-Object partitionstyle -eq 'raw' | Sort-Object number
if ($disks) {
#Format disks
$i = 70
$DiskCount = 1
foreach ($disk in $disks) {
$DiskLUN = [int]([regex]::Match($disk.Path, "[#]{1}\d{1,}[#]{1}").Value.Replace("#", ""))
if ($DiskLUN -lt 19 -or $DiskLUN -gt 39) {
$diskID = [string]$DiskCount
$diskLabel = $env:COMPUTERNAME + "-DataDisk-" + $DiskID
$diskLetter = [char]$i
#Mount Disks
$disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter $diskLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $diskLabel -Confirm:$false -Force
$i++; $DiskCount++
}
if ($DiskLUN -gt 19 -and $DiskLUN -lt 30) {
$i = 76
$DiskCount = 1
$diskID = [string]$DiskCount
$diskLabel = $env:COMPUTERNAME + "-LogDisk-" + $DiskID
$diskLetter = [char]$i
#Mount Disks
$disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter $diskLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $diskLabel -Confirm:$false -Force
$i++; $DiskCount++
}
if ($DiskLUN -gt 29 -and $DiskLUN -lt 40) {
$i = 83
$DiskCount = 1
$diskID = [string]$DiskCount
$diskLabel = $env:COMPUTERNAME + "-BackupDisk-" + $DiskID
$diskLetter = [char]$i
#Mount Disks
$disk |
Initialize-Disk -PartitionStyle GPT -PassThru |
New-Partition -UseMaximumSize -DriveLetter $diskLetter |
Format-Volume -FileSystem NTFS -NewFileSystemLabel $diskLabel -Confirm:$false -Force
$i++; $DiskCount++
}
}
}
} #end try
catch {
Write-Error -Message "Caught an exception:"
Write-Error -Message "Exception Type: $($_.Exception.GetType().FullName)"
Write-Error -Message "Exception Message: $($_.Exception.Message)"
}
Here is the azurerm_virtual_machine_extension, to which i seem to not be able to pass through to the extension, i've also tried sending the -File parameter as a path to the powershell script.
resource "azurerm_virtual_machine_extension" "CustomScriptDisks" {
name = "${azurerm_windows_virtual_machine.win-vm.name}-CustomScriptDisks"
virtual_machine_id = azurerm_windows_virtual_machine.win-vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
settings = <<SETTINGS
{
"commandToExecute": "powershell.exe -ExecutionPolicy Unrestricted -File ./CustomScripts/CustomScriptDataDisks.ps1"
}
SETTINGS
}
Error:
Command execution finished, but failed because it returned a non-zero exit code of: '-196608'. The command had an error output of: 'The argument './CustomScripts/CustomScriptDataDisks.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter. '
I have also tried to encode the protected settings, not sure what else this could be doing. Any help would be greatly appreciated.
resource "azurerm_virtual_machine_extension" "CustomScriptDisks" {
name = "${azurerm_windows_virtual_machine.win-vm.name}-CustomScriptDisks"
virtual_machine_id = azurerm_windows_virtual_machine.win-vm.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.10"
protected_settings = <<SETTINGS
{
"commandToExecute": "powershell -encodedCommand ${textencodebase64(file("./CustomScripts/CustomScriptDataDisks.ps1"), "UTF-16LE")}"
}
SETTINGS
}
Error:
Share Improve this question edited Feb 4 at 4:13 Vinay B 2,5312 gold badges3 silver badges12 bronze badges Recognized by Microsoft Azure Collective asked Feb 3 at 19:47 NickPNickP 891 gold badge1 silver badge6 bronze badges 3Command execution finished, but failed because it returned a non-zero exit code of: '1'. The command had an error output of: 'The command line is too long. '
- This goes through, but the script is not running. protected_settings = <<SETTINGS { "commandToExecute": "powershell -command \"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode("./CustomScripts/CustomScriptDataDisks.ps1")}')) | Out-File -filepath CustomScriptDataDisks.ps1\" && powershell -ExecutionPolicy Unrestricted -File CustomScriptDataDisks.ps1" } SETTINGS } – NickP Commented Feb 3 at 20:08
- this was the fix, protected_settings = <<SETTINGS { "commandToExecute": "powershell -command \"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode(data.template_file.disks-customscript.rendered)}')) | Out-File -filepath CustomScriptDataDisks.ps1\" && powershell -ExecutionPolicy Unrestricted -File CustomScriptDataDisks.ps1" } but i need to figure out how to pass multiple scripts as you cannot create another azurerm_virtual_machine_extension due to it being unsupported by MSFT – NickP Commented Feb 3 at 21:01
- I hope this helps to resolve your issue. – Venkat V Commented Feb 7 at 13:23
1 Answer
Reset to default 1Run a PowerShell Azure CustomScriptExtension through Terraform
As you have already found the answer to your first question, I will now address your second question, which you asked in the comment section.
i need to figure out how to pass multiple scripts as you cannot create another azurerm_virtual_machine_extension due to it being
In order to run multiple scripts on a VM using,Terraform
since VM extensions are limited, you can achieve this by using Terraform provisioners, such as the local-exec provisioner.
provider "azurerm" {
features {}
subscription_id = "83329a9"
}
resource "null_resource" "powershell" {
provisioner "local-exec" {
command = <<-EOT
pwsh -Command "Invoke-AzVMRunCommand -ResourceGroupName 'Venkat-RG' -VMName 'Venkat-Vm' -CommandId 'RunPowerShellScript' -ScriptPath 'Script.ps1'"
pwsh -Command "Invoke-AzVMRunCommand -ResourceGroupName 'Venkat-RG' -VMName 'Venkat-Vm' -CommandId 'RunPowerShellScript' -ScriptPath 'script2.ps1'"
EOT
}
}
Note: Make sure to place the powershell script in same folder as inthe Terraform directory.
Terraform apply:
After running the script, both scripts were executed on the VM. The first script created a folder, and the second script created files inside that folder