After attempting several different examples I am unable to update list items using the Sharepoint REST API. I receive back a 400 error from the request.
The creplace is due to Sharepoint sending both ID and Id for some reason and breaking the ConvertFrom-Json in my Get-SPListItems method.
function Update-SPListItems
{
param
(
$listUpdate
)
$requestDigest = Get-RequestDigest
foreach($item in $listUpdate.Results)
{
$restUrl = $item.__metadata.uri
$item.tsFeedbackStatus = "Open"
$item.Modified = Get-Date -Format s
$updatedItem = $item | ConvertTo-Json
#convert back the duplicate field
$updatedItem = $updatedItem -creplace '"ignoreId":','"Id":'
$itemJsonBytes = [System.Text.Encoding]::ASCII.GetBytes($updatedItem)
try
{
#examples have shown POST/MERGE, POST/PATCH, MERGE/MERGE,
#PATCH/PATCH, none of them in those combinations have worked
$request = [System.Net.WebRequest]::Create($restUrl)
$request.Credentials = $Credential.GetNetworkCredential()
$request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
$request.Headers.Add("If-Match", "*")
$request.Headers.Add("X-RequestDigest", $requestDigest)
$request.Headers.Add("X-HTTP-Method", "MERGE")
$request.Accept = "application/json;odata=verbose"
$request.Method = "POST"
$request.ContentType = "application/json;odata=verbose"
$request.ContentLength = $itemJsonBytes.Length
$stream = $request.GetRequestStream()
$stream.Write($itemJsonBytes, 0, $itemJsonBytes.Length)
$stream.Close()
$response = $request.GetResponse()
}
catch [System.Exception]
{
Write-Error $_.Exception.ToString()
}
}
}
Here is the exact error:
Update-SPListItems : System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at CallSite.Target(Closure , CallSite , Object )
At C:\Users\user\Desktop\SPListTest.ps1:120 char:11
$result = Update-SPListItems $list
~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Update-SPListItems
Try the below reusable function for this. It worked for me every time. Ensure to pass the parameters properly. This has authentication built into it and even works for older versions of PowerShell.
function Request-Rest{
[CmdletBinding()]
PARAM (
[Parameter(Mandatory=$False)]
[String]$Metadata,
[Parameter(Mandatory=$true)]
[String] $URL,
[Parameter(Mandatory=$False)]
[Switch]$listUpdate,
[Parameter(Mandatory=$False)]
[String]$RequestDigest,
[Parameter(Mandatory=$false)]
[Microsoft.SharePoint.Client.SharePointOnlineCredentials] $credentials,
[Parameter(Mandatory=$false)]
[String] $UserAgent = "PowerShell API Client",
[Parameter(Mandatory=$false)]
[Switch] $JSON,
[Parameter(Mandatory=$false)]
[Switch] $Raw
)
#Create a URI instance since the HttpWebRequest.Create Method will escape the URL by default.
#$URL = Fix-Url $Url
$URI = New-Object System.Uri($URL,$true)
#Create a request object using the URI
$request = [System.Net.HttpWebRequest]::Create($URI)
#Build up a User Agent
$request.UserAgent = $(
"{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}),
[Environment]::Version,
[Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win")
)
if ($credentials -eq $null)
{
$request.UseDefaultCredentials = $true
}
else
{
$request.Credentials = $credentials
}
$request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
#Request Method
$request.Method = "POST"
#Headers
if($listUpdate)
{
$request.Headers.Add("X-RequestDigest", $RequestDigest)
$request.Headers.Add("If-Match", "*")
$request.Headers.Add("X-HTTP-Method", "MERGE")
$request.ContentType = "application/json;odata=verbose"
$request.Accept = "application/json;odata=verbose"
}
#Request Body
if($Metadata) {
$Body = [byte[]][char[]]$Metadata
$request.ContentLength = $Body.Length
$stream = $request.GetRequestStream()
$stream.Write($Body, 0, $Body.Length)
}
else {
$request.ContentLength = 0
}
try
{
[System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse()
}
catch
{
Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)"
}
$reader = [IO.StreamReader] $response.GetResponseStream()
if (($PSBoundParameters.ContainsKey('JSON')) -or ($PSBoundParameters.ContainsKey('Raw')))
{
$output = $reader.ReadToEnd()
}
else
{
$output = $reader.ReadToEnd()
}
$reader.Close()
if($output.StartsWith("<?xml"))
{
[xml]$outputXML = [xml]$output
}
else
{
[xml]$outputXML = [xml] ("<xml>" + $output + "</xml>")
}
Write-Output $outputXML
$response.Close()
}
Related
I want to use this powershell script to import and export platforms from cyberark. However, its showing this error:
Parameter set cannot be resolved using the specified named parameters.
+ CategoryInfo : InvalidArgument: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : AmbiguousParameterSet
I am not very not very fimilar with powershell yet. Could someone please help me out. I would really appricate it. I tried many changes but nothing is really happening. I need to fix this error as soon as possible. Please go through the code and give me solution to fix it.
param
(
[Parameter(Mandatory = $true, HelpMessage = "Please enter your PVWA address (For example: https://pvwa.mydomain.com/PasswordVault)")]
#[ValidateScript({Invoke-WebRequest -UseBasicParsing -DisableKeepAlive -Uri $_ -Method 'Head' -ErrorAction 'stop' -TimeoutSec 30})]
[Alias("url")]
[String]$PVWAURL,
[Parameter(Mandatory = $false, HelpMessage = "Enter the Authentication type (Default:CyberArk)")]
[ValidateSet("cyberark", "ldap", "radius")]
[String]$AuthType = "cyberark",
# Use this switch to Import a Platform
[Parameter(ParameterSetName = 'Import', Mandatory = $true)][switch]$Import,
# Use this switch to Export a Platform
[Parameter(ParameterSetName = 'Export', Mandatory = $true)][switch]$Export,
# Use this switch to Import a Platform using a file
[Parameter(ParameterSetName = 'ImportFile', Mandatory = $true)][switch]$ImportFile,
# Use this switch to Export a Platform using a file
[Parameter(ParameterSetName = 'ExportFile', Mandatory = $true)][switch]$ExportFile,
[Parameter(ParameterSetName = 'ExportActive', Mandatory = $true)][switch]$ExportActive,
[Parameter(ParameterSetName = 'ExportAll', Mandatory = $true)][switch]$ExportAll,
[Parameter(ParameterSetName = 'Export', Mandatory = $true, HelpMessage = "Enter the platform ID to export")]
[Alias("id")]
[string]$PlatformID,
[Parameter(ParameterSetName = 'Import', Mandatory = $true, HelpMessage = "Enter the platform Zip path for import")]
[Parameter(ParameterSetName = 'Export', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[Parameter(ParameterSetName = 'ImportFile', Mandatory = $false, HelpMessage = "Enter the platform Zip path for import")]
[Parameter(ParameterSetName = 'ExportFile', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[Parameter(ParameterSetName = 'ExportActive', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[Parameter(ParameterSetName = 'ExportAll', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[string]$PlatformZipPath,
# Use this to specify where file to read is
[Parameter(ParameterSetName = 'ImportFile', Mandatory = $true, HelpMessage = "Enter the import file path for import")]
[Parameter(ParameterSetName = 'ExportFile', Mandatory = $true, HelpMessage = "Enter the export file path for export")]
[string]$listFile,
[Parameter(Mandatory = $false)]
$creds,
# Use this switch to Disable SSL verification (NOT RECOMMENDED)
[Parameter(Mandatory = $false)]
[Switch]$DisableSSLVerify
)
# Global URLS
# -----------
$URL_PVWAAPI = $PVWAURL + "/api"
$URL_Authentication = $URL_PVWAAPI + "/auth"
$URL_Logon = $URL_Authentication + "/$AuthType/Logon"
$URL_Logoff = $URL_Authentication + "/Logoff"
# URL Methods
# -----------
$URL_GetPlatforms = $URL_PVWAAPI + "/Platforms"
$URL_PlatformDetails = $URL_PVWAAPI + "/Platforms/{0}"
$URL_ExportPlatforms = $URL_PVWAAPI + "/Platforms/{0}/Export"
$URL_ImportPlatforms = $URL_PVWAAPI + "/Platforms/Import"
# Initialize Script Variables
# ---------------------------
$rstusername = $rstpassword = ""
$logonToken = ""
#region Functions
Function Test-CommandExists {
Param ($command)
$oldPreference = $ErrorActionPreference
$ErrorActionPreference = 'stop'
try { if (Get-Command $command) { RETURN $true } }
Catch { Write-Host "$command does not exist"; RETURN $false }
Finally { $ErrorActionPreference = $oldPreference }
} #end function test-CommandExists
# #FUNCTION# ======================================================================================================================
# Name...........: Join-ExceptionMessage
# Description....: Formats exception messages
# Parameters.....: Exception
# Return Values..: Formatted String of Exception messages
# =================================================================================================================================
Function Join-ExceptionMessage {
<#
.SYNOPSIS
Formats exception messages
.DESCRIPTION
Formats exception messages
.PARAMETER Exception
The Exception object to format
#>
param(
[Exception]$e
)
Begin {
}
Process {
$msg = "Source:{0}; Message: {1}" -f $e.Source, $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n`t->Source:{0}; Message: {1}" -f $e.Source, $e.Message
}
return $msg
}
End {
}
}
#endregion
Function import-platform {
param(
[string]$PlatformZipPath
)
If (Test-Path $PlatformZipPath) {
$zipContent = [System.IO.File]::ReadAllBytes($(Resolve-Path $PlatformZipPath))
$importBody = #{ ImportFile = $zipContent; } | ConvertTo-Json -Depth 3 -Compress
try {
$ImportPlatformResponse = Invoke-RestMethod -Method POST -Uri $URL_ImportPlatforms -Headers $logonHeader -ContentType "application/json" -TimeoutSec 2700 -Body $importBody
Write-Debug "Platform ID imported: $($ImportPlatformResponse.PlatformID)"
Write-Host "Retrieving Platform details"
# Get the Platform Name
$platformDetails = Invoke-RestMethod -Method Get -Uri $($URL_PlatformDetails -f $ImportPlatformResponse.PlatformID) -Headers $logonHeader -ContentType "application/json" -TimeoutSec 2700
If ($platformDetails) {
Write-Debug $platformDetails
Write-Host "$($platformDetails.Details.PolicyName) (ID: $($platformDetails.PlatformID)) was successfully imported and $(if($platformDetails.Active) { "Activated" } else { "Inactive" })"
Write-Host "Platform details:"
$platformDetails.Details | Select-Object PolicyID, AllowedSafes, AllowManualChange, PerformPeriodicChange, #{Name = 'AllowManualVerification'; Expression = { $_.VFAllowManualVerification } }, #{Name = 'PerformPeriodicVerification'; Expression = { $_.VFPerformPeriodicVerification } }, #{Name = 'AllowManualReconciliation'; Expression = { $_.RCAllowManualReconciliation } }, #{Name = 'PerformAutoReconcileWhenUnsynced'; Expression = { $_.RCAutomaticReconcileWhenUnsynched } }, PasswordLength, MinUpperCase, MinLowerCase, MinDigit, MinSpecial
}
} catch {
#Write-Error $_.Exception
#Write-Error $_.Exception.Response
#Write-Error $_.Exception.Response.StatusDescription
($_.ErrorDetails | ConvertFrom-Json | Select-Object -Property ErrorMessage)
"Error while attempting to export $PlatformZipPath"
""
}
}
} #end function Import
Function export-platform {
param(
[string]$PlatformID
)
try {
$exportURL = $URL_ExportPlatforms -f $PlatformID
Invoke-RestMethod -Method POST -Uri $exportURL -Headers $logonHeader -ContentType "application/zip" -TimeoutSec 2700 -OutFile "$PlatformZipPath\$PlatformID.zip" -ErrorAction SilentlyContinue
} catch {
#Write-Error $_.Exception.Response
#Write-Error $_.Exception.Response.StatusDescription
($_.ErrorDetails | ConvertFrom-Json | Select-Object -Property ErrorMessage)
"Error while attempting to export $PlatformID"
""
}
} #end function Import
Function Get-PlatformsList {
param(
[switch]$GetAll
)
$idList = #()
try {
If ($GetAll){
$url = $URL_GetPlatforms + "?PlatformType=Regular"
} else {
$url = $URL_GetPlatforms + "?Active=True&PlatformType=Regular"
}
$result = Invoke-RestMethod -Method GET -Uri $url -Headers $logonHeader -ErrorAction SilentlyContinue
foreach ($platform in $result.Platforms){
$idList += $platform.general.id
}
return $idList
} catch {
#Write-Error $_.Exception.Response
#Write-Error $_.Exception.Response.StatusDescription
($_.ErrorDetails | ConvertFrom-Json | Select-Object -Property ErrorMessage)
"Error while attempting to export $PlatformID"
""
}
} #end function Import
If (Test-CommandExists Invoke-RestMethod) {
If ($DisableSSLVerify) {
try {
Write-Warning "It is not Recommended to disable SSL verification" -WarningAction Inquire
# Using Proxy Default credentials if the Server needs Proxy credentials
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
# Using TLS 1.2 as security protocol verification
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls11
# Disable SSL Verification
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $DisableSSLVerify }
} catch {
Write-Error "Could not change SSL validation"
Write-Error (Join-ExceptionMessage $_.Exception) -ErrorAction "SilentlyContinue"
return
}
} Else {
try {
Write-Debug "Setting script to use TLS 1.2"
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
} catch {
Write-Error "Could not change SSL settings to use TLS 1.2"
Write-Error (Join-ExceptionMessage $_.Exception) -ErrorAction "SilentlyContinue"
}
}
# Check that the PVWA URL is OK
If ($PVWAURL -ne "") {
If ($PVWAURL.Substring($PVWAURL.Length - 1) -eq "/") {
$PVWAURL = $PVWAURL.Substring(0, $PVWAURL.Length - 1)
}
} else {
Write-Host -ForegroundColor Red "PVWA URL can not be empty"
return
}
Write-Host "Export / Import Platform: Script Started" -ForegroundColor Cyan
#region [Logon]
# Get Credentials to Login
# ------------------------
$caption = "Export / Import Platform"
$msg = "Enter your User name and Password";
if ($Null -eq $creds) {$creds = $Host.UI.PromptForCredential($caption, $msg, "", "")}
if ($null -ne $creds) {
$rstusername = $creds.username.Replace('\', '');
$rstpassword = $creds.GetNetworkCredential().password
} else { return }
# Create the POST Body for the Logon
# ----------------------------------
$logonBody = #{ username = $rstusername; password = $rstpassword; concurrentSession = 'true' }
$logonBody = $logonBody | ConvertTo-Json
try {
# Logon
$logonToken = Invoke-RestMethod -Method Post -Uri $URL_Logon -Body $logonBody -ContentType "application/json"
} catch {
Write-Host -ForegroundColor Red $_.Exception.Response.StatusDescription
$logonToken = ""
}
If ($logonToken -eq "") {
Write-Host -ForegroundColor Red "Logon Token is Empty - Cannot login"
return
}
# Create a Logon Token Header (This will be used through out all the script)
# ---------------------------
$logonHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$logonHeader.Add("Authorization", $logonToken)
#endregion
switch ($PsCmdlet.ParameterSetName) {
"Import" {
import-platform $PlatformZipPath -error
}
"ImportFile" {
foreach ($line in Get-Content $listFile) {
Write-Debug "Trying to import $line"
if (![string]::IsNullOrEmpty($line)) { import-platform $line }
}
}
"Export" {
if (![string]::IsNullOrEmpty($PlatformID)) { export-platform $PlatformID}
}
"ExportFile" {
$null | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Force
foreach ($line in Get-Content $listFile) {
Write-Debug "Trying to export $line"
if (![string]::IsNullOrEmpty($line))
{
export-platform $line
("$PlatformZipPath\$line.zip").Replace("\\","\").Replace("/","\") | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Append
}
}
}
("ExportActive" -or "ExportAll") {
$platforms = Get-PlatformsList -GetAll:$(($PsCmdlet.ParameterSetName -eq "ExportAll"))
$null | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Force
foreach ($line in $platforms) {
Write-Debug "Trying to export $line"
if (![string]::IsNullOrEmpty($line)) {
export-platform $line
("$PlatformZipPath\$line.zip").Replace("\\","\").Replace("/","\") | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Append
}
}
}
}
# Logoff the session
# ------------------
Write-Host "Logoff Session..."
Invoke-RestMethod -Method Post -Uri $URL_Logoff -Headers $logonHeader -ContentType "application/json" | Out-Null
} else {
Write-Error "This script requires PowerShell version 3 or above"
}
Write-Host "Export / Import Platform: Script Finished" -ForegroundColor Cyan
I use rest api with powershell to get details from the Service Bus queue message. I am not sure when it happened, but now Content is in bytes ex: Content:{64, 6, 115, 116…}.
How can I convert it to the normal string with data?
function Get-SAStoken {
param (
$QueueName,
$Access_Policy_Name,
$Access_Policy_Key
)
$expireInSeconds = 300
[Reflection.Assembly]::LoadWithPartialName("System.Web")| out-null
$uri="my.servicebus.windows.net/$QueueName"
#Token expires now+300
$expires=([DateTimeOffset]::Now.ToUnixTimeSeconds())+ $expireInSeconds
$signatureString=[System.Web.HttpUtility]::UrlEncode($uri)+ "`n" + [string]$expires
$HMAC = New-Object System.Security.Cryptography.HMACSHA256
$HMAC.key = [Text.Encoding]::ASCII.GetBytes($Access_Policy_Key)
$signature = $HMAC.ComputeHash([Text.Encoding]::ASCII.GetBytes($signatureString))
$signature = [Convert]::ToBase64String($signature)
$sasToken = "SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}" -f [System.Web.HttpUtility]::UrlEncode($uri),
[System.Web.HttpUtility]::UrlEncode($signature),
[System.Web.HttpUtility]::UrlEncode($expires),
[System.Web.HttpUtility]::UrlEncode($Access_Policy_Name)
return $sasToken
}
function Get-SBmessage {
param (
$SASToken,
$Queue
)
$queue = $Queue
$header = #{ Authorization = $SASToken }
$postService = Invoke-WebRequest -Uri "https://my.servicebus.windows.net/$queue/messages/head" `
-Headers $header `
-Method Post
return $postService
}
$Queue = "capacity-checker"
$SAStokenRunningTest = Get-SAStoken -QueueName $Queue -Access_Policy_Name "pipeline" -Access_Policy_Key "key-for-sb-queue"
$SBmessage = Get-SBmessage -SASToken $SAStokenRunningTest -Queue $Queue
$SBmessage
So my solution is
[byte[]]$bytes = $SBmessage.Content
$msContent = [System.Text.Encoding]::ASCII.GetString($bytes)
Thanks, #MathiasR.Jessen for the help
Function jay {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Position = 0, Mandatory, HelpMessage = "Enter the new repository name")]
[ValidateNotNullorEmpty()]
[string]$Name,
[string]$Description,
[switch]$Private,
[switch]$NoWiki,
[switch]$NoIssues,
[switch]$NoDownloads,
[switch]$AutoInitialize,
#license templates found at https://github.com/github/choosealicense.com/tree/gh-pages/_licenses
[ValidateSet("MIT", "apache-2.0", "gpl-3.0", "ms-pl", "unlicense")]
[string]$LicenseTemplate,
[Alias("token")]
[ValidateNotNullorEmpty()]
[string]$UserToken = 'github token here',
#write full native response to the pipeline
[switch]$Raw
)
Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)"
#display PSBoundparameters formatted nicely for Verbose output
[string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd()
Write-Verbose "[BEGIN ] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*2)$_"}) | Out-String) `n"
#create the header
$head = #{
Authorization = 'Basic ' + $UserToken
}
#create a hashtable from properties
$hash = #{
name = $Name
description = $Description
private = $Private -as [boolean]
has_wiki = (-Not $NoWiki)
has_issues = (-Not $NoIssues)
has_downloads = (-Not $NoDownloads)
auto_init = $AutoInitialize -as [boolean]
}
if ($LicenseTemplate) {
$hash.add("license_template", $LicenseTemplate)
}
$body = $hash | ConvertTo-Json
Write-Verbose "[PROCESS] Sending json"
Write-Verbose $body
#define parameter hashtable for Invoke-RestMethod
$paramHash = #{
Uri = "https://api.github.com/user/repos"
Method = "Post"
body = $body
ContentType = "application/json"
Headers = $head
UseBasicParsing = $True
DisableKeepAlive = $True
}
#should process
if ($PSCmdlet.ShouldProcess("$name [$description]")) {
$r = Invoke-RestMethod #paramHash
if ($r.id -AND $Raw) {
Write-Verbose "[PROCESS] Raw result"
$r
}
elseif ($r.id) {
write-Verbose "[PROCESS] Formatted results"
$r | Select-Object #{Name = "Name"; Expression = { $_.name } },
#{Name = "Description"; Expression = { $_.description } },
#{Name = "Private"; Expression = { $_.private } },
#{Name = "Issues"; Expression = { $_.has_issues } },
#{Name = "Wiki"; Expression = { $_.has_wiki } },
#{Name = "URL"; Expression = { $_.html_url } },
#{Name = "Clone"; Expression = { $_.clone_url } }
}
else {
Write-Warning "Something went wrong with this process"
}
if ($r.clone_url) {
$msg = #"
To push an existing local repository to Github run these commands:
-> git remote add origin $($r.clone_url)"
-> git push -u origin master
"#
Write-Host $msg -ForegroundColor Green
}
}
Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)"
}
I am working on this Powershell script to accept creating Github repo from my local pc to Github. But every time I try to enter description it fails and provides me this error. Could someone please help me out
Invoke-RestMethod : {"message":"Requires
authentication","documentation_url":"https://developer.github.com/v3/repos/#create"}
At C:\Users\norep\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:96 char:14
It looks like you're trying to use your Github API token with Basic Authentication, but according to the Github API v3 documentation that token is an OAuth token. Your header should look like this instead:
$head = #{
Authorization = 'token ' + $UserToken
}
You would use the Basic auth header if you were providing a base64 encoded string of your username and password (in the format of USERNAME:PASSWORD):
$basicAuthBytes = [System.Text.Encoding]::UTF8.GetBytes('USERNAME:PASSWORD')
$basicAuthBase64String = [Convert]::ToBase64String( $basicAuthBytes )
$head = #{
Authorization = "Basic ${basicAuthBase64String"
}
I want to upload a file using powershell to a RestAPI. Sadly the invoke-restmethod does not support MultipartForm Uploads and even with building my own body it does not work. Therefore, I have to get this working using another way :)
Luckily I found this excellent blog post: http://blog.majcica.com/2016/01/13/powershell-tips-and-tricks-multipartform-data-requests/ and now I'm trying to build me a request using the .NET Client within Powershell. But I do hit my borders right now. I need to edit the standard header to add an authorization token. And I have no clue how! Would somebody please so kind and point me in the right direction how to do this? Thank you very much!
function Invoke-MultipartFormDataUpload
{
[CmdletBinding()]
PARAM
(
[string][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$InFile,
[string]$ContentType,
[Uri][parameter(Mandatory = $true)][ValidateNotNullOrEmpty()]$Uri,
[System.Management.Automation.PSCredential]$Credential
)
BEGIN
{
if (-not (Test-Path $InFile))
{
$errorMessage = ("File {0} missing or unable to read." -f $InFile)
$exception = New-Object System.Exception $errorMessage
$errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, 'MultipartFormDataUpload', ([System.Management.Automation.ErrorCategory]::InvalidArgument), $InFile
$PSCmdlet.ThrowTerminatingError($errorRecord)
}
if (-not $ContentType)
{
Add-Type -AssemblyName System.Web
$mimeType = [System.Web.MimeMapping]::GetMimeMapping($InFile)
if ($mimeType)
{
$ContentType = $mimeType
}
else
{
$ContentType = "application/octet-stream"
}
}
}
PROCESS
{
Add-Type -AssemblyName System.Net.Http
$httpClientHandler = New-Object System.Net.Http.HttpClientHandler
if ($Credential)
{
$networkCredential = New-Object System.Net.NetworkCredential #($Credential.UserName, $Credential.Password)
$httpClientHandler.Credentials = $networkCredential
}
$httpClient = New-Object System.Net.Http.Httpclient $httpClientHandler
$packageFileStream = New-Object System.IO.FileStream #($InFile, [System.IO.FileMode]::Open)
$contentDispositionHeaderValue = New-Object System.Net.Http.Headers.ContentDispositionHeaderValue "form-data"
$contentDispositionHeaderValue.Name = "fileData"
$contentDispositionHeaderValue.FileName = (Split-Path $InFile -leaf)
$streamContent = New-Object System.Net.Http.StreamContent $packageFileStream
$streamContent.Headers.ContentDisposition = $contentDispositionHeaderValue
$streamContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue $ContentType
$content = New-Object System.Net.Http.MultipartFormDataContent
$content.Add($streamContent)
try
{
$response = $httpClient.PostAsync($Uri, $content).Result
if (!$response.IsSuccessStatusCode)
{
$responseBody = $response.Content.ReadAsStringAsync().Result
$errorMessage = "Status code {0}. Reason {1}. Server reported the following message: {2}." -f $response.StatusCode, $response.ReasonPhrase, $responseBody
throw [System.Net.Http.HttpRequestException] $errorMessage
}
return $response.Content.ReadAsStringAsync().Result
}
catch [Exception]
{
$PSCmdlet.ThrowTerminatingError($_)
}
finally
{
if($null -ne $httpClient)
{
$httpClient.Dispose()
}
if($null -ne $response)
{
$response.Dispose()
}
}
}
END { }
}
Try this
#Authorization
$httpClient.DefaultRequestHeaders.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", $accesstoken);
Read over the stackoverflow for the answer, still can't find what causing this..
Trying to connect and send a POST request using powershell, and getting "unable to connect to remote server" error. Tried 3 different dummy servers like http://posttestserver.com/post.php
Script:
Get-ExecutionPolicy
[string]$url = "http://posttestserver.com/post.php"
function Execute-HTTPPostCommand()
{
param([string]$target = $null)
#$username = "administrator"
#$password = "mypass"
$webRequest = [System.Net.WebRequest]::Create($target)
$webRequest.ContentType = "text/html"
$post = "abcdefg"
$PostStr = [System.Text.Encoding]::UTF8.GetBytes($Post)
$webrequest.ContentLength = $PostStr.Length
$webRequest.ServicePoint.Expect100Continue = $false
#$webRequest.Credentials = New-Object System.Net.NetworkCredential -ArgumentList $username, $password
#$webRequest.PreAuthenticate = $true
$webRequest.Method = "POST"
try
{
$requestStream = $webRequest.GetRequestStream()
}
catch
{
write-host $_.Exception
}
$requestStream.Write($PostStr, 0,$PostStr.length)
$requestStream.Close()
[System.Net.WebResponse]$resp = $webRequest.GetResponse();
$rs = $resp.GetResponseStream();
[System.IO.StreamReader]$sr = New-Object System.IO.StreamReader -argumentList $rs;
[string]$results = $sr.ReadToEnd();
return $results;
}
Execute-HTTPPostCommand $url
[System.GC]::Collect()