2017-01-31 13 views
1

meine Ignoranz Vergib - Ich versuche, ein Powershell-Cmdlets zu schreiben, die Eingabe Benutzer nimmt und erstellt eine Abfrage uri an eine API (eine obligatorische, 3 entscheidet sich) - Ich habe bekam Art die allgemeine Idee dass ich Hash-Tabellen für das Wörterbuch von Abfragezeichenfolgen und Parametern verwenden muss.Powershell URI-Builder für ein Sys-Admin

Ich versuche $baseurl + $querystring + '=' + $parameter + '&' + $querystring + '=' $value (if not null)

zu bauen z.B. https://example.com/api?param1=value&param2=value

bisher - und das ist sehr rau, und die Arbeit nicht vollständig:

  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 

} 

Ich habe so etwas geschrieben, aber es funktioniert nicht - bin ich noch auf dem richtigen Weg hier? - Ich bin mir sicher, dass dies schon eine Million Mal gemacht wurde, aber ich weiß nicht einmal, was ich googlen soll - etwas sagt mir, dass ich die Hash-Tabelle nicht mit Variablen einrichten sollte. danke fürs schauen.

+0

Hallo, Ihr Code läuft nicht als as_is_, und ist nicht gut eingerückt, so dass es schwer zu lesen und zu verstehen ist. Können Sie bitte versuchen, es ein wenig zu beheben? Zum Beispiel denke ich, dass die erste schließende geschweifte Klammer fehlplatziert ist, weil sie den Funktionsdeklarationsblock beendet. Ich fürchte, ich werde deine Logik brechen, wenn ich versuche, Dinge zu ändern. Wenn Sie Benutzereingaben machen wollen, können Sie auch versuchen mit: '$ userValue1 = Read-Host" geben Sie den ersten Wert ein "' zum Beispiel. – sodawillow

+0

danke sodawillow, ich versuche nur, eine Idee zu bekommen, wie man den Abfrage-String mit Hash-Tabelle erstellen - nicht wirklich nach Code per se suchen, ich möchte es als ein Cmdlet erstellen, so dass Benutzer die Parameter Tabs anstatt sein können aufgefordert, so 'Get-commonURI -param1 value' und 'get-commonURI -param1 value param2 value' das cmdlet sollte die richtige uri bauen – Sum1sAdmin

Antwort

7

Ich bin immer ein Fan von nicht neu zu erfinden das Rad:

[System.UriBuilder]::new('http', 'myhost.com', 80, 'mypath/query.aspx', '?param=value') 

Update:

Dies ist eine eingebaute in .NET-Klasse, die zahlreiche Konstrukteure hat. Der obige akzeptiert ein Protokoll, einen Host, eine Portnummer, einen Pfad und eine Abfragezeichenfolge. Es scheint sich um eine leere oder leere Abfragezeichenfolge zu handeln, so dass Sie dies nicht selbst behandeln müssen. Für Informationen kann der Konstruktor der Klasse here gesehen werden. Um eine Eingabe vom Benutzer abgerufen werden, können Sie Read-Host verwenden, zB:

[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 
+0

danke Simon, können Sie ein wenig darauf eingehen, vor allem im Hinblick auf Benutzereingaben und nicht anhängen Abfragezeichenfolge, wenn der Parameter null ist. Vielen Dank. – Sum1sAdmin

+0

Kein Problem; wird die Antwort aktualisieren. –

+0

netter ein dank, auf einem Mac jetzt aber werde versuchen, dies morgen und lassen Sie es wissen, wird die Antwort akzeptieren, sobald ich es probiere! Danke noch einmal. – Sum1sAdmin

0

Am Ende habe ich dies als Cmdlets schrieb die Pipeline Eingabe verwendet und kann von anderen Skripten aufgerufen werden - es kann öffnen die uri in einem Browser, speichern Sie das XML als Dokument, oder das Dokument als XML-Objekt - das ist sehr praktisch, wie Sie können dann die XML-Objekteigenschaften (XML-Knoten, Attribute) mit gepunkteten Notation anstelle von xPath und Powershells intellisense verwendet die Tab-Vervollständigung, so dass Sie durch die xml-Knoten in der Befehlszeile oder in der Powershell-ISE wechseln können.

Ich verwende auch die Powershell-Community-Erweiterungen Modul https://pscx.codeplex.com/ für seine sinnvolle 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 


    } 


} 

Beispiel zur Nutzung

get-APICommon -param1 Abfragezeichen

oder

get-APICommon -param1 queryvalue1 -param2 queryvalue2

Beispiel führt

https://example.com/restapi?&query1=queryvalue&query2=queryvalue2&auth=JSJAUJQJALF09OLQLS34LLK 
Verwandte Themen