7

I'm trying to use HttpClient with a custom HttpClientHandler (to fix a Cookie issue not correctly managed with redirection).

Both are into the System.Net.Http assembly (and namespace) and Powershell (and ISE) can't see the classes (nor the namespace) most of the time.

It does find a class System.Net.Http (in fact it is WebRequestMethods.Http) which I won't be surprised breaks everything.

So I created this KISS sample:

using namespace System.Net.Http

class Wtf : HttpClientHandler {
}

$t = [HttpClient]::new()

If I run it, it will tell me the type doesn't exist. (It also does if I use the full namespace instead of using).

What is funny however is what comes next. If I use the same code within ISE, the IDE will only tell me the base class HttpClient can't be found. (Nothing about the instantiation)

I found that Add-Type can help me here, so I add

Add-Type -AssemblyName System.Net.Http

Write-Host "Hello World"

between using namespace System.Net.Http and class Wtf : HttpClientHandler {

I still got the same error when trying to run it - but I don't see my "Hello World" at all! So it seems to fail when parsing it and it doesn't even try to run it. ISE still displays the same error within the IDE.

Then if I run Add-Type -AssemblyName System.Net.Http before running the script again (both from a PowerShell prompt or the ISE) everything runs without an issue. Also from then, the ISE IDE intellisense can list everything within the System.Net.Http namespace.

So how can a user only start my PowerShell script instead of having to both run Add-Type and my script?

I'm using PS 5.1 on Win10 and I'm new with the PowerShell environment, though I do have a C# background.

EDIT1: Use HttpClientHandler instead of HttpClient (but whatever the issue is the same)

EDIT2: Here what I'm using right now

using assembly System.Net.Http
using namespace System.Net.Http

class Test : HttpClient {
}

[HttpClient]::new()

Here's the output:

Au caractère C:\Users\0xdcdcdcd\Desktop\Test.ps1:4 : 14
+ class Test : HttpClient {
+              ~~~~~~~~~~
Type [HttpClient] introuvable.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TypeNotFound
0xCDCDCDCD
  • 364
  • 1
  • 3
  • 16
  • Why can't you have add-type or using assembly in the script the user runs? – js2010 Aug 22 '19 at 13:36
  • As for the Add-Type the issue is not I don't want to use it, it is PowerShell that doesn't run it (or that doesn't do within my script). I didn't know about using assembly until now. Even with using assembly I still have the error. See me EDIT2. – 0xCDCDCDCD Aug 22 '19 at 17:15

2 Answers2

8
# test.ps1
Add-Type -AssemblyName System.Net.Http

class Test : system.Net.Http.HttpClient {
}


At C:\users\admin\test.ps1:3 char:14
+ class Test : system.Net.Http.HttpClient {
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~
Unable to find type [system.Net.Http.HttpClient].
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TypeNotFound

I understand now. It's crazy that it doesn't work in a script. I believe some solutions are offered here: Powershell: Unable to find type when using PS 5 classes

EDIT: Actually, this works for me in PS 6. If you're in Windows 10 1809, a lot of the commands work again in PS 6.

js2010
  • 23,033
  • 6
  • 64
  • 66
  • It indeed fix the `[HttpClient]::new()`, but not the base class. (BTW: For the base class I used HttpClient but it should be HttpClientHandler, anyway in both case I still have a parsing issue). – 0xCDCDCDCD Aug 22 '19 at 11:42
  • I don't understand the question. Can you give an example of code that doesn't work, and the error message it results in? – js2010 Aug 22 '19 at 11:47
  • I added an "EDIT2" with the current example + result (error). – 0xCDCDCDCD Aug 22 '19 at 17:16
  • Ok I will look at your stackoverflow solution, seem pretty much my issue! Thanks!. I hate to be cursed... it took me 2 days to do a simple HttpClient; because I found a bug with HttpClient cookies and now in PowerShell... FML – 0xCDCDCDCD Aug 22 '19 at 19:52
4

So how can a user only start my PowerShell script instead of having to both run Add-Type and my script?

It's pretty common to see advanced PowerShell scripts begin with a few using statements, so you could begin your script like so:

using assembly System.Net.Http
using namespace System.Net.Http
#your code here

But most of the time in modern PowerShell, especially for web commands you can and should begin by using the PowerShell cmdlet.

My question to you then is what is it you're looking to do with HttpClient? Let me know what you want to do and I will be happy to show you the 'PowerShell' way to do it :)

FoxDeploy
  • 12,569
  • 2
  • 33
  • 48
  • I tried to use Invoke-WebRequest but I can't use it: PS5.1 doesn't support -Authentication nor -Form so I have to build -Body myself (I need to post form-data + a file). Unfortunately, you can't use -Body with -InFile. I found MultipartFormDataContent but it doesn't support it as a -Body (it send the full namespace instead of his content) – 0xCDCDCDCD Aug 22 '19 at 17:24