I am trying to run an Invoke-WebRequest command on PowerShell Core 6.3 on a Ubuntu system with the following settings to create a forwarder:
$userLocalMailPart = "user"
$userGlobalMailPart = "Hotmail.com"
$address = "Some Address"
$pair = $login + ":" + $password
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$url = "https://" + $server + ":" + $port + "/Domain/ObjectList.html"
$headers = #{"Authorization" = $basicAuthValue;
"Referer" = $url
}
$body = #{
"NewForwarderName" = $userLocalMailPart ;
"NewForwarderAddress" = $address;
"CreateForwarder" = "Create Forwarder"
}
$result = Invoke-WebRequest `
-Uri $url `
-SkipCertificateCheck `
-Method 'POST' `
-Headers $headers `
-Body $body
This runs perfectly. No error and the forwarder is successfully created.
Now I want to use a function like this:
[Web]::requestHeaderContent($url, $headers, (ConvertTo-Json($body)), 'POST')
[object] static requestHeaderContent([String] $url, [hashtable] $headers, [Object] $body, [String] $meth) {
Invoke-WebRequest `
-Uri $url `
-SkipCertificateCheck `
-Method $meth `
-Headers $headers `
-Body $body
}
The variables like headers and body are the same. I also tried it with ConvertTo-Json but it just don’t work. I also receive a Success 200 Code but the forwarder is not created. I guess my problem are the parameters. Any idea what I am doing wrong?
Thanks
Stephan
Related
In PowerShell using Invoke-RestMetjhod to call different API´s I am stuck getting an InvalidOperation error when trying to pass both header and body information to the POST call.
My script is:
Set-StrictMode -Version Latest
$ApiToken = Get-Content ‘C:\APIEnergiNet\api_token.txt’
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer $ApiToken")
$response = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/token' -Method 'GET' -Headers $headers
$GetMetringPointID = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meteringpoints/meteringpoints?includeAll=true' -Headers #{ Authorization = "Bearer " + $response.result }
foreach($result in $GetMetringPointID){
$CurrentMeteringID = $GetMetringPointID.result.meteringPointId
foreach($Currentresult in $CurrentMeteringID){
$MeterID = $Currentresult
$GetCharges = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/MeteringPoints/MeteringPoint/GetCharges' -Method 'POST' -Headers #{ Authorization = "Bearer " + $response.result } -Body #{ meteringPoints = #( #{meteringPoint = "$Currentresult" } ) }
$GetCharges
}
}
The API needs the following sent in the body :
{
"meteringPoints": {
"meteringPoint": [
"string"
]
}
}
if I create variable $postParams containing the data like this:
$postParams = #{
meteringPoints = #(
#{meteringPoint = "$MeterID" }
)
}
$postParams
it returns:
meteringPoints {System.Collections.Hashtable}
The API has a swagger here https://api.eloverblik.dk/customerapi/index.html
Can anyone help me why I get this error and how to fix it?
Best Regards
Stig :-)
UPDATE WITH LATEST CODE BELOW:
Set-StrictMode -Version Latest
$ApiToken = Get-Content ‘C:\APIEnergiNet\api_token.txt’
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer $ApiToken")
$response = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/token' -Method 'GET' -Headers $headers
$GetMetringPointID = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meteringpoints/meteringpoints?includeAll=true' -Headers #{ Authorization = "Bearer " + $response.result }
foreach ($result in $GetMetringPointID)
{
$CurrentMeteringID = $GetMetringPointID.result.meteringPointId
foreach ($Currentresult in $CurrentMeteringID)
{
$MeterID = $Currentresult
$postParams = #{
meteringPoints = #(
#{ meteringPoint = "$MeterID" }
)
} | ConvertTo-Json
$resultlist = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/MeteringPoints/MeteringPoint/GetCharges' -Method 'POST' -ContentType 'application/json' -Headers #{ Authorization = "Bearer " + $response.result } -Body #{ $postParams }
$resultlist
}
}
ERROR I NOW GET:
ParserError: C:\APIEnergiNet\api.ps1:31:245
Line |
31 | … Authorization = "Bearer " + $response.result } -Body #{ $postParams }
| ~
| Missing '=' operator after key in hash literal.
I've made this little PS for you based on yours
$Path = "C:\EnergiNet\"
$TokenFile = $Path + "token.txt"
$JSON_ResponseFile = $Path + "Response.json"
$XML_ResponseFile = $Path + "Response.xml"
$ApiToken = Get-Content $TokenFile
# Get Auth token #
$response = Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/token' -Method 'GET' -Headers #{ Authorization = "Bearer " + $ApiToken }
$Auth_Token = $response.result
$body = '{ "meteringPoints": {"meteringPoint": ["571313174xxxxxxxxxxx","571313174xxxxxxxxxxx","571313174xxxxxxxxxxx"] }}'
$headers = #{
'Authorization' = "Bearer " + $response.result
'Accept' = 'application/json'
}
Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meterdata/gettimeseries/2023-01-01/2023-02-01/Quarter' -Method 'POST' -ContentType 'application/json' -Headers $headers -Body $body | ConvertTo-Json -Depth 100 | out-file $JSON_ResponseFile
$headers = #{
'Authorization' = "Bearer " + $response.result
'Accept' = 'application/xml'
}
(Invoke-RestMethod 'https://api.eloverblik.dk/customerapi/api/meterdata/gettimeseries/2023-01-01/2023-02-01/Quarter' -Method 'POST' -ContentType 'application/json' -Headers $headers -Body $body).outerXml | out-file $XML_ResponseFile
I have been trying to pull out Azure Audit logs using Microsoft Graph. I am using Powershell to do this nut I can't get filtering to work.
For example, this URL returns lots of older data than then date specified in the filter.
https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?\$filter=activityDateTime ge 2020-02-24T18:39:36Z
Here is my code
$ClientID = "yyyyyy"
$ClientSecret = "xxxxxxxxx"
$loginURL = "https://login.microsoftonline.com"
$tenantdomain = "xxx.onmicrosoft.com"
$resource = "https://graph.microsoft.com"
$Date = Get-Date
$UTC = $Date.ToUniversalTime();
$UTC
$Time = "{0:s}" -f $UTC.AddMinutes(-5) + "Z"
$Time
$body =
#{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-
version=1.0 -Body $body
$headerParams = #{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}
$url = 'https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?\`$filter=activityDateTime ge ' +
$Time
$Data = Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url
$DataFromJson = $Data.Content | ConvertFrom-Json
$ValueFromJason = $DataFromJson.value
$AllAuditData += $ValueFromJason
# Output
$Time
2020-02-24T18:39:36Z
$short = $AllAuditData | Sort-Object activityDateTime
$short[1].activityDateTime
2020-02-24T17:52:09.9673372Z # Old data as comparison to $Time
$short[-1].activityDateTime
2020-02-24T18:44:15.1283452Z
According to my test, we can use the following script
$ClientID = "yyyyyy"
$ClientSecret = "xxxxxxxxx"
$loginURL = "https://login.microsoftonline.com"
$tenantdomain = "xxx.onmicrosoft.com"
$resource = "https://graph.microsoft.com"
$body =
#{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-
version=1.0 -Body $body
$Date = Get-Date
$UTC = $Date.ToUniversalTime();
$Time = "{0:s}" -f $UTC.AddMinutes(-5) + "Z"
$Time
$url= "https://graph.microsoft.com/beta/auditLogs/directoryAudits?`$filter=activityDateTime gt " + $Time
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "$($oauth.token_type) $($oauth.access_token)")
$AllAuditData=#()
$response = Invoke-RestMethod $url -Method 'GET' -Headers $headers
$AllAuditData += $response.value
$short = $AllAuditData | Sort-Object activityDateTime
$short[1].activityDateTime
$short[-1].activityDateTime
Update
According to my research, we can use the Azure AD PowerShell command Get-AzureADAuditDirectoryLogs to filter audit logs. For more details, please refer to https://learn.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-powershell-reporting.
For example
Install-module AzureADPreview
Connect-AzureAD
$result=Get-AzureADAuditDirectoryLogs -Filter "activityDisplayName eq 'Update user'"
$result | Select-Object ActivityDisplayName
I want to edit a Azure DevOps wiki page over the REST API (Azure DevOps Server 2019.0.1).
When I run this PowerShell script:
#VARIABLES
$api = "api-version=5.0"
$root = "http://136.202.18.216:8070/Samples"
$personalToken = "uwawlzqp6j7i1nd5dasspwkwp63tr2w2sxb5563zrla2bivynbza"
#AUTHORIZATION
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$headers = #{
"Authorization" = ('Basic {0}' -f $token)
"If-Match" = '*'
}
#PROJECT VARIABLES
$project = "Framework%20A"
$pageToUpdate = "/Seite2"
#BODY
$body = #"
{
"content": "Hello"
}
"#
#GET
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&includeContent=True&$api"
$content = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers $headers
Write-Host "$($content.path) = $($content.content)" -ForegroundColor Yellow
#PUT
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&$api"
$update = Invoke-RestMethod -Uri $url -Method Put -ContentType "application/json" -Headers $header -Body $body -Verbose
Write-Host $update.content -ForegroundColor Yellow
exit(0)
The consolen output is:
/Seite2 = Seite 2 Content
AUSFÜHRLICH: PUT http://136.202.18.216:8070/Samples/Framework A/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=/Seite2&api-version=5.0 with -1-byte payload
Invoke-RestMethod: {"$ id": "1", "innerException": null, "message": "The required \" IfMatch \ "header specified in the request is an invalid page version Version of the
Wiki page as \ "IfMatch \" header for the request. \ R \ nParameterName: IfMatch "," typeName ":" Microsoft.TeamFoundation.SourceControl.WebServer.InvalidArgumentValueException,
Microsoft.TeamFoundation.SourceControl.WebServer "," TypeKey ":" InvalidArgumentValueException "," error code ": 0," eventId ": 0}
In C:\Users\mkober\Desktop\Azure DevOps Skripte (Bearbeitung)\WikiAPI.ps1:34 Zeichen:11
+ $update = Invoke-RestMethod -Uri $url -Method Put -ContentType "appli ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
The first line /Seite2 = Seite 2 Content is the result of a successful get request from the page I want to edit. The put request occures the error. What am I doing wrong here?
UPDATE: (Working Example)
#VARIABLES
$api = "api-version=5.0"
$root = "http://136.202.18.216:8070/Samples"
$personalToken = "uwawlzqp6j7i1nd5dasspwkwp63tr2w2sxb5563zrla2bivynbza"
#AUTHORIZATION
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$headers = #{
"Authorization" = ('Basic {0}' -f $token)
"If-Match" = '{0}'
}
#PROJECT VARIABLES
$project = "Framework%20A"
$pageToUpdate = "/Seite2"
#BODY
$body = #"
{
"content": "Hello"
}
"#
#---------------------------------------------------------------------------------------------------------------------------
#GET
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&includeContent=True&$api"
$content = Invoke-WebRequest -Uri $url -Method Get -ContentType "application/json" -Headers $headers
$etag = $content.Headers.ETag
$headers.'If-Match' = $headers.'If-Match' -f $etag
Write-Host "$($content.path) = $($content.content)" -ForegroundColor Yellow
#PUT
$url = "$root/$project/_apis/wiki/wikis/2e887fde-ce76-4180-aa8d-f26ed4799eb3/pages?version=wikiMaster&path=$pageToUpdate&$api"
$update = Invoke-RestMethod -Uri $url -Method Put -ContentType "application/json" -Headers $headers -Body $body -Verbose
Write-Host $update.content -ForegroundColor Yellow
exit(0)
#---------------------------------------------------------------------------------------------------------------------------
In the If-Match header you can't just put '*', you need to put there the ETag of the page.
How do you get it? in your first GET call use Invoke-WebRequest (instaed of Invoke-RestMethod), now in the response you will get also headers response and there the ETag exist:
$page = Invoke-WebRequest -Uri $url ...........
$etag = $page.Headers.ETag
$headers = #{
"Authorizaion = ....."
"If-Match" = $etag
}
Now the second Invoke-RestMethod will work to update the page.
I'm trying to create a command in Powershell that is an equivalent of
curl -u username:abcd -i -F name=files -F filedata=#employees.csv https://myservice.com/v1/employees/csv
I need to have file name in the request. So in Powershell
$FilePath = 'employees.csv'
$FieldName = 'employees.csv'
$ContentType = 'text/csv'
$username = "user"
$password = "..."
$FileStream = [System.IO.FileStream]::new($filePath, [System.IO.FileMode]::Open)
$FileHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new('form-data')
$FileHeader.Name = $FieldName
$FileHeader.FileName = Split-Path -leaf $FilePath
$FileContent = [System.Net.Http.StreamContent]::new($FileStream)
$FileContent.Headers.ContentDisposition = $FileHeader
$FileContent.Headers.ContentType = [System.Net.Http.Headers.MediaTypeHeaderValue]::Parse($ContentType)
$MultipartContent = [System.Net.Http.MultipartFormDataContent]::new()
$MultipartContent.Add($FileContent)
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($username):$($password)" ))
$Response = Invoke-WebRequest -Headers #{Authorization = "Basic $base64AuthInfo" } -Body $MultipartContent -Method 'POST' -Uri 'https://myservice.com/v1/employees/csv'
Is there a better (shorter) way of doing this so I have a file name in Content Disposition?
$body = get-content employees.csv -raw
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("user:pass" ))
Invoke-RestMethod -Headers #{Authorization = "Basic $base64AuthInfo" } -uri url -Method Post -body $body -ContentType 'text/csv
# a flag -ContentDispositionFileName would be great
Taking a guess with what your endpoint will accept, but here's an example of your curl request in powershell:
$u, $p = 'username', 'password'
$b64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${u}:$p"))
$invokerestmethodParams = #{
'Uri' = 'https://myservice.com/v1/employees/csv'
'Method' = 'POST'
'Headers' = #{ Authorization = "Basic $b64" }
'InFile' = 'C:\path\to\employees.csv'
'SessionVariable' = 's' # use $s to view content headers, etc.
}
$output = Invoke-RestMethod #invokerestmethodParams
I've this command:
curl -s -L --header "PRIVATE-TOKEN:XXXX" https://myuri/"
And I need to convert to PowerShell
I've tried this, but doesn't works:
Invoke-RestMethod -Method Get -Headers #{"AUTHORIZATION"="XXXXXX"} -Uri https://myUri
I've also tried this:
PS > $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
PS > $headers.Add("Authorization","XXXXXX")
PS > $headers.Add("Accept","application/json")
PS > $headers.Add("Content-Type","application/json")
PS> $uri = "https://myUri"
PS> $response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get -ContentType "application/json"
PS> $response
PS>
but the $response is empty.
Any help ?
Here is one that I used to authenticate to Teamcity
function Connect-to-Teamcity ($userName, $password, $tcServer, $uri)
{
$auth = $username + ':' + $password
$Encoded = [System.Text.Encoding]::UTF8.GetBytes($auth)
$EncodedPassword = [System.Convert]::ToBase64String($Encoded)
$headers = #{"Authorization"="Basic $($EncodedPassword)"}
$url = "http://$tcServer/httpAuth/app/rest"
$result = Invoke-RestMethod -Uri "$url/$uri" -Header $headers -Method Get
return $result
}
Here is another example if you have more than one header Item:
$resourceAppIdURI = "https://graph.windows.net"
# Login to Azure and get a token valid for accessing the graph API
$authority = "https://login.windows.net/$adTenant"
$authContext = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList $authority
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")
# Add the token to the header of all future calls to the graph API
$headers = #{"Authorization"=$authResult.CreateAuthorizationHeader();"Content-Type"="application/json"}
$uri = [string]::Format("https://graph.windows.net/{0}/groups/{1}/appRoleAssignments?api-version=1.5", $adTenant, $groupId)
$body = #"
{
"id": $appRoleId,
"principalId": $groupId,
"principalType": "Group",
"resourceId": $appObjectId
}
"#
$result = Invoke-RestMethod -Method "POST" -Uri $uri -Headers $headers -Body $Body