Передача массива в хэш-таблице параметров Invoke-AzureRmVMRunCommand не работает

Я пытаюсь выполнить Runbook PowerShell учетной записи службы автоматизации Azure, который должен выполнять сценарий PowerShell на виртуальной машине Azure Win, используя следующую инструкцию:

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

Параметр инструкции следующий:

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

Вопрос: Возможно ли это со встроенным массивом («Para6») в хеш-таблице? И если да, то как?

Я пробовал это в течение некоторого времени безуспешно, так как я не могу получить доступ к значениям массива в удаленном скрипте; см. ниже подробности и фактические образцы кода. Пожалуйста, помогите кому-нибудь !!!

Детали проблемы:

В модуле Runbook службы автоматизации Azure у меня есть:

...

[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
    }

(здесь надгробные акценты убраны)

В вызванном скрипте у меня есть:

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

И [array] $ sdvastrCopyFolders, и [array []] $ sdvastrCopyFolders не будут работать.

Симптомом является то, что я получаю в вызванном скрипте:

$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[]

, но не ожидаемые члены массива:

Application
Data
Execution

Если я тестирую эту передачу / извлечение параметров HT / Array между двумя сценариями в простой PowerShell, все работает так, как ожидалось:

PS Z:\> $sdvastrCopyFolders.Length
3

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

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

person Woody Chan    schedule 23.09.2019    source источник
comment
Не могли бы вы сказать мне, что вы хотите сделать? Не могли бы вы мне сказать, можете ли вы запустить скрипт локально?   -  person Jim Xu    schedule 24.09.2019
comment
Итак, запустите модуль Runbook PowerShell для учетной записи службы автоматизации Azure, который будет выполнять сценарий PowerShell на виртуальной машине Azure Win. Необходимо использовать службу автоматизации Azure; как это проверить на месте?   -  person Woody Chan    schedule 24.09.2019
comment
Вы можете сохранить сценарий PowerShell, который хотите выполнить на виртуальной машине Azure локально, а затем запустить команду в локальном модуле Runbook PowerShell.   -  person Jim Xu    schedule 24.09.2019
comment
Привет, в последние дни я снова исследовал массивы, запускал локальные тесты с передачей параметров с использованием HT splatting при прямом вызове скриптов PS ('&') - с успехом. Однако выполнение Invoke-AzureRmVMRunCommand на моем локальном компьютере дало тот же результат, что и при использовании службы автоматизации Azure: удаленное выполнение сценария не заполняет параметр массива; .Count = 1, .GetValue (0) - это строка System.Object []. Я приму новый пост ниже и возвращаюсь!   -  person Woody Chan    schedule 26.09.2019


Ответы (1)


Согласно моему тесту, когда мы запускаем команду Invoke-AzureRmVMRunCommand, серверная часть выполнит какое-то действие для обработки значения параметра, тип которого является массивом. Тогда мы не сможем получить значение в скрипте. Но серверная часть не будет обрабатывать параметр строкового типа. Поэтому я предлагаю вам использовать в скрипте строковый параметр. Если для одного параметра требуются некоторые значения, вы можете разделить их специальными символами, такими как ,. Например:

Мой модуль 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


Сценарий:

  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


Результат:  введите здесь описание изображения

person Jim Xu    schedule 26.09.2019
comment
Спасибо за вашу помощь, и работа здесь сделана! Я понимаю, что кажется невозможным (для вас или меня) распространить объект массива с помощью Invoke-AzureRmVMRunCommand - что за хрень от MS !!! (Я потратил на это 1 неделю, так как доверял MS, что этот стандартный метод просто должен работать ...) Однако я продолжу ваше предложение о преобразовании строки в массив - Большое спасибо за это !!! Тогда я отмечу ваш ввод как ответ, несмотря на то, что я не верю, что Invoke-AzureRmVMRunCommand не может передавать массивы. Еще раз большое спасибо! - person Woody Chan; 26.09.2019