Azure-docs: No PowerShell support Run Command for Linux

Created on 1 Apr 2019  Â·  7Comments  Â·  Source: MicrosoftDocs/azure-docs

Unlike the CLI, it seems that the PowerShell Invoke-AzVMRunCommand cannot be used to run scripts inside Linux VMs. The script must be present on the calling machine, which is not practical.

The problem is that Azure Automation runbooks only support PowerShell and not CLI. Is there any solution to this catch-22?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Pri2 automatiosvc cxp product-question triaged

Most helpful comment

@dohughes-msft So that is a problem, there are two ways to solve that. Run it from a hybrid runbook worker where you can install whatever you need locally. Or use the REST API endpoint for run command... You can call it with PowerShell with the example below replacing the values in the uri with your valid values. I just used an example of running ps aux.. you can do whatever you want though. I have not tested this in a runbook but since it is PowerShell and just using Invoke-WebRequest and Azure cmdlets you should be fine.. Ohh and I used Az instead of AzureRm.. you would just need to fix that as well.

$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Subscription.TenantId)
$authHeader = @{
    'Content-Type'='application/json'
    'Authorization'='Bearer ' + $token.AccessToken
}

# Invoke the REST API
$restUri = 'https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/runCommand?api-version=2017-03-30'
$body = @{
    'commandId' = 'RunShellScript'
  'script' = @('ps aux')
}
$response = Invoke-webrequest -Uri $restUri -Method Post -Headers $authHeader -Body $($body | ConvertTo-Json)

$asyncstatus = $($response.headers.'Azure-AsyncOperation')
$status = "InProgress"
While($status -eq "InProgress")`
{
Write-Output "Status: $status"
$response = invoke-webrequest -uri $asyncstatus -Headers $authHeader
$status = $($response.Content | ConvertFrom-Json).status -eq "InProgress"
sleep 5
}
Write-Output $($response.Content | ConvertFrom-Json).properties.output.message

All 7 comments

@dohughes-msft Thanks for the Comment. We are actively investigating and will get back to you soon.

@dohughes-msft Run command does not require an Automation account to work. Is there somewhere you are seeing states this? As for running the scripts, az cli is only used for Linux machines and PowerShell is only used for Windows machines. Can you please clarify what it is you are having issues with? Are you trying to use Run command on a linux machine by calling it from an automation runbook?

@georgewallace yes that's correct, I want to execute a script inside a Linux VM from an automation runbook. CLI is not available for that.

@dohughes-msft So that is a problem, there are two ways to solve that. Run it from a hybrid runbook worker where you can install whatever you need locally. Or use the REST API endpoint for run command... You can call it with PowerShell with the example below replacing the values in the uri with your valid values. I just used an example of running ps aux.. you can do whatever you want though. I have not tested this in a runbook but since it is PowerShell and just using Invoke-WebRequest and Azure cmdlets you should be fine.. Ohh and I used Az instead of AzureRm.. you would just need to fix that as well.

$azContext = Get-AzContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Subscription.TenantId)
$authHeader = @{
    'Content-Type'='application/json'
    'Authorization'='Bearer ' + $token.AccessToken
}

# Invoke the REST API
$restUri = 'https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/runCommand?api-version=2017-03-30'
$body = @{
    'commandId' = 'RunShellScript'
  'script' = @('ps aux')
}
$response = Invoke-webrequest -Uri $restUri -Method Post -Headers $authHeader -Body $($body | ConvertTo-Json)

$asyncstatus = $($response.headers.'Azure-AsyncOperation')
$status = "InProgress"
While($status -eq "InProgress")`
{
Write-Output "Status: $status"
$response = invoke-webrequest -uri $asyncstatus -Headers $authHeader
$status = $($response.Content | ConvertFrom-Json).status -eq "InProgress"
sleep 5
}
Write-Output $($response.Content | ConvertFrom-Json).properties.output.message

@dohughes-msft We will now close this issue. If there are further questions regarding this matter, please reply and we will gladly continue the discussion.

save your block-script to file and reference the file. tested on automation account sandbox.

The script like "mkdir test" works for me where it creates folder inside the VM. However, iam not able to invoke a .sh file that is present in the VM. Tried doing the below, but no luck. Any help is appreciated.
$body = @{ 'commandId' = 'RunShellScript' 'script' = @('sh /home/azureuser/test.sh') }

Was this page helpful?
0 / 5 - 0 ratings

Related issues

spottedmahn picture spottedmahn  Â·  3Comments

varma31 picture varma31  Â·  3Comments

DeepPuddles picture DeepPuddles  Â·  3Comments

bityob picture bityob  Â·  3Comments

behnam89 picture behnam89  Â·  3Comments