Reputation: 43
I have found this code
// "url" is the full destination path (including filename, i.e. https://mysite.sharepoint.com/Documents/Test.txt)
// "cookie" is the CookieContainer generated from Wichtor's code
// "data" is the byte array containing the files contents (used a FileStream to load)
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
request.Method = "PUT";
request.Accept = "*/*";
request.ContentType = "multipart/form-data; charset=utf-8";
request.CookieContainer = cookie; request.AllowAutoRedirect = false;
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
request.Headers.Add("Accept-Language", "en-us");
request.Headers.Add("Translate", "F"); request.Headers.Add("Cache-Control", "no-cache"); request.ContentLength = data.Length;
using (Stream req = request.GetRequestStream())
{ req.Write(data, 0, data.Length); }
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream res = response.GetResponseStream();
StreamReader rdr = new StreamReader(res);
string rawResponse = rdr.ReadToEnd();
response.Close();
rdr.Close();
Which apparently successfully uploads a large file to a sharepoint site, however my code is in powershell. Is there anyway to use this in powershell in its form now or even convert this to powershell?
Upvotes: 3
Views: 1573
Reputation: 174545
C# code is, as a general rule, easily translated to PowerShell because C# uses the exact same underlying type system and runtime environment as PowerShell (.NET).
A few things to watch out for:
C# is a type-safe language, meaning that the compiler guarantees the type of a variable and its value, as seen in your example:
HttpWebRequest request = HttpWebRequest.Create(url);
// ^ ^ \________________________/^
// | | | |
// | variable name | statement terminator ";"
// type-name |
// static method call that returns a
// value we can assign to "request"
In PowerShell:
$
Create()
method above), we use the following syntax:
[Namespace.TypeName]::Member
;
is unnecessary, a linebreak after a statement implies terminationThus, the above statement becomes:
$request = [System.Net.HttpWebRequest]::Create($url)
The two C# boolean keywords (true
and false
) are, in PowerShell, represented by two automatic variables called $true
and $false
:
[System.Net.ServicePointManager]::Expect100Continue = $false
using
PowerShell doesn't have a construct comparable to C#'s using
statement. To ensure disposal of an object that implements IDisposable
, you'll have to use try
/catch
/finally
:
$req = $request.GetRequestStream()
try{
$req.Write($data, 0, $data.Length)
} catch {
throw $_
} finally {
if($req){
$req.Dispose()
}
}
PowerShell doesn't have a new
keyword for object instantiation, but provides the New-Object
cmdlet that can wrap C# constructors:
$rdr = New-Object -TypeName System.IO.StreamReader -ArgumentList $res
Rather than:
StreamReader rdr = new StreamReader(res);
In PowerShell 5.0 and newer, you can now invoke constructors using the new
static method as well:
$rdr = [System.IO.StreamReader]::new($res)
PowerShell supports both explicit casting that in C# would look like (typename)variable
, but again, with square brackets instead of parentheses:
[System.Net.HttpWebResponse]$request.GetResponse()
And (as of version 3.0) it supports unchecked casting as well (still with square brackets):
$request.GetResponse() -as [System.Net.HttpWebResponse]
The latter will return $null
, rather than throw an error, if the cast is not possible.
This should get you translating in no time. From the comments in your codefind, it seems you might need to translate "Wichtor's code" as well, in order to generate the $cookie
container.
Upvotes: 18
Reputation: 575
See below example. I had to wrap the code in class and function.
$code = @"
using System.Security.Policy;
using System.IO;
using System.Net;
public class MySharepointTools
{
public void UploadFile(System.String url, System.Net.CookieContainer cookie, System.Byte[] data)
{
System.Net.ServicePointManager.Expect100Continue = false;
HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
request.Method = "PUT";
request.Accept = "*/*";
request.ContentType = "multipart/form-data; charset=utf-8";
request.CookieContainer = cookie; request.AllowAutoRedirect = false;
request.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
request.Headers.Add("Accept-Language", "en-us");
request.Headers.Add("Translate", "F"); request.Headers.Add("Cache-Control", "no-cache"); request.ContentLength = data.Length;
using (Stream req = request.GetRequestStream())
{ req.Write(data, 0, data.Length); }
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream res = response.GetResponseStream();
StreamReader rdr = new StreamReader(res);
string rawResponse = rdr.ReadToEnd();
response.Close();
rdr.Close();
}
}
"@
Add-Type -TypeDefinition $code -Language CSharp
$tools = New-Object MySharepointTools
Now you can call the method using
$Tools.UploadFile(url, cookie, data)
Upvotes: 2