请原谅我的无知 - 我正在尝试编写一个powershell cmdlet,它接受用户输入并构建查询uri到API(一个强制性,3个opts) - 我有点大概我需要使用哈希表查询字符串和参数字典。
我正在尝试构建$baseurl + $querystring + '=' + $parameter + '&' + $querystring + '=' $value (if not null)
e.g。 https://example.com/api?param1=value¶m2=value
到目前为止 - 这非常粗糙,完全不起作用:
Function Get-commonURI{ #takes 4 params from user
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[String[]]$value1
[Parameter(Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[String[]]$value2,
[String[]]$value3,
[String[]]$value4
) #end param
}
#put the input into a paramter hash table with the query strings
$Parameters = @{
query = 'querysting1', 'querystring2', 'querystring3', 'querystring4'
values = $value1,$value2.$value2, $value4
}
uri = https://example.com/api?
$HttpValueCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
foreach ($Item in $Parameters.GetEnumerator()) {
#I want to append each query passed in on the cli
foreach ($Value in $Item.Value) {
$ParameterName = $Item.value
$HttpValueCollection.Add($ParameterName, $Value)}
$Request = [System.UriBuilder]($Uri)
$Request.Query = $HttpValueCollection.ToString()
invoke-webrequest $Request.Uri
}
我有类似的东西写但是它不起作用 - 我甚至在这里正确的轨道? - 我确定这已经完成了一百万次,但甚至不知道谷歌的内容 - 有些事情告诉我,我不应该用变量设置哈希表。谢谢你的期待。
答案 0 :(得分:10)
我总是不再重新发明轮子的粉丝:
$ub = new-object System.UriBuilder -argumentlist 'http', 'myhost.com', 80, 'mypath/query.aspx', '?param=value'
$ub.Uri.AbsoluteUri
>>>> http://myhost.com/mypath/query.aspx?param=value
更新
这是一个内置的.NET类,它有许多构造函数。上面的一个接受协议,主机,端口号,路径和查询字符串。它似乎处理一个空的或空的查询字符串,所以不需要自己处理。有关信息,班级'可以看到构造函数here。为了从用户检索输入,您可以使用Read-Host,例如:
[String] $Local:strServer = '';
[String] $Local:strPath = '';
[String] $Local:strQuery = '';
[String] $Local:strUri = '';
while ( $strServer -eq '' ) {
$strServer = Read-Host -Prompt 'Please enter a server name';
} #while
while ( $strPath -eq '' ) {
$strPath = Read-Host -Prompt 'Please enter a path';
} #while
# Get query string and ensure it begins with a "?".
$strQuery = Read-Host -Prompt 'Please enter a query string';
if ( ($strQuery -ne '') -and (! $strQuery.StartsWith('?')) ) { $strQuery = '?' + $strQuery; }
try {
$strUri = [System.UriBuilder]::new( 'http', $strServer, 80, $strPath, $strQuery );
Write-Host -Object ( 'URI is {0}' -f $strUri );
} #try
catch [System.ArgumentException] {
# Something went wrong.
} #catch
答案 1 :(得分:0)
最后,我将其编写为cmdlet,它接受管道输入并可以从其他脚本调用 - 它可以在浏览器中打开uri,将xml保存为文档,或者将文档转换为xml类型对象 - 这非常方便,因为您可以使用点分表示法而不是xPath选择xml对象属性(xml节点,属性),并且Powershells intellisense使用制表符完成,这样您就可以在命令行或Powershell ISE中循环通过xml节点。 / p>
我还使用了powershell社区扩展模块 https://pscx.codeplex.com/因为它是明智的join-string cmdlet。
Add-Type -AssemblyName System.Web
$authparam = '&auth='
$baseURI = 'https://example.com/restapi?'
$password = 'plaintextpassword'
Function Get-APICommon
{
#takes 4 params and auth key
[CmdletBinding()]
Param (
[Parameter(Mandatory = $false,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true)]
[String[]]$param1,
[String[]]$Param2,
[String[]]$Param3,
[String[]]$Param4
) #end param
Begin { }
process
{
$Parameters = [ordered] @{
Query1 = $Param1
Query2 = $Param2
Query3 = $Param3
Query4 = $Param4
}
#This particular API needs to have query parameters separated by ':' and hashed as part of the authentication parameter i.e param1:param2:param3:param4:password
$preauth = ($Parameters.GetEnumerator() | % { "$($_.Value)" }) -join ':'
$prehash = Join-String $preauth, ':', $password
$hash = $prehash | Get-Hash -Algorithm SHA1 -StringEncoding ascii
foreach ($item in $Parameters.GetEnumerator())
{
if ($item.value -ne $null)
{
$query =[System.Web.HttpUtility]::ParseQueryString($uriBuilder.Query)
$query[$item.key] = $item.Value
$uriBuilder = [System.UriBuilder]::new($baseURI)
$uriBuilder.Query = $query.ToString()
$baseURI = $uriBuilder.ToString()
}
}
$queryURI = Join-String $baseURI, $authparam, $hash
Write-Host $queryURI
$Resultfile = Join-String $($Parameters.Query1),'-Result.xml'
$Resultxml = [xml](Invoke-WebRequest -Uri $queryURI | Select-Object -ExpandProperty content | Out-File $Resultfile)
$Parameters.Clear()
$Browser = new-object -com internetexplorer.application
$Browser.navigate2("$queryURI")
$Browser.visible = $true
}
}
使用示例
get-APICommon -param1查询字符串
或
get-APICommon -param1 queryvalue1 -param2 queryvalue2
示例结果
https://example.com/restapi?&query1=queryvalue&query2=queryvalue2&auth=JSJAUJQJALF09OLQLS34LLK