I updated the biz.dfch.PS.Storebox.Api for being able to have file transfers to and from Ctera (Storebox) via its REST API. There you will also find the link to the NuGet package and the Github repository.

With it you can get a directory listing, download and upload a file. It uses our logging module as well as the generic ‘Invoke-CteraRestCommand’. There is an issue with writing an error to the log while doing a delete which you can safely ignore. Have fun …


// https://d-fens.ch/2013/11/27/biz-dfch-ps-storebox-api-invoke-cterafiletransfer/
// Check https://github.com/dfch/biz.dfch.PS.Storebox.Api for the complete repository of this module
function Invoke-CteraFileTransfer {
[CmdletBinding(
SupportsShouldProcess=$true,
ConfirmImpact="High",
HelpURI='http://dfch.biz/PS/Storebox/Api/Invoke-CteraFileTransfer'
)]
[OutputType([string])]
Param (
[Parameter(Mandatory = $false, Position = 2)]
[alias("s")]
$Session = $biz_dfch_PS_Storebox_Api.Session
,
[Parameter(Mandatory = $true, ParameterSetName = 'u')]
[alias("u")]
[switch] $Upload
,
[Parameter(Mandatory = $true, ParameterSetName = 'd')]
[alias("d")]
[switch] $Download
,
[Parameter(Mandatory = $true, ParameterSetName = 'del')]
[alias("del")]
[switch] $Delete
,
[Parameter(Mandatory = $true, ParameterSetName = 'm')]
[alias("m")]
[switch] $Move
,
[Parameter(Mandatory = $true, ParameterSetName = 'c')]
[alias("c")]
[switch] $Copy
,
[Parameter(Mandatory = $false)]
[Alias('p')]
[Alias('Portal')]
[string] $PortalName = $biz_dfch_PS_Storebox_Api.PortalName
,
[Parameter(Mandatory = $false, Position = 0)]
[alias("Source")]
[string] $Api = '/'
,
[Parameter(Mandatory = $false, ParameterSetName = 'u')]
[Parameter(Mandatory = $false, ParameterSetName = 'd')]
[switch] $AutomaticFileName = $true
,
[Parameter(Mandatory = $false, ParameterSetName = 'u')]
[switch] $Folder = $false
,
[Parameter(Mandatory = $false, Position = 1, ParameterSetName = 'u')]
[Parameter(Mandatory = $false, Position = 1, ParameterSetName = 'd')]
[string] $Path = $PWD
,
[Parameter(Mandatory = $false, ParameterSetName = 'u')]
[switch] $CreateDirectory = $false
,
[Parameter(Mandatory = $false, ParameterSetName = 'd')]
[switch] $ListAvailable = $false
,
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'm')]
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'c')]
[string] $NewUri
) # Param
BEGIN {
$datBegin = [datetime]::Now;
[string] $fn = $MyInvocation.MyCommand.Name;
Log-Debug -fn $fn -msg ("CALL. ParameterSetName '{0}'; Api: '{1}'." -f $PSCmdlet.ParameterSetName, $Api) -fac 1;
}
PROCESS {
[boolean] $fReturn = $false;
try {
# Parameter validation
if( $Session -isnot [System.Collections.Hashtable] ) {
Log-Error $fn ("Invalid input parameter type specified: Session. Aborting …");
throw($gotoFailure);
} # if
if(!$Session.ContainsKey('WebSession')) {
Log-Error $fn ("Invalid input parameter type specified: Session [{0}] does not contain key 'WebSession'. Aborting …" -f $Session.GetType().FullName);
throw($gotoFailure);
} #if
$WebRequestSession = $Session.WebSession;
if( $WebRequestSession -isnot [Microsoft.PowerShell.Commands.WebRequestSession] ) {
Log-Error $fn ("Invalid input parameter type specified: WebRequestSession [{0}]. Aborting …" -f $WebRequestSession.GetType().FullName);
throw($gotoFailure);
} # if
if(!$Session.ContainsKey('UriPortal')) {
Log-Error $fn ("Invalid input parameter type specified: Session [{0}] does not contain key 'UriPortal'. Aborting …" -f $Session.GetType().FullName);
throw($gotoFailure);
} #if
if(!$PortalName) {
Log-Error $fn ("Invalid input parameter type specified: 'PortalName' is not set. Aborting …");
throw($gotoFailure);
} #if
$UriAdmin = '{0}{1}' -f $Session.UriPortal, $biz_dfch_PS_Storebox_Api.UriBaseLocal;
if($Api.StartsWith($UriAdmin)) { $Api = $Api.Replace($UriAdmin, ''); }
if($Api.StartsWith($biz_dfch_PS_Storebox_Api.UriBaseLocal)) { $Api = $Api.Replace($biz_dfch_PS_Storebox_Api.UriBaseLocal, ''); }
$Api = $Api.TrimStart('/');
if(!$Api.StartsWith('webdav')) { $Api = 'webdav/{0}' -f $Api; }
$Api = $Api.TrimStart('/');
if([string]::IsNullOrEmpty($Api) -or [string]::IsNullOrWhiteSpace($Api)) {
Log-Error $fn "Invalid or empty input parameter specified: Api. Aborting …";
throw($gotoFailure);
} # if
switch($PSCmdlet.ParameterSetName) {
'd' {
$Method = 'GET';
} # 'd'
'u' {
$Method = 'PUT';
$fReturn = Test-Path -Path $Path;
if($fReturn) {
$File = Get-Item -Path $Path;
} else {
$fReturn = Test-Path -LiteralPath $Path;
} # if
if($fReturn -and !$File) {
$File = Get-Item -LiteralPath $Path;
} elseif($File) {
# good – we got a file object
$Path = $File.FullName;
} else {
$e = New-CustomErrorRecord -m ("Unsupported ParameterSetName '{0}'." -f $PSCmdlet.ParameterSetName) -cat ObjectNotFound -o $Path;
throw($gotoError);
} # if
} # 'u'
'del' {
$Method = 'DELETE';
} # 'del'
'm' {
$Method = 'MOVE';
} # 'm'
'c' {
$Method = 'COPY';
} # 'c'
default {
$e = New-CustomErrorRecord -m ("Unsupported ParameterSetName '{0}'." -f $PSCmdlet.ParameterSetName) -cat InvalidArgument -o $PSCmdlet.ParameterSetName;
throw($gotoError);
}
} # switch
if($PSCmdlet.ParameterSetName -eq 'd') {
$Uri = ('{0}{1}') -f $UriAdmin, $Api;
[Uri] $UriUri = $Uri;
if($AutomaticFileName) {
$Path = Join-Path -Path $Path -ChildPath $UriUri.Segments[-1];
} # if
$Uri = $UriUri.AbsoluteUri;
} # if
if($PSCmdlet.ParameterSetName -eq 'u') {
[Uri] $UriPath = $Path;
$Uri = ('{0}{1}') -f $UriAdmin, $Api;
[Uri] $UriUri = $Uri;
if($AutomaticFileName) {
$Uri = '{0}/{1}' -f $UriUri.AbsoluteUri.TrimEnd('/'), $UriPath.Segments[-1];
[Uri] $UriUri = $Uri;
} # if
$Uri = $UriUri.AbsoluteUri;
} # if
if($PSCmdlet.ParameterSetName -eq 'del') {
$Uri = ('{0}{1}') -f $UriAdmin, $Api;
[Uri] $UriUri = $Uri;
$Uri = $UriUri.AbsoluteUri;
} # if
$QueryParameters = 'portalName={0}' -f $PortalName;
$Uri = ('{0}?{1}' -f $Uri, $QueryParameters).TrimEnd('?');
[Uri] $UriUri = $Uri;
$Uri = $UriUri.AbsoluteUri;
# create WebClient
$wc = New-Object System.Net.WebClient;
$wc.Encoding = [System.Text.Encoding]::UTF8;
$wc.Headers.Clear();
$wc.Headers.Add("Cookie", $WebRequestSession.Cookies.GetCookieHeader($uri))
#$wc.Headers.Add('Content-Type', 'text/xml; charset=UTF-8');
$wc.Headers.Add('Content-Type', 'application/octet-stream');
$wc.Headers.Add('Accept', '*/*');
#$wc.Headers.Add('x-ctera-token', $WebRequestSession.Cookies.GetCookieHeader($uri));
$wc.Headers.Add('x-ctera-token', $biz_dfch_PS_Storebox_Api.SessionCookie.Value);
$wc.Headers.Add('User-Agent', $WebRequestSession.UserAgent);
$msg = "Invoking '{0}' '{1}' [on '{2}'] …" -f $Method, $Uri, $Path;
Log-Debug $fn $msg;
if(!$PSCmdlet.ShouldProcess($msg)) {
$fReturn = $false;
} else {
[string] $response = '';
$Method = $Method.ToUpper();
if($Method -eq 'GET') {
if($ListAvailable) {
$Method = 'PROPFIND';
$response = $wc.UploadString($Uri, $Method, '');
Log-Debug $fn ("response count '{0}'" -f $r.multistatus.response.Count);
# $response = $true;
} else {
$response = $wc.DownloadFile($Uri, $Path);
$response = $true;
} # if
} elseif($Method -eq 'DELETE') {
$response = $wc.UploadString($Uri, $Method, '');
} else {
if($CreateDirectory) {
$Method = 'MKCOL';
$response = $wc.UploadString($Uri, $Method, '');
} else {
$response = $wc.UploadFile($Uri, $Method, $Path);
} # if
} # if
if(!$response) {
Log-Error $fn ("Invoking '{0}' '{1}' FAILED. '{2}'" -f $Method, $Uri, $error[0]);
throw($gotoFailure);
} # if
Log-Info $fn ("Invoking '{0}' '{1}' SUCCEEDED." -f $Method, $Uri);
$OutputParameter = $response;
$fReturn = $true;
} # if
} # try
catch {
if($gotoSuccess -eq $_.Exception.Message) {
$fReturn = $true;
} else {
[string] $ErrorText = "catch [$($_.FullyQualifiedErrorId)]";
$ErrorText += (($_ | fl * -Force) | Out-String);
$ErrorText += (($_.Exception | fl * -Force) | Out-String);
$ErrorText += (Get-PSCallStack | Out-String);
if($_.Exception.InnerException -is [System.Net.WebException]) {
Log-Critical $fn ("Operation '{0}' '{1}' FAILED [{2}]." -f $Method, $Uri, $_);
Log-Debug $fn $ErrorText -fac 3;
} # [System.Net.WebException]
else {
Log-Error $fn $ErrorText -fac 3;
if($gotoError -eq $_.Exception.Message) {
Log-Error $fn $e.Exception.Message;
$PSCmdlet.ThrowTerminatingError($e);
} elseif($gotoFailure -ne $_.Exception.Message) {
Write-Verbose ("$fn`n$ErrorText");
} else {
# N/A
} # if
} # other exceptions
$fReturn = $false;
$OutputParameter = $null;
} # !$gotoSuccess
} # catch
finally {
# Clean up
if($wc -is [System.Net.WebClient]) { $wc.Dispose(); }
} # finally
return $OutputParameter;
} # PROCESS
END {
$datEnd = [datetime]::Now;
Log-Debug -fn $fn -msg ("RET. fReturn: [{0}]. Execution time: [{1}]ms. Started: [{2}]." -f $fReturn, ($datEnd – $datBegin).TotalMilliseconds, $datBegin.ToString('yyyy-MM-dd HH:mm:ss.fffzzz')) -fac 2;
} # END
} # function
Export-ModuleMember -Function Invoke-CteraFileTransfer;

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.