[UPDATE 2014-04-08] Thanks to Meir I updated the post as the code was missing the definition for the regular expression. Now I corrected that, so the code should work now. In addition, I found out that the apple web server is not serving ‘Set-Cookie’ header according to RFC so I changed the example from apple.com to google.ch (as we are in Switzerland). Furthermore, keep in mind that even when you request e.g. ‘http://www.google.de’ you might be ending up with cookies from ‘google.com’ (as you get redirected). If in doubt use Fiddler to trace the traffic.
[UPDATE 2014-04-08 END]
When you use the Invoke-WebRequest Cmdlet that is available since PowerShell 3.0 you have the option of saving a “WebSession” object via the “-SessionVariable” parameter. This comes in handy when you load web pages that have session state cookies so you can make subsequent and stay in the same session (via the “-WebSession” parameter).
Unfortunately not all cookies returned by web pages are saved into this variable. You can easily observe this behaviour when comparing the “Set-Cookie” header in the response headers with the cookies saved in the session variable:
$Uri = "http://www.google.ch/" $r = Invoke-WebRequest -Uri $Uri -Method GET -SessionVariable s; $s.Cookies.GetCookies($Uri) Comment : CommentUri : HttpOnly : False Discard : False Domain : .google.ch Expired : False Expires : 07.04.2016 11:00:27 Name : PREF Path : / Port : Secure : False TimeStamp : 08.04.2014 11:00:24 Value : ID=8433f29e7847bc24:FF=0:TM=1396947627:LM=1396947627:S=Gm0Sn_3dalialh6o Version : 0 Comment : CommentUri : HttpOnly : True Discard : False Domain : .google.ch Expired : False Expires : 08.10.2014 11:00:27 Name : NID Path : / Port : Secure : False TimeStamp : 08.04.2014 11:00:24 Value : 67=B9UgmJrwbNRJQ64FpOnJKNJKiVXtbw81VuwxyQ4bLugd5tX1r3Ocg0ITtWRpI038ru6fJ3qB1ju1f8RcX19Flk-vTZ6T2zcw8BzRehq u4cwmbFYza4d8zAuFYupiMzq8 Version : 0 $SetCookieHeader = $r.Headers.'set-cookie'; $SetCookieHeader PREF=ID=8433f29e7847bc24:FF=0:TM=1396947627:LM=1396947627:S=Gm0Sn_3dalialh6o; expires=Thu, 07-Apr-2016 09:00:27 GMT; pa th=/; domain=.google.ch,NID=67=B9UgmJrwbNRJQ64FpOnJKNJKiVXtbw81VuwxyQ4bLugd5tX1r3Ocg0ITtWRpI038ru6fJ3qB1ju1f8RcX19Flk-v TZ6T2zcw8BzRehqu4cwmbFYza4d8zAuFYupiMzq8; expires=Wed, 08-Oct-2014 09:00:27 GMT; path=/; domain=.google.ch; HttpOnly [/sourcode] In order to get all cookie into the SessionVariable you have to extract them from the Set-Cookie header and construct a Cookie header manually similar to this: function ConvertFrom-SetCookieHeader { [cmdletbinding()] Param ( #Define parameters [Parameter(Mandatory=$true,Position=0)] [string] $SetCookieHeader ) $res = @{} $res.SetCookieSplit = "([^=]+)=([^;]+);\ "; $SetCookie = $SetCookieHeader; #$r.Headers.'set-cookie'; $SetCookie = $SetCookie.Replace('Secure,', 'Secure=1;').Replace('Secure;', 'Secure=1;'); $SetCookie = $SetCookie.Replace('HTTPOnly,', 'HTTPOnly=1;').Replace('HTTPOnly;', 'HTTPOnly=1;'); $MatchInfo = Select-String -InputObject $SetCookie $res.SetCookieSplit -AllMatches; $CookieHeader = ""; foreach($Match in $MatchInfo.Matches) { if(!$Match.Success) { continue; } $CookieName = $Match.Groups.Value[1].Trim(); $CookieValue = $Match.Groups.Value[2].Trim(); #$CookiePath = $res.CookiePathDefault; $CookieDomain = $WebHost; switch($CookieName) { "version" { break; } "path" { break; } "domain" { break; } "expires" { break; } "HTTPOnly" { break; } "Secure" { break; } default { Log-Debug $fn ("'{0}' = '{1}'" -f $CookieName, $CookieValue); if(!$CookieHeader) { $CookieHeader = ("{0}={1}" -f $CookieName, $CookieValue); } else { $CookieHeader += ("; {0}={1}" -f $CookieName, $CookieValue); } # if } } # switch } # foreach Match return $CookieHeader; } # ConvertFrom-SetCookieHeader
What should be set in $res variable? The code does not work.
Hi Meir, you are right. $res is a hashtable that has a key “SetCookieSplit” that holds the regular expression (“([^=]+)=([^;]+);\ “) for match on the Cookie header. I updated the post. Thanks!
Yes, it works, Thank you for your quick response and your effort to help to others.
I was able to gather cookies by using your function “ConvertFrom-SetCookieHeader” but how do i use this cookies to set and make next invoke-webrequest call
To send cookies with Invoke-WebRequest you can create a session, add cookies to it and pass it to the Cmdlet with the WebSession parameter. Here is a good example on how to do it: https://blog.gripdev.xyz/2015/05/27/powershell-invoke-webrequest-with-a-cookie/