Search code examples
arraysazurepowershellhashtableazure-runbook

Passing an array in an Invoke-AzureRmVMRunCommand parameter hash table not working


I am trying to execute an Azure Automation Account PowerShell runbook which shall execute a PowerShell script on an Azure Win VM using the following statement:

Invoke-AzureRmVMRunCommand -ResourceGroupName $sdvobjVM1.ResourceGroupName -Name $sdvstrNameVM1 -CommandId 'RunPowerShellScript' -ScriptPath $sdvstrScriptFileNameTmp -Parameter $sdvhshParamsFolderCopy

The statement's parameter is as follows:

$sdvhshParamsFolderCopy = @{Para1='String1'; Para2='String2'; Para3='String3'; Para4='String4'; Para5='String5'; Para6=@('Application', 'Data', 'Execution')}

Question: Is this possible with the embedded array ("Para6") in the hash table? And if yes, how?

I have tried this for some time now without success as I cannot access the array values in the remote script; see below for details and actual code samples. Please someone help!!!

Problem details:

In the Azure Automation runbook I have:

...

[string] $sdvstrFileShare = "$sdvstrNameSA1.file.core.windows.net\$sdvstrFileShareName"
[array] $sdvastrCopyFolders = @('Application', 'Data', 'Execution')

...

$sdvhshParamsFolderCopy = @{sdvstrNameSA1 = $sdvstrNameSA1;
                            sdvstrSA1AccessKey = $sdvstrSA1AccessKey;
                            sdvstrFileShare = $sdvstrFileShare;
                            sdvstrSrcDriveLetter = $sdvstrSrcDriveLetter;
                            sdvstrDstDriveLetter = $sdvstrDstDriveLetter;
                            sdvastrCopyFolders = $sdvastrCopyFolders
    }

(break-line grave-accents removed here)

In the invoked script I have:

# Parameters
Param (
    [string] $sdvstrNameSA1,
    [string] $sdvstrSA1AccessKey,
    [string] $sdvstrFileShare,      
    [string] $sdvstrSrcDriveLetter,
    [string] $sdvstrDstDriveLetter,     
    [array] $sdvastrCopyFolders
)

Both [array] $sdvastrCopyFolders and [array[]] $sdvastrCopyFolders won't work.

The symptom is that I am getting in the invoked script:

$sdvastrCopyFolders | ForEach{$_} | Out-File  -FilePath 'D:\sdvastrCopyFoldersForEach.txt'
System.Object[]

$sdvastrCopyFolders.Item(0) | Out-File  -FilePath 'D:\sdvastrCopyFoldersItem0.txt'
System.Object[]

$sdvastrCopyFolders.GetValue(0) | Out-File  -FilePath 'D:\sdvastrCopyFoldersGetValue.txt'
System.Object[]

, but not the expected array members which are:

Application
Data
Execution

If I am testing this HT/Array parameter passing/extraction between 2 scripts in plain PowerShell it all works as expected:

PS Z:\> $sdvastrCopyFolders.Length
3

PS Z:\> (,$sdvastrCopyFolders).GetValue(0)
Application
Data
Execution

PS Z:\> (,$sdvastrCopyFolders).GetValue(0).Item(2)
Execution

Solution

  • According to my test, when we run the command Invoke-AzureRmVMRunCommand, the backend end will do some action to process the value of parameter which type is array. Then we can not get the value in the script. But the backend end will not process the string type parameter. So I suggest you use the string parameter in the script. If one parameter needs some values, you can separate them with special characters such as ,. For example:

    My automation runbook:

    $connectionName = "AzureRunAsConnection"
    try
    {
        # Get the connection "AzureRunAsConnection "
        $servicePrincipalConnection=Get-AutomationConnection -Name $connectionName         
    
        "Logging in to Azure..."
        Add-AzureRmAccount `
            -ServicePrincipal `
            -TenantId $servicePrincipalConnection.TenantId `
            -ApplicationId $servicePrincipalConnection.ApplicationId `
            -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint 
    }
    catch {
        if (!$servicePrincipalConnection)
        {
            $ErrorMessage = "Connection $connectionName not found."
            throw $ErrorMessage
        } else{
            Write-Error -Message $_.Exception
            throw $_.Exception
        }
    }
    Add-AzureRmAccount -Credential $mycreds -Tenant e4c9ab4e-bd27-40d5-8459-230ba2a757fb -ServicePrincipal 
    }
    catch {
        if (!$servicePrincipalConnection)
        {
            $ErrorMessage = "Connection $connectionName not found."
            throw $ErrorMessage
        } else{
            Write-Error -Message $_.Exception
            throw $_.Exception
        }
    }
    [string] $Filesharename = "test"
    [string] $Folders ="test,test1"
    $Params = @{Filesharename = $Filesharename;
    
                                Folders = $Folders;
        }
    
    
    $groupName=' '
    $vmName =' '
    $path=' '
    
    Invoke-AzureRmVMRunCommand -ResourceGroupName $groupName -Name $vmName -CommandId'RunPowerShellScript' -ScriptPath $path -Parameter $Params
    
    
    

    Script :

      Param (
            [string] $Filesharename, 
            [string] $Folders 
            )
    
    
          $Folders | Out-File -FilePath 'C:\test.txt' -Append
          $test =  $Folders -split ','
    
          $test.GetType() | Out-File -FilePath 'C:\test.txt' -Append
    
          $test.Length | Out-File -FilePath 'C:\test.txt' -Append
    
          "-----------------------" | Out-File -FilePath 'C:\test.txt' -Append
          $test | foreach{$_} |  Out-File -FilePath 'C:\test.txt' -Append
    
          "-----------------------" | Out-File -FilePath 'C:\test.txt' -Append
    
          $test[0] | Out-File -FilePath 'C:\test.txt' -Append
    
    
    

    Result: enter image description here