最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Run a PowerShell Azure CustomScriptExtension through Terraform - Stack Overflow

programmeradmin0浏览0评论

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:

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

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 3
  • 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
Add a comment  | 

1 Answer 1

Reset to default 1

Run 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

发布评论

评论列表(0)

  1. 暂无评论