我想问您一个有关将哈希表传递给Invoke-Expression的问题。
我编写简单的E2E监控和提到的哈希表用作包含HTTP形式登录jira凭据的主体。 它对我来说很好用,但是由于特定的原因,我想根据收到的参数动态创建此Invoke-Webrequest。 还有我的收获。
因此,我不知道如何将哈希表(其他数据类型可以,例如字符串或int)传递给Invoke Expression。
它总是像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)
我想我缺少一些基本知识。 我可以问你个建议吗?
谢谢,马塞尔(Marcel)
答案 0 :(得分:-1)
让我们来谈谈哪里出了问题。
$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)