Передать всю хеш-таблицу Invoke-Expression - PullRequest
0 голосов
/ 11 октября 2018

Я хотел бы задать вам вопрос о передаче хеш-таблицы в Invoke-Expression.

Я пишу простой E2E-мониторинг, и упомянутая хеш-таблица используется в качестве тела, содержащего кредиты для формы HTTP, для регистрации jira.У меня это работает нормально, но по конкретной причине я хотел бы динамически создавать этот Invoke-Webrequest, в зависимости от полученных аргументов.И здесь есть мой подвох.

Таким образом, я не знаю, как передать хеш-таблицу (другие типы данных в порядке, например, строка или int) в выражение Invoke.Он всегда представлен как System.Collections.Hashtable

$uri = 'https://exdom.com/login.jsp?saml_sso=false'
$method = "POST"
$postParams = @{
    os_username = "username";
    os_password = "password";
    login = "true"
}

$scriptBlock = {
    param(
        [Parameter(Mandatory=$true,Position=1)][string]$uri,
        [Parameter(Mandatory=$false,Position=2)][string]$method,
        [Parameter(Mandatory=$true,Position=3)][hashtable]$postParams
    )
    $commandFragments = @()
    $commandFragments += "Invoke-WebRequest"
    if ( $PSBoundParameters.ContainsKey('uri')){
        $commandFragments += " -Uri $uri"
    }
    if ( $PSBoundParameters.ContainsKey('method')){
        $commandFragments += " -Method $method"
    }
    if ( $PSBoundParameters.ContainsKey('postParams')){
        $commandFragments += " -Body $postParams"
    }
    $commandFromFragments = $commandFragments -join ''
    (Invoke-Expression -Command $commandFromFragments).Content | Out-File 'c:\tmp\response3.html'
    (Invoke-Expression -Command "Invoke-WebRequest -Uri https://exdom.com/login.jsp?saml_sso=false -Method POST -Body @(@{'os_username' = 'username@mydomain.com'; 'os_password' = 'mypassword'; 'login' = 'true'})").Content | Out-File 'c:\tmp\response4.html'
    (Invoke-WebRequest -Method $method -Uri $uri -Body $postParams).Content | Out-File 'c:\tmp\response5.html'
}

Invoke-Command -ScriptBlock $scriptBlock -ArgumentList ($uri, $method, $postParams)

Мне кажется, мне не хватает чего-то простого.Могу я попросить у вас совета?

Спасибо, Марсель

1 Ответ

0 голосов
/ 11 октября 2018

Давайте поговорим о том, что не так.

$commandFragments += " -Body $postParams"

Вы превращаете HashTable в строку.Что не возможно.Итак, что мы можем сделать, это преобразовать это во что-то.Теперь что мы должны преобразовать в?Invoke-WebRequest -body

Это можно сделать с помощью Json.Таким образом, вы можете использовать " -Body $($postParams | convertto-json)"

Но это только сохранение JSON в строку, которая все еще не будет работать, поскольку Json должен находиться в строке внутри команды Invoke-WebRequest.Поэтому исправление будет заключаться в том, чтобы заключить JSON в одинарные кавычки." -Body '$($postParams | ConvertTo-Json)'"

У нас также есть несколько небольших исправлений, которые мы можем сделать для повышения эффективности.Например, операторы if выглядят как

$PSBoundParameters.GetEnumerator() | %{
    switch($_.Key){
        "uri" { $commandFragments += " -Uri $uri" }
        "method" { $commandFragments += " -Method $method" }
        "postParams" { $commandFragments += " -Body '$($postParams | ConvertTo-Json)'" }
    }
}

Конечный продукт:

$uri = 'https://exdom.com/login.jsp?saml_sso=false'
$method = "POST"
$postParams = @{
    "os_username" = "username";
    "os_password" = "password";
    "login" = "true"
}

$scriptBlock = {
    param(
        [Parameter(Mandatory=$true,Position=1)][string]$uri,
        [Parameter(Mandatory=$false,Position=2)][string]$method,
        [Parameter(Mandatory=$true,Position=3)][hashtable]$postParams
    )

    $commandFragments = $("Invoke-WebRequest")
    $PSBoundParameters.GetEnumerator() | %{
        switch($_.Key){
            "uri" { $commandFragments += " -Uri $uri" }
            "method" { $commandFragments += " -Method $method" }
            "postParams" { $commandFragments += " -Body '$($postParams | ConvertTo-Json)'" }
        }
    }
    (Invoke-Expression -Command $($commandFragments -join '')).Content | Out-File 'c:\tmp\response3.html'
    (Invoke-Expression -Command "Invoke-WebRequest -Uri https://exdom.com/login.jsp?saml_sso=false -Method POST -Body @(@{'os_username' = 'username@mydomain.com'; 'os_password' = 'mypassword'; 'login' = 'true'})").Content | Out-File 'c:\tmp\response4.html'
    (Invoke-WebRequest -Method $method -Uri $uri -Body $postParams|ConvertTo-Json).Content
}

Invoke-Command -ScriptBlock $scriptBlock -ArgumentList ($uri, $method, $postParams)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...