From de2fa020d4674dd137b1da7db58feb2d3d06e7bd Mon Sep 17 00:00:00 2001 From: he852100 Date: Tue, 21 Jan 2020 15:08:55 +0800 Subject: [PATCH 01/18] Linux path --- Sources/OneDrive.psm1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 50891f0..0bf4bb1 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -651,13 +651,14 @@ function Get-ODItem { $Download=Get-ODItemProperty -AccessToken $AccessToken -ResourceId $ResourceId -Path $Path -ElementId $ElementId -DriveId $DriveId -SelectProperties "name,@content.downloadUrl,lastModifiedDateTime" if ($LocalPath -eq "") {$LocalPath=Get-Location} + $LocalPath=resolve-Path ($LocalPath.TrimEnd("\")+"\") if ($LocalFileName -eq "") { - $SaveTo=$LocalPath.TrimEnd("\")+"\"+$Download.name + $SaveTo=$LocalPath+$Download.name } else { - $SaveTo=$LocalPath.TrimEnd("\")+"\"+$LocalFileName + $SaveTo=$LocalPath+$LocalFileName } try { @@ -921,4 +922,4 @@ function Move-ODItem return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method PATCH -rURI $rURI -Body $body } } -} \ No newline at end of file +} From 762b54668587d0cc10c7388cb5c40d0745d3df4a Mon Sep 17 00:00:00 2001 From: he852100 Date: Tue, 21 Jan 2020 15:47:51 +0800 Subject: [PATCH 02/18] add global Variable --- Sources/OneDrive.psm1 | 81 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 17 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 0bf4bb1..ec9921a 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -39,7 +39,8 @@ function Get-ODAuthentication [string]$ResourceId="", [switch]$DontShowLoginScreen=$false, [switch]$AutoAccept, - [switch]$LogOut + [switch]$LogOut, + [switch]$enableglobal ) $optResourceId="" $optOauthVersion="/v2.0" @@ -67,7 +68,8 @@ function Get-ODAuthentication } else { write-debug("Authentication mode: " +$Type) - [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null + $ErrorActionPreference="SilentlyContinue" + if([Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") ){$Verify} [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null [Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null if ($Logout) @@ -87,6 +89,7 @@ function Get-ODAuthentication $URIGetAccessToken="https://login.live.com/oauth20_authorize.srf?client_id="+$ClientId+"&scope="+$Scope+"&response_type="+$Type+"&redirect_URI="+$RedirectURI } } + if($Verify){ $form = New-Object Windows.Forms.Form $form.text = "Authenticate to OneDrive" $form.size = New-Object Drawing.size @(700,600) @@ -106,6 +109,7 @@ function Get-ODAuthentication } $web.Add_DocumentCompleted($DocComplete) $form.Controls.Add($web) + } if ($DontShowLoginScreen) { write-debug("Logon screen suppressed by flag -DontShowLoginScreen") @@ -149,6 +153,10 @@ function Get-ODAuthentication { write-warning("There is maybe an errror, because there is no access_token!") } + $Authentication | add-member Noteproperty "ClientId" ($ClientId) + if($enableglobal){ + $Global:Authentication=$Authentication + } return $Authentication } function Get-ODRootUri @@ -187,7 +195,7 @@ function Get-ODWebContent Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$rURI = "", @@ -203,15 +211,28 @@ function Get-ODWebContent { $xBody=$Body } + $ODRootURI=Get-ODRootUri -ResourceId $ResourceId +do{ +$doCount++ +if($doCount -ne 1){ +if ($Authentication -ne $null ) { +$null=Get-ODAuthentication -ClientId $Authentication.ClientId -enableglobal +if(-not($?)){break} +} +else{$null=Get-ODAuthentication -enableglobal +if(-not($?)){break}}} +if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { $webRequest=Invoke-WebRequest -Method $Method -Uri ($ODRootURI+$rURI) -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $xBody -UseBasicParsing -ErrorAction SilentlyContinue + $errorcode=$? } catch { write-error("Cannot access the api. Webrequest return code is: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) break } +}until($errorcode -or $doCount -ne 1) switch ($webRequest.StatusCode) { 200 @@ -252,7 +273,7 @@ function Get-ODDrives Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="" ) @@ -277,7 +298,7 @@ function Get-ODSharedItems Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="" ) @@ -377,7 +398,7 @@ function Get-ODItemProperty Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [string]$ResourceId="", [string]$Path="/", @@ -416,7 +437,7 @@ function Get-ODChildItems Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$Path="/", @@ -430,6 +451,7 @@ function Get-ODChildItems [parameter(DontShow)] [switch]$Loop=$false ) + $ODRootURI=Get-ODRootUri -ResourceId $ResourceId if ($Path.Contains('$skiptoken=') -or $Loop) { @@ -517,10 +539,10 @@ function Search-ODItems Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$true,Position=0)] [string]$SearchText, [string]$Path="/", [string]$ElementId="", @@ -554,7 +576,7 @@ function New-ODFolder Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [Parameter(Mandatory=$True)] @@ -590,7 +612,7 @@ function Remove-ODItem Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$Path="", @@ -634,7 +656,7 @@ function Get-ODItem Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$Path="", @@ -649,6 +671,7 @@ function Get-ODItem } else { + $Download=Get-ODItemProperty -AccessToken $AccessToken -ResourceId $ResourceId -Path $Path -ElementId $ElementId -DriveId $DriveId -SelectProperties "name,@content.downloadUrl,lastModifiedDateTime" if ($LocalPath -eq "") {$LocalPath=Get-Location} $LocalPath=resolve-Path ($LocalPath.TrimEnd("\")+"\") @@ -701,7 +724,7 @@ function Add-ODItem Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$Path="/", @@ -711,6 +734,16 @@ function Add-ODItem [string]$LocalFile="" ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId +do{ +$doCount++ +if($doCount -ne 1){ +if ($Authentication -ne $null ) { +$null=Get-ODAuthentication -ClientId $Authentication.ClientId -enableglobal +if(-not($?)){break} +} +else{$null=Get-ODAuthentication -enableglobal +if(-not($?)){break}}} +if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { $spacer="" @@ -718,12 +751,14 @@ function Add-ODItem $ODRootURI=Get-ODRootUri -ResourceId $ResourceId $rURI=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/content").Replace("/root/","/root:/") return $webRequest=Invoke-WebRequest -Method PUT -InFile $LocalFile -Uri $rURI -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "multipart/form-data" -UseBasicParsing -ErrorAction SilentlyContinue + $errorcode=$? } catch { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) return -1 } +}until($errorcode -or $doCount -ne 1) } function Add-ODItemLarge { <# @@ -750,7 +785,7 @@ function Add-ODItemLarge { #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$Path="/", @@ -759,8 +794,18 @@ function Add-ODItemLarge { [Parameter(Mandatory=$True)] [string]$LocalFile="" ) - + $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId +do{ +$doCount++ +if($doCount -ne 1){ +if ($Authentication -ne $null ) { +$null=Get-ODAuthentication -ClientId $Authentication.ClientId -enableglobal +if(-not($?)){break} +} +else{$null=Get-ODAuthentication -enableglobal +if(-not($?)){break}}} +if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Try { # Begin to construct the real (full) URI $spacer="" @@ -772,6 +817,7 @@ function Add-ODItemLarge { # Initialize upload session $webRequest=Invoke-WebRequest -Method PUT -Uri $rURI -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -UseBasicParsing -ErrorAction SilentlyContinue + $errorcode=$? # Parse the response JSON (into a holder variable) $convertResponse = ($webRequest.Content | ConvertFrom-Json) @@ -851,6 +897,7 @@ function Add-ODItemLarge { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) return -1 } +}until($errorcode -or $doCount -ne 1) } function Move-ODItem { @@ -882,7 +929,7 @@ function Move-ODItem Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", [string]$Path="", @@ -922,4 +969,4 @@ function Move-ODItem return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method PATCH -rURI $rURI -Body $body } } -} +} \ No newline at end of file From a924ac9d22dbd6f5349b7d2311bbae6d8e5faf4c Mon Sep 17 00:00:00 2001 From: he852100 Date: Tue, 21 Jan 2020 16:34:38 +0800 Subject: [PATCH 03/18] add global Variable --- Sources/OneDrive.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index ec9921a..5657915 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -68,8 +68,8 @@ function Get-ODAuthentication } else { write-debug("Authentication mode: " +$Type) - $ErrorActionPreference="SilentlyContinue" - if([Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") ){$Verify} + [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null + $Verify= -not($?) [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null [Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null if ($Logout) @@ -110,7 +110,7 @@ function Get-ODAuthentication $web.Add_DocumentCompleted($DocComplete) $form.Controls.Add($web) } - if ($DontShowLoginScreen) + if ($DontShowLoginScreen -or $Verify) { write-debug("Logon screen suppressed by flag -DontShowLoginScreen") $form.Opacity = 0.0; From 9bb493949562f41c8cc591c89dc049ec0392f4ee Mon Sep 17 00:00:00 2001 From: he852100 Date: Tue, 21 Jan 2020 19:38:53 +0800 Subject: [PATCH 04/18] xx --- Sources/OneDrive.psm1 | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 5657915..48bdb0a 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -68,8 +68,9 @@ function Get-ODAuthentication } else { write-debug("Authentication mode: " +$Type) - [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | out-null - $Verify= -not($?) + $ErrorActionPreference="SilentlyContinue" + $null=[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") + $Verify= $? [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null [Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null if ($Logout) @@ -109,13 +110,23 @@ function Get-ODAuthentication } $web.Add_DocumentCompleted($DocComplete) $form.Controls.Add($web) - } - if ($DontShowLoginScreen -or $Verify) + if ($DontShowLoginScreen -or -not($Verify)) { write-debug("Logon screen suppressed by flag -DontShowLoginScreen") $form.Opacity = 0.0; } $form.showdialog() | out-null + }else{ + @("A refresh token is given. Try to refresh it in code mode.",$URIGetAccessToken)|out-host + $regex= 'access_token=[^&]+' + do { + $key=read-host -prompt 'URL' + if (-not($key -match $regex)){write-host 'ERROR' -ForegroundColor DarkCyan|out-host} + }until($key -match $regex) + $Global:ODAccessToken=($key|select-string -pattern '(?<=token=)[^&]+' ).matches.value + $Global:odtokentime=get-date + $web=[PSobject]@{Url=$key} + } # Build object from last URI (which should contains the token) $ReturnURI=($web.Url).ToString().Replace("#","&") if ($LogOut) {return "Logout"} @@ -225,14 +236,14 @@ if(-not($?)){break}}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { $webRequest=Invoke-WebRequest -Method $Method -Uri ($ODRootURI+$rURI) -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $xBody -UseBasicParsing -ErrorAction SilentlyContinue - $errorcode=$? } catch { write-error("Cannot access the api. Webrequest return code is: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) - break } + $errorcode=$? }until($errorcode -or $doCount -ne 1) +if (-not($errorcode)){break} switch ($webRequest.StatusCode) { 200 @@ -749,15 +760,15 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} $spacer="" if ($ElementId -ne "") {$spacer=":"} $ODRootURI=Get-ODRootUri -ResourceId $ResourceId - $rURI=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/content").Replace("/root/","/root:/") - return $webRequest=Invoke-WebRequest -Method PUT -InFile $LocalFile -Uri $rURI -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "multipart/form-data" -UseBasicParsing -ErrorAction SilentlyContinue - $errorcode=$? + $ruri1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/content").Replace("/root/","/root:/") + return $webRequest=Invoke-WebRequest -Method PUT -InFile $LocalFile -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "multipart/form-data" -UseBasicParsing -ErrorAction SilentlyContinue|%{$_.content}|convertfrom-json } catch { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) - return -1 + #return -1 } + $errorcode=$? }until($errorcode -or $doCount -ne 1) } function Add-ODItemLarge { @@ -813,11 +824,10 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} $ODRootURI=Get-ODRootUri -ResourceId $ResourceId # Construct the real (full) URI - $rURI=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/createUploadSession").Replace("/root/","/root:/") + $rURI1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/createUploadSession").Replace("/root/","/root:/") # Initialize upload session - $webRequest=Invoke-WebRequest -Method PUT -Uri $rURI -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -UseBasicParsing -ErrorAction SilentlyContinue - $errorcode=$? + $webRequest=Invoke-WebRequest -Method PUT -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -UseBasicParsing -ErrorAction SilentlyContinue # Parse the response JSON (into a holder variable) $convertResponse = ($webRequest.Content | ConvertFrom-Json) @@ -895,8 +905,9 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} } Catch { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) - return -1 - } + #return -1 + } + $errorcode=$? }until($errorcode -or $doCount -ne 1) } function Move-ODItem From cda9fd52561b00805a578ad0b3370ef6edf8e0ee Mon Sep 17 00:00:00 2001 From: he852100 Date: Tue, 21 Jan 2020 23:44:56 +0800 Subject: [PATCH 05/18] xx --- Sources/OneDrive.psm1 | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 48bdb0a..aeefbff 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -165,6 +165,9 @@ function Get-ODAuthentication write-warning("There is maybe an errror, because there is no access_token!") } $Authentication | add-member Noteproperty "ClientId" ($ClientId) + if ($ResourceId){ + $Authentication | add-member Noteproperty "ResourceId" ($ResourceId) + } if($enableglobal){ $Global:Authentication=$Authentication } @@ -224,15 +227,15 @@ function Get-ODWebContent } $ODRootURI=Get-ODRootUri -ResourceId $ResourceId + $string=@() + $string=@{ enableglobal=$true} + if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} do{ $doCount++ if($doCount -ne 1){ -if ($Authentication -ne $null ) { -$null=Get-ODAuthentication -ClientId $Authentication.ClientId -enableglobal -if(-not($?)){break} -} -else{$null=Get-ODAuthentication -enableglobal -if(-not($?)){break}}} +$null=Get-ODAuthentication @string +if(-not($?)){break}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { $webRequest=Invoke-WebRequest -Method $Method -Uri ($ODRootURI+$rURI) -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $xBody -UseBasicParsing -ErrorAction SilentlyContinue @@ -745,15 +748,15 @@ function Add-ODItem [string]$LocalFile="" ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId + $string=@() + $string=@{ enableglobal=$true} + if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} do{ $doCount++ if($doCount -ne 1){ -if ($Authentication -ne $null ) { -$null=Get-ODAuthentication -ClientId $Authentication.ClientId -enableglobal -if(-not($?)){break} -} -else{$null=Get-ODAuthentication -enableglobal -if(-not($?)){break}}} +$null=Get-ODAuthentication @string +if(-not($?)){break}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { @@ -807,15 +810,15 @@ function Add-ODItemLarge { ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId + $string=@() + $string=@{ enableglobal=$true} + if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} do{ $doCount++ if($doCount -ne 1){ -if ($Authentication -ne $null ) { -$null=Get-ODAuthentication -ClientId $Authentication.ClientId -enableglobal -if(-not($?)){break} -} -else{$null=Get-ODAuthentication -enableglobal -if(-not($?)){break}}} +$null=Get-ODAuthentication @string +if(-not($?)){break}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Try { # Begin to construct the real (full) URI From 15a4212e107ab330203df730b4d17fb5326db1d5 Mon Sep 17 00:00:00 2001 From: he852100 Date: Wed, 22 Jan 2020 01:06:30 +0800 Subject: [PATCH 06/18] add get-odsharelinkdownload --- Sources/OneDrive.psm1 | 140 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index aeefbff..8877eb3 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -983,4 +983,142 @@ function Move-ODItem return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method PATCH -rURI $rURI -Body $body } } -} \ No newline at end of file +} +function get-odsharelinkdownload + <# + .DESCRIPTION + Download a shared file + .PARAMETER URL + onedrive Share links + .PARAMETER path + Mandatory for OneDrive 4 Business access. Is the ressource URI: "https://-my.sharepoint.com/". Example: "https://sepagogmbh-my.sharepoint.com/" + .EXAMPLE + Get-ODDrives -URL https://1drv.ms/f/s!AtftJLuuzIqngqg598UpNi1x5YJ8bQ + Download a file + Get-ODDrives -URL xxx -path \d\d\ + .NOTES + Avoid downloading large files + The application for OneDrive 4 Business needs "Read items in all site collections" on application level (API: Office 365 SharePoint Online) + Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer + #> + {PAram( + [Parameter(Mandatory=$true,Position=0)] + [string]$uri, + [Parameter(Mandatory=$true,Position=1)] + [string]$path) + if(-not(Test-Path $path)){break;write-host 'error path'} + if($path -match '[^/]$'){ + $path= (resolve-path -path $path).path+"/"} +$ProgressPreference= "SilentlyContinue" +function Runspace0{ +param($ScriptBlock) +$throttleLimit = 8 +$SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault() +$Pool = [runspacefactory]::CreateRunspacePool(1, $throttleLimit, $SessionState, $Host) +$Pool.Open() +if ($ScriptBlock -is [string]){[array]$ScriptBlock=$ScriptBlock} +$threads = @() +$handles = for ($x = 0; $x -lt $ScriptBlock.length; $x++) { +$fg=$ScriptBlock[$x] +$scriptblock1=@" +param(`$id) +`$ErrorActionPreference='SilentlyContinue'; +`$WarningPreference='SilentlyContinue'; +`$ProgressPreference='SilentlyContinue'; +`$code=($fg) +[PScustomobject]@{id=`$id;code=`$code} +"@ + $powershell = [powershell]::Create().AddScript($scriptblock1).AddArgument($x) + $powershell.RunspacePool = $Pool + $powershell.BeginInvoke() + $threads += $powershell} +if ($handles -is [string]){[array]$handles=$handles} +$ss=@() +do { +$done = $true +# ($handles -ne $null).length +for ($x=0;$X -lt $handles.length;$x++){ +$bi=$handles[$x].IsCompleted -like 'true' +if ($bi){ +$ss=$ss += $threads[$x].EndInvoke($handles[$x]) +$threads[$x].Dispose() +$handles[$x]=$null +$threads[$x]=$null}} +if ($handles.IsCompleted -ne $null){$done = $false} +if (-not $done) { Start-Sleep -Milliseconds 900 } +} until ($done) +($ss |sort-object -Property id).code} +function Folder-downloads { +PAram([string]$URL,[string]$path='./') +[array]$URL=$URL +$path=(resolve-path -path $path).path +$data=@() +[array]$path1=$path +$yuan='https://storage.live.com/items/' +$folderID=@() +do { +if ($folderID[0] -ne $null -and $folderID[0] -ne $replace){ +[string]$replace=$folderID[0] +$url=@() +[array]$folder=$path1|select-object -Skip $folder.length +$path1=@() +for ($i=0;$i -lt $folder.length;$i++) { +for ($x=0;$X -lt $folderName.length;$x++) { +$path1+=$folder[$i]+$folderName[$x]+'/' +$itempath=$folder[$i]+$folderName[$x]+"/" +$null=New-Item -path "$itempath" -itemtype Directory -force +#$folder[$i] -Name $folderName[$x]}} +$folderID|%{$url+="$yuan$_$key"} +Remove-variable folderName,folderID -force} +for ($x=0;$x -lt $URL.length;$x++){ +$xml=irm $URL[$x] +$dd= [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::GetEncoding(28591).GetBytes($xml)) +$key='?'+ ($URL[$x] |select-string -pattern 'authkey.*$').matches.value +$dd=$([XML]$($dd -replace '^[^<]+')).Folder.Items +[array]$ResourceID=$dd.Document.ResourceID +[array]$RelationshipName=$dd.Document.RelationshipName +for ($i=0;$I -lt $ResourceID.length;$i++){ +$data+=[PScustomobject]@{ +ResourceID=$ResourceID[$i] +RelationshipName=$RelationshipName[$i] +path= $path1[$x]+$RelationshipName[$i] +url=($yuan+$ResourceID[$i]+$key)}} +[array]$folderID=$dd.folder.ResourceID +[array]$folderName=$dd.folder.RelationshipName +#if ($folderID -eq $null){break}} +} until ($folderID -eq $null) +$script=@() +For ( $x=0; $x -lt $data.length;$x++){ +$path=$data.path[$x] +$URL=$data.url[$x] +$script+="iwr '$URL' -o '$path'"} +if ($script -is [array] -and $script.length -gt 5){ +runspace0 $script +}elseif($script -is [string]){iex $script}else{ +for ($x=0;$x -lt $script.length;$x++){ +iex $script[$x]}} +write-host "文件数量:"$ResourceID.count -ForegroundColor Blue|out-host +$data} + +if ($uri -notmatch 'onedrive|skydrive|storage'){ + $link=iwr $uri -MaximumRedirection 0 -SkipHttpErrorCheck -ErrorAction Ignore + $link=$link.headers.location +}else{$link=$uri} +if ($link -match 'ithint\=folder'){ + $link= $link -replace '^(.*?)(?:onedrive|skydrive)(\..*)?(?:redir|download)\?resid\=(.*?\d)(\&a.*)$','$1storage$2items/$3?$4' + [PScustomobject]@{链接地址=$link}|format-table -wrap + Folder-downloads -URL $link -path $path +}else{ + #$link -replace '^(.*?)(?:onedrive|skydrive)(\..*)?(?:redir|download)(.*)$','$1skydrive$2download$3'|out-host + #$link -replace '^(.*?)(?:onedrive|skydrive)(\..*)?(?:redir|download)\?resid\=(.*?\d)(\&a.*)$','$1storage$2items/$3?$4'|out-host + $link= $link -replace '^(.*?)(?:onedrive|skydrive)(\..*)?(?:redir|download)(.*)$','$1skydrive$2download$3' + #$link=iwr $uri -MaximumRedirection 0 -SkipHttpErrorCheck -ErrorAction Ignore + [PScustomobject]@{链接地址=$link}|format-table -wrap + $data=iwr "$link" + $replace=$data.headers.'Content-Disposition' -replace '^.*?(?=[^ ''"]+$)' + $name=[System.Web.HttpUtility]::UrlDecode($replace) + set-content -value $data -path "$path$name" + [PScustomobject]@{ + name=$name + path=$path + URL=$link}}} \ No newline at end of file From c3f1ca23b823c3d3760921dd32c93583aeb31442 Mon Sep 17 00:00:00 2001 From: he852100 Date: Wed, 22 Jan 2020 02:26:24 +0800 Subject: [PATCH 07/18] fix --- Sources/OneDrive.psm1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 8877eb3..3096b1f 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -1066,8 +1066,7 @@ for ($i=0;$i -lt $folder.length;$i++) { for ($x=0;$X -lt $folderName.length;$x++) { $path1+=$folder[$i]+$folderName[$x]+'/' $itempath=$folder[$i]+$folderName[$x]+"/" -$null=New-Item -path "$itempath" -itemtype Directory -force -#$folder[$i] -Name $folderName[$x]}} +$null=New-Item -path "$itempath" -itemtype Directory -force}} $folderID|%{$url+="$yuan$_$key"} Remove-variable folderName,folderID -force} for ($x=0;$x -lt $URL.length;$x++){ @@ -1084,8 +1083,7 @@ RelationshipName=$RelationshipName[$i] path= $path1[$x]+$RelationshipName[$i] url=($yuan+$ResourceID[$i]+$key)}} [array]$folderID=$dd.folder.ResourceID -[array]$folderName=$dd.folder.RelationshipName -#if ($folderID -eq $null){break}} +[array]$folderName=$dd.folder.RelationshipName} } until ($folderID -eq $null) $script=@() For ( $x=0; $x -lt $data.length;$x++){ From 57921f78dcda8ead9eceb2df6357c006189271d8 Mon Sep 17 00:00:00 2001 From: he852100 Date: Wed, 22 Jan 2020 21:49:50 +0800 Subject: [PATCH 08/18] n --- Sources/OneDrive.psm1 | 110 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 12 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 3096b1f..6539e6c 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -1,3 +1,26 @@ +function jwt-decode { +PAram([Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$data) +if (-not($data)){Write-Error "没有输入值,例如:JWTxxxxxxxx.....";break;} +[array]$data=$data -split '\.' +function frombase64 { +param([Parameter(Position = 0, ValueFromPipeline = $True)] +[string]$a) +$c=$a.Length +if((4 -lt $c) -and(0 -ne $c%4)){$b=4-$c%4}elseif($c -lt 4){$b=4-$c}else{$b=0} +[System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($a+("="*$b))) +} +$base=@() +for($i=0;$I -lt ($data.length -1);$i++){ +frombase64 $data[$i]|convertfrom-json +} +} + +function timestamp-to-date { +PAram([int64]$data) +if (-not($data)){Write-Error "没有输入值,例如 :15868847";break;} +(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($data)) +} + function Get-ODAuthentication { <# @@ -171,6 +194,16 @@ function Get-ODAuthentication if($enableglobal){ $Global:Authentication=$Authentication } +<# +$URL=$Key -replace '[^#]+#' -split '&' -replace '^[^=]+$' -split '=' +$format=@() +for(($i=0),($j=1);$I -lt $URL.length;($i+=2),($j+=2)){ +$format+=@{$URL[$i]=$URL[$j]}} +$access_token=jwt-decode $format.access_token +$global:authen=jwt-decode $format.authentication_token +#timestamp-to-date $access_token.exp[1] +$global:authentication_token=timestamp-to-date $authen.exp[1] +#> return $Authentication } function Get-ODRootUri @@ -231,10 +264,17 @@ function Get-ODWebContent $string=@{ enableglobal=$true} if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} + if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ + [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} + } + if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ + [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} + } do{ $doCount++ if($doCount -ne 1){ $null=Get-ODAuthentication @string +$AccessToken=$null if(-not($?)){break}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { @@ -244,8 +284,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} { write-error("Cannot access the api. Webrequest return code is: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) } - $errorcode=$? -}until($errorcode -or $doCount -ne 1) +}until($? -or $doCount -ne 1) if (-not($errorcode)){break} switch ($webRequest.StatusCode) { @@ -291,6 +330,7 @@ function Get-ODDrives [string]$AccessToken, [String]$ResourceId="" ) + $ProgressPreference="SilentlyContinue" $ResponseObject=Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method GET -rURI "/drives" return $ResponseObject.Value } @@ -316,6 +356,7 @@ function Get-ODSharedItems [string]$AccessToken, [String]$ResourceId="" ) + $ProgressPreference="SilentlyContinue" $ResponseObject=Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method GET -rURI "/drive/oneDrive.sharedWithMe" return $ResponseObject.Value } @@ -420,6 +461,7 @@ function Get-ODItemProperty [string]$SelectProperties="name,size,lastModifiedDateTime,id", [string]$DriveId="" ) + $ProgressPreference="SilentlyContinue" return Get-ODChildItems -AccessToken $AccessToken -ResourceId $ResourceId -Path $Path -ElementId $ElementId -SelectProperties $SelectProperties -DriveId $DriveId -ItemPropertyMode } @@ -455,6 +497,7 @@ function Get-ODChildItems [string]$AccessToken, [String]$ResourceId="", [string]$Path="/", + [Parameter(HelpMessage="input folder id")] [string]$ElementId="", [string]$SelectProperties="name,size,lastModifiedDateTime,id", [string]$DriveId="", @@ -465,7 +508,7 @@ function Get-ODChildItems [parameter(DontShow)] [switch]$Loop=$false ) - + $ProgressPreference="SilentlyContinue" $ODRootURI=Get-ODRootUri -ResourceId $ResourceId if ($Path.Contains('$skiptoken=') -or $Loop) { @@ -548,6 +591,12 @@ function Search-ODItems Specifies the OneDrive drive id. If not set, the default drive is used. .EXAMPLE Search-ODItems -AccessToken $AuthToken -Path "/My pictures" -SearchText "FolderA" + Search-ODItems + Search-ODItems + Search-ODItems + Search-ODItems f -selectproperties 'name,id' + Search-ODItems 'mm' -path '/powershell' + Search-ODItems 'mm' -path '/powershell' -AccessToken $AuthToken Searches for items in a sub folder recursively. Take a look at OneDrives API documentation to see how search (preview) works (file and folder names, in files, …) .NOTES Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer @@ -556,14 +605,20 @@ function Search-ODItems [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", - [Parameter(Mandatory=$true,Position=0)] + [Parameter(Mandatory=$false,Position=0)] [string]$SearchText, + [Parameter(Mandatory=$false,Position=3)] [string]$Path="/", + [Parameter(Mandatory=$false,Position=1)] [string]$ElementId="", + [Parameter(Mandatory=$false,Position=2)] [string]$SelectProperties="name,size,lastModifiedDateTime,id", + [Parameter(Mandatory=$false)] [string]$DriveId="" ) - return Get-ODChildItems -AccessToken $AccessToken -ResourceId $ResourceId -Path $Path -ElementId $ElementId -SelectProperties $SelectProperties -DriveId $DriveId -SearchText $SearchText + $ProgressPreference="SilentlyContinue" + if(!($SearchText)-and!($ElementId)){"请输入一个值:SearchText or ElementId";break} + return Get-ODChildItems -AccessToken $AccessToken -ResourceId $ResourceId -Path $Path -ElementId $ElementId -SelectProperties $SelectProperties -DriveId $DriveId -SearchText $SearchText } function New-ODFolder @@ -595,10 +650,13 @@ function New-ODFolder [String]$ResourceId="", [Parameter(Mandatory=$True)] [string]$FolderName, + [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="/", + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="" ) + $ProgressPreference="SilentlyContinue" $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId $rURI=$rURI+"/children" return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method POST -rURI $rURI -Body ('{"name": "'+$FolderName+'","folder": { },"@name.conflictBehavior": "fail"}') @@ -629,10 +687,13 @@ function Remove-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", + [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="", + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="" ) + $ProgressPreference="SilentlyContinue" if (($ElementId+$Path) -eq "") { write-error("Path nor ElementId is set") @@ -673,7 +734,9 @@ function Get-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", + [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="", + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="", [string]$LocalPath="", @@ -741,10 +804,13 @@ function Add-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", + [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="/", + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="", - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$true,ParameterSetName="path")] + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$LocalFile="" ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId @@ -752,10 +818,17 @@ function Add-ODItem $string=@{ enableglobal=$true} if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} + if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ + [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} + } + if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ + [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} + } do{ $doCount++ if($doCount -ne 1){ $null=Get-ODAuthentication @string +$AccessToken=$null if(-not($?)){break}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try @@ -771,8 +844,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 } - $errorcode=$? -}until($errorcode -or $doCount -ne 1) +}until($? -or $doCount -ne 1) } function Add-ODItemLarge { <# @@ -802,10 +874,13 @@ function Add-ODItemLarge { [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", + [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="/", + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="", - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$true,ParameterSetName="path")] + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$LocalFile="" ) @@ -814,10 +889,17 @@ function Add-ODItemLarge { $string=@{ enableglobal=$true} if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} + if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ + [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} + } + if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ + [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} + } do{ $doCount++ if($doCount -ne 1){ $null=Get-ODAuthentication @string +$AccessToken=$null if(-not($?)){break}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Try { @@ -910,8 +992,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 } - $errorcode=$? -}until($errorcode -or $doCount -ne 1) +}until($? -or $doCount -ne 1) } function Move-ODItem { @@ -946,12 +1027,15 @@ function Move-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", + [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="", + [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="", [string]$TargetPath="", [string]$NewName="" ) + $ProgressPreference="SilentlyContinue" if (($ElementId+$Path) -eq "") { write-error("Path nor ElementId is set") @@ -991,7 +1075,7 @@ function get-odsharelinkdownload .PARAMETER URL onedrive Share links .PARAMETER path - Mandatory for OneDrive 4 Business access. Is the ressource URI: "https://-my.sharepoint.com/". Example: "https://sepagogmbh-my.sharepoint.com/" + .EXAMPLE Get-ODDrives -URL https://1drv.ms/f/s!AtftJLuuzIqngqg598UpNi1x5YJ8bQ Download a file @@ -1010,6 +1094,7 @@ function get-odsharelinkdownload if($path -match '[^/]$'){ $path= (resolve-path -path $path).path+"/"} $ProgressPreference= "SilentlyContinue" + function Runspace0{ param($ScriptBlock) $throttleLimit = 8 @@ -1048,6 +1133,7 @@ if ($handles.IsCompleted -ne $null){$done = $false} if (-not $done) { Start-Sleep -Milliseconds 900 } } until ($done) ($ss |sort-object -Property id).code} + function Folder-downloads { PAram([string]$URL,[string]$path='./') [array]$URL=$URL From ccfb62cf6534562151150a675ba51bf8e48be5a9 Mon Sep 17 00:00:00 2001 From: he852100 Date: Thu, 23 Jan 2020 00:14:45 +0000 Subject: [PATCH 09/18] n --- Sources/OneDrive.psm1 | 58 +++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 6539e6c..da33ec4 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -7,19 +7,11 @@ param([Parameter(Position = 0, ValueFromPipeline = $True)] [string]$a) $c=$a.Length if((4 -lt $c) -and(0 -ne $c%4)){$b=4-$c%4}elseif($c -lt 4){$b=4-$c}else{$b=0} -[System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($a+("="*$b))) -} +[System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($a+("="*$b)))} $base=@() for($i=0;$I -lt ($data.length -1);$i++){ -frombase64 $data[$i]|convertfrom-json -} -} +frombase64 $data[$i]|convertfrom-json}} -function timestamp-to-date { -PAram([int64]$data) -if (-not($data)){Write-Error "没有输入值,例如 :15868847";break;} -(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($data)) -} function Get-ODAuthentication { @@ -201,8 +193,8 @@ for(($i=0),($j=1);$I -lt $URL.length;($i+=2),($j+=2)){ $format+=@{$URL[$i]=$URL[$j]}} $access_token=jwt-decode $format.access_token $global:authen=jwt-decode $format.authentication_token -#timestamp-to-date $access_token.exp[1] -$global:authentication_token=timestamp-to-date $authen.exp[1] +$global:authentication_token= +(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($authen.exp[1])) #> return $Authentication } @@ -262,30 +254,32 @@ function Get-ODWebContent $ODRootURI=Get-ODRootUri -ResourceId $ResourceId $string=@() $string=@{ enableglobal=$true} - if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} + if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string=@{ResourceId=$ResourceId}} if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} } if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} + $Global:Authentication.ResourceId=$ResourceId } +$code=@('Access token is empty.','Authentication failed','Unauthorized') do{ $doCount++ if($doCount -ne 1){ $null=Get-ODAuthentication @string -$AccessToken=$null -if(-not($?)){break}} +if(-not($?)){break} +if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { - $webRequest=Invoke-WebRequest -Method $Method -Uri ($ODRootURI+$rURI) -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $xBody -UseBasicParsing -ErrorAction SilentlyContinue + $webRequest=Invoke-WebRequest -Method $Method -Uri ($ODRootURI+$rURI) -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $xBody -UseBasicParsing } catch { - write-error("Cannot access the api. Webrequest return code is: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) + #write-error("Cannot access the api. Webrequest return code is: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) + $mess=$_.Exception + $err=($_.ErrorDetails.message|ConvertFrom-Json).error } -}until($? -or $doCount -ne 1) -if (-not($errorcode)){break} +}until($code -notcontains $mess.Response.StatusCode -or $code -notcontains $err.message -or $doCount -ne 1) switch ($webRequest.StatusCode) { 200 @@ -816,7 +810,7 @@ function Add-ODItem $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId $string=@() $string=@{ enableglobal=$true} - if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} + if($Authentication.ClientId -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} @@ -824,12 +818,13 @@ function Add-ODItem if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} } +$code=@('Access token is empty.','Authentication failed','Unauthorized') do{ $doCount++ if($doCount -ne 1){ $null=Get-ODAuthentication @string -$AccessToken=$null -if(-not($?)){break}} +if(-not($?)){break} +if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { @@ -843,8 +838,9 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 - } -}until($? -or $doCount -ne 1) + $mess=$_.Exception.Response.StatusCode + } +}until($code -notcontains $mess -or $doCount -ne 1) } function Add-ODItemLarge { <# @@ -887,7 +883,7 @@ function Add-ODItemLarge { $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId $string=@() $string=@{ enableglobal=$true} - if($Authentication -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} + if($Authentication.ClientId -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} @@ -895,12 +891,13 @@ function Add-ODItemLarge { if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} } +$code=@('Access token is empty.','Authentication failed','Unauthorized') do{ $doCount++ if($doCount -ne 1){ $null=Get-ODAuthentication @string -$AccessToken=$null -if(-not($?)){break}} +if(-not($?)){break} +if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Try { # Begin to construct the real (full) URI @@ -991,8 +988,9 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Catch { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 + $mess=$_.Exception.Response.StatusCode } -}until($? -or $doCount -ne 1) +}until($code -notcontains $mess -or $doCount -ne 1) } function Move-ODItem { From 5a051cdd936e7dd3a056d4d73b50c4f7bcb165ef Mon Sep 17 00:00:00 2001 From: he852100 Date: Thu, 23 Jan 2020 08:20:53 +0000 Subject: [PATCH 10/18] commit --- Sources/OneDrive.psm1 | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index da33ec4..451ed6d 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -136,7 +136,7 @@ function Get-ODAuthentication $regex= 'access_token=[^&]+' do { $key=read-host -prompt 'URL' - if (-not($key -match $regex)){write-host 'ERROR' -ForegroundColor DarkCyan|out-host} + if (-not($key -match $regex)){write-host '`rERROR' -ForegroundColor DarkCyan|out-host} }until($key -match $regex) $Global:ODAccessToken=($key|select-string -pattern '(?<=token=)[^&]+' ).matches.value $Global:odtokentime=get-date @@ -262,10 +262,9 @@ function Get-ODWebContent if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ $Global:Authentication.ResourceId=$ResourceId } -$code=@('Access token is empty.','Authentication failed','Unauthorized') +$code=@('WWW-Authenticate') do{ -$doCount++ -if($doCount -ne 1){ +if($mess){ $null=Get-ODAuthentication @string if(-not($?)){break} if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} @@ -275,11 +274,11 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} } catch { - #write-error("Cannot access the api. Webrequest return code is: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) - $mess=$_.Exception - $err=($_.ErrorDetails.message|ConvertFrom-Json).error + $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} + if($mess){$mess.value -replace '(^[^=]+?)(=)','"$1":' ` + -replace ', *([^ =]+?)(=)',',"$1":' -replace '^','{' -replace '$','}'|ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} } -}until($code -notcontains $mess.Response.StatusCode -or $code -notcontains $err.message -or $doCount -ne 1) +}until($code -notcontains $mess.key) switch ($webRequest.StatusCode) { 200 @@ -299,7 +298,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} $responseObject = "0" return $responseObject } - default {write-warning("Cannot access the api. Webrequest return code is: "+$webRequest.StatusCode+"`n"+$webRequest.StatusDescription)} + #default {write-warning("Cannot access the api. Webrequest return code is: "+$webRequest.StatusCode+"`n"+$webRequest.StatusDescription)} } } @@ -818,10 +817,9 @@ function Add-ODItem if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} } -$code=@('Access token is empty.','Authentication failed','Unauthorized') +$code=@('WWW-Authenticate') do{ -$doCount++ -if($doCount -ne 1){ +if($mess){ $null=Get-ODAuthentication @string if(-not($?)){break} if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} @@ -838,9 +836,11 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 - $mess=$_.Exception.Response.StatusCode + $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} + if($mess){$mess.value -replace '(^[^=]+?)(=)','"$1":' ` + -replace ', *([^ =]+?)(=)',',"$1":' -replace '^','{' -replace '$','}'|ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} } -}until($code -notcontains $mess -or $doCount -ne 1) +}until($code -notcontains $mess.key) } function Add-ODItemLarge { <# @@ -891,10 +891,9 @@ function Add-ODItemLarge { if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} } -$code=@('Access token is empty.','Authentication failed','Unauthorized') +$code=@('WWW-Authenticate') do{ -$doCount++ -if($doCount -ne 1){ +if($mess){ $null=Get-ODAuthentication @string if(-not($?)){break} if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} @@ -988,9 +987,11 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Catch { write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 - $mess=$_.Exception.Response.StatusCode + $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} + if($mess){$mess.value -replace '(^[^=]+?)(=)','"$1":' ` + -replace ', *([^ =]+?)(=)',',"$1":' -replace '^','{' -replace '$','}'|ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} } -}until($code -notcontains $mess -or $doCount -ne 1) +}until($code -notcontains $mess.key) } function Move-ODItem { From fd3e015ee09445daf94a2cb8ad4bc95b2f63b4a5 Mon Sep 17 00:00:00 2001 From: he852100 Date: Thu, 23 Jan 2020 09:35:02 +0000 Subject: [PATCH 11/18] commit --- Sources/OneDrive.psm1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 451ed6d..86f41e9 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -267,6 +267,7 @@ do{ if($mess){ $null=Get-ODAuthentication @string if(-not($?)){break} +remove-variable mess -force if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { @@ -822,6 +823,7 @@ do{ if($mess){ $null=Get-ODAuthentication @string if(-not($?)){break} +remove-variable mess -force if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try @@ -896,6 +898,7 @@ do{ if($mess){ $null=Get-ODAuthentication @string if(-not($?)){break} +remove-variable mess -force if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Try { From d9abb85f0bb30d0b1c40d02403ab505573b40108 Mon Sep 17 00:00:00 2001 From: he852100 Date: Thu, 23 Jan 2020 17:45:42 +0000 Subject: [PATCH 12/18] commit --- Sources/OneDrive.psm1 | 88 +++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 33 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 86f41e9..bd53fae 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -57,6 +57,7 @@ function Get-ODAuthentication [switch]$LogOut, [switch]$enableglobal ) + if($ClientId -cnotmatch '^([a-f0-9]{3,}-){3,}[a-f0-9]{3,}$'){write-error 'ClientId error';break} $optResourceId="" $optOauthVersion="/v2.0" if ($ResourceId -ne "") @@ -252,22 +253,28 @@ function Get-ODWebContent } $ODRootURI=Get-ODRootUri -ResourceId $ResourceId - $string=@() + function splash{$string=@() $string=@{ enableglobal=$true} - if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string=@{ResourceId=$ResourceId}} + if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}} + $string} + $string= splash + if (!($Authentication)){$Global:Authentication = New-Object PSObject} if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ - [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} - } + switch ($Authentication.ResourceId -eq $null) { + true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} + false {$Authentication.access_token=$AccessToken}}} if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - $Global:Authentication.ResourceId=$ResourceId - } -$code=@('WWW-Authenticate') + switch ($Authentication.ResourceId -eq $null) { + false {$Authentication.ResourceId=$ResourceId} + true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} + $code=@('WWW-Authenticate') do{ if($mess){ $null=Get-ODAuthentication @string -if(-not($?)){break} +if(!($?)){break} remove-variable mess -force +$string=splash if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try { @@ -276,8 +283,9 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} catch { $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} - if($mess){$mess.value -replace '(^[^=]+?)(=)','"$1":' ` - -replace ', *([^ =]+?)(=)',',"$1":' -replace '^','{' -replace '$','}'|ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} + if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` + -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| + ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} } }until($code -notcontains $mess.key) switch ($webRequest.StatusCode) @@ -808,22 +816,28 @@ function Add-ODItem [string]$LocalFile="" ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId - $string=@() + function splash{$string=@() $string=@{ enableglobal=$true} - if($Authentication.ClientId -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} + if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}} + $string} + $string= splash + if (!($Authentication)){$Global:Authentication = New-Object PSObject} if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ - [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} - } + switch ($Authentication.ResourceId -eq $null) { + true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} + false {$Authentication.access_token=$AccessToken}}} if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} - } -$code=@('WWW-Authenticate') + switch ($Authentication.ResourceId -eq $null) { + false {$Authentication.ResourceId=$ResourceId} + true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} + $code=@('WWW-Authenticate') do{ if($mess){ $null=Get-ODAuthentication @string -if(-not($?)){break} +if(!($?)){break} remove-variable mess -force +$string=splash if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} try @@ -839,8 +853,9 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} - if($mess){$mess.value -replace '(^[^=]+?)(=)','"$1":' ` - -replace ', *([^ =]+?)(=)',',"$1":' -replace '^','{' -replace '$','}'|ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} + if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` + -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| + ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} } }until($code -notcontains $mess.key) } @@ -883,22 +898,28 @@ function Add-ODItemLarge { ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId - $string=@() + function splash{$string=@() $string=@{ enableglobal=$true} - if($Authentication.ClientId -and -not($ResourceId)){$string=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and -not($ResourceId)){$string=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId){$string=@{ResourceId=$ResourceId}} + if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}} + $string} + $string= splash + if (!($Authentication)){$Global:Authentication = New-Object PSObject} if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ - [array]$Global:Authentication+=[PScustomobject]@{access_token=$AccessToken} - } + switch ($Authentication.ResourceId -eq $null) { + true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} + false {$Authentication.access_token=$AccessToken}}} if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - [array]$Global:Authentication+=[PScustomobject]@{ResourceId=$ResourceId} - } -$code=@('WWW-Authenticate') + switch ($Authentication.ResourceId -eq $null) { + false {$Authentication.ResourceId=$ResourceId} + true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} + $code=@('WWW-Authenticate') do{ if($mess){ $null=Get-ODAuthentication @string -if(-not($?)){break} +if(!($?)){break} remove-variable mess -force +$string=splash if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} if (-not($AccessToken)){$AccessToken=$Authentication.access_token} Try { @@ -991,8 +1012,9 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} - if($mess){$mess.value -replace '(^[^=]+?)(=)','"$1":' ` - -replace ', *([^ =]+?)(=)',',"$1":' -replace '^','{' -replace '$','}'|ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} + if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` + -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| + ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} } }until($code -notcontains $mess.key) } From 43efead376aeef5e89bd9bf4814ce3b1a3382537 Mon Sep 17 00:00:00 2001 From: he852100 Date: Fri, 24 Jan 2020 19:15:40 +0000 Subject: [PATCH 13/18] commit --- Sources/OneDrive.psm1 | 47 ++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index bd53fae..fbff943 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -57,7 +57,7 @@ function Get-ODAuthentication [switch]$LogOut, [switch]$enableglobal ) - if($ClientId -cnotmatch '^([a-f0-9]{3,}-){3,}[a-f0-9]{3,}$'){write-error 'ClientId error';break} + if($ClientId -cnotmatch '([a-f0-9]{4,}-?){4,}'){write-host 'ClientId error' -ForegroundColor red;break} $optResourceId="" $optOauthVersion="/v2.0" if ($ResourceId -ne "") @@ -78,7 +78,7 @@ function Get-ODAuthentication { write-debug("A refresh token is given. Try to refresh it in code mode.") $body="client_id=$ClientId&redirect_URI=$RedirectURI&client_secret=$([uri]::EscapeDataString($AppKey))&refresh_token="+$RefreshToken+"&grant_type=refresh_token" - write-host $body + write-debug $body $webRequest=Invoke-WebRequest -Method POST -Uri "https://login.microsoftonline.com/common/oauth2$optOauthVersion/token" -ContentType "application/x-www-form-URLencoded" -Body $Body -UseBasicParsing $Authentication = $webRequest.Content | ConvertFrom-Json } else @@ -87,6 +87,7 @@ function Get-ODAuthentication $ErrorActionPreference="SilentlyContinue" $null=[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") $Verify= $? + $ErrorActionPreference="Continue" [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null [Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null if ($Logout) @@ -134,10 +135,10 @@ function Get-ODAuthentication $form.showdialog() | out-null }else{ @("A refresh token is given. Try to refresh it in code mode.",$URIGetAccessToken)|out-host - $regex= 'access_token=[^&]+' + $regex= 'access_token=[^&]+|\?code=[^&]+' do { $key=read-host -prompt 'URL' - if (-not($key -match $regex)){write-host '`rERROR' -ForegroundColor DarkCyan|out-host} + if (-not($key -match $regex)){write-host "`rERROR" -ForegroundColor DarkCyan|out-host} }until($key -match $regex) $Global:ODAccessToken=($key|select-string -pattern '(?<=token=)[^&]+' ).matches.value $Global:odtokentime=get-date @@ -184,6 +185,9 @@ function Get-ODAuthentication if ($ResourceId){ $Authentication | add-member Noteproperty "ResourceId" ($ResourceId) } + if ($appkey){ + $Authentication | add-member Noteproperty "appkey" ($appkey) + } if($enableglobal){ $Global:Authentication=$Authentication } @@ -255,8 +259,11 @@ function Get-ODWebContent $ODRootURI=Get-ODRootUri -ResourceId $ResourceId function splash{$string=@() $string=@{ enableglobal=$true} - if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}} + if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ + if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} + if($Authentication.refresh_token){$string+=@{RefreshToken=$Authentication.refresh_token}} + if($Authentication.appkey){$string+=@{appkey=$Authentication.appkey}}} $string} $string= splash if (!($Authentication)){$Global:Authentication = New-Object PSObject} @@ -818,8 +825,11 @@ function Add-ODItem $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId function splash{$string=@() $string=@{ enableglobal=$true} - if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}} + if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ + if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} + if($Authentication.refresh_token){$string+=@{RefreshToken=$Authentication.refresh_token}} + if($Authentication.appkey){$string+=@{appkey=$Authentication.appkey}}} $string} $string= splash if (!($Authentication)){$Global:Authentication = New-Object PSObject} @@ -900,8 +910,11 @@ function Add-ODItemLarge { $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId function splash{$string=@() $string=@{ enableglobal=$true} - if($Authentication.ClientId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId -and ($ResourceId -cmatch '.{10,}')){$string+=@{ResourceId=$Authentication.ResourceId}}elseif($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}} + if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ + if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} + if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} + if($Authentication.refresh_token){$string+=@{RefreshToken=$Authentication.refresh_token}} + if($Authentication.appkey){$string+=@{appkey=$Authentication.appkey}}} $string} $string= splash if (!($Authentication)){$Global:Authentication = New-Object PSObject} @@ -1097,14 +1110,16 @@ function get-odsharelinkdownload .DESCRIPTION Download a shared file .PARAMETER URL - onedrive Share links + onedrive.live.com Share links .PARAMETER path .EXAMPLE - Get-ODDrives -URL https://1drv.ms/f/s!AtftJLuuzIqngqg598UpNi1x5YJ8bQ + get-ODShareLinkDownload -URL https://1drv.ms/f/s!AtftJLuuzIqngqg598UpNi1x5YJ8bQ Download a file - Get-ODDrives -URL xxx -path \d\d\ + get-ODShareLinkDownload -URL xxx + get-ODShareLinkDownload -URL xxx -path c:\d\d\ .NOTES + Avoid downloading large files The application for OneDrive 4 Business needs "Read items in all site collections" on application level (API: Office 365 SharePoint Online) Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer @@ -1112,9 +1127,9 @@ function get-odsharelinkdownload {PAram( [Parameter(Mandatory=$true,Position=0)] [string]$uri, - [Parameter(Mandatory=$true,Position=1)] - [string]$path) - if(-not(Test-Path $path)){break;write-host 'error path'} + [Parameter(Mandatory=$false,Position=1)] + [string]$path='./') + if(-not(Test-Path $path)){write-host -ForegroundColor DarkCyan 'Tips:error path';break} if($path -match '[^/]$'){ $path= (resolve-path -path $path).path+"/"} $ProgressPreference= "SilentlyContinue" From 0361a0dff31fb3616faa21d7498c421e5a3f6909 Mon Sep 17 00:00:00 2001 From: he852100 Date: Sat, 25 Jan 2020 07:09:03 +0000 Subject: [PATCH 14/18] add uriencode file path Support /drive/root:/%E5%9B%BE%xxx or /%E5%9B%BE%xxx --- Sources/OneDrive.psm1 | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index fbff943..52a6813 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -389,6 +389,10 @@ function Format-ODPathorIdString [string]$DriveId="", [string]$ElementId="" ) + if($Path -cmatch'(%[A-F0-9]{2}){2}'){ + if($Path -match ':'){$Path=$Path -replace '^[^:]+:'} + $Path=[System.Web.HttpUtility]::UrlDecode($Path) + } if (!$ElementId -eq "") { # Use ElementId parameters @@ -906,7 +910,7 @@ function Add-ODItemLarge { [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$LocalFile="" ) - + $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId function splash{$string=@() $string=@{ enableglobal=$true} @@ -1105,7 +1109,7 @@ function Move-ODItem } } } -function get-odsharelinkdownload +function get-ODShareLinkDownload <# .DESCRIPTION Download a shared file @@ -1119,7 +1123,6 @@ function get-odsharelinkdownload get-ODShareLinkDownload -URL xxx get-ODShareLinkDownload -URL xxx -path c:\d\d\ .NOTES - Avoid downloading large files The application for OneDrive 4 Business needs "Read items in all site collections" on application level (API: Office 365 SharePoint Online) Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer From 015ca43845ca38c909f4766285420ac629aef444 Mon Sep 17 00:00:00 2001 From: he852100 Date: Thu, 20 Feb 2020 12:37:01 +0000 Subject: [PATCH 15/18] test --- Sources/OneDrive.psm1 | 86 ++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 52a6813..249b09a 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -1,18 +1,3 @@ -function jwt-decode { -PAram([Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$data) -if (-not($data)){Write-Error "没有输入值,例如:JWTxxxxxxxx.....";break;} -[array]$data=$data -split '\.' -function frombase64 { -param([Parameter(Position = 0, ValueFromPipeline = $True)] -[string]$a) -$c=$a.Length -if((4 -lt $c) -and(0 -ne $c%4)){$b=4-$c%4}elseif($c -lt 4){$b=4-$c}else{$b=0} -[System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($a+("="*$b)))} -$base=@() -for($i=0;$I -lt ($data.length -1);$i++){ -frombase64 $data[$i]|convertfrom-json}} - - function Get-ODAuthentication { <# @@ -45,19 +30,43 @@ function Get-ODAuthentication Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> PARAM( - [Parameter(Mandatory=$True)] + [Parameter(Mandatory=$True,HelpMessage="ClientId of your 'app' from https://apps.dev.microsoft.com,'93xxxx81-2a8a-46d7-8524-9xxe07c6xxx0'")] + [ValidateScript( + { + if ($_ -cmatch '([a-f0-9]{4,}-?){4,}') + { + $true + } + else + { + Throw 'ClientId error' + } + })] [string]$ClientId = "unknown", [string]$Scope = "onedrive.readwrite,offline_access", [string]$RedirectURI ="https://login.live.com/oauth20_desktop.srf", [string]$AppKey="", [string]$RefreshToken="", + [ValidateScript( + { + if ($_ -cmatch '^h(\w)\1ps:\/\/[^,<>/]+?-my.sharepoint.com\/?$|^[^,/]{2,20}$') + { + $true + } + else + { + Throw 'Accepted value: "" or "https://-my.sharepoint.com/"' + } + })] [string]$ResourceId="", [switch]$DontShowLoginScreen=$false, [switch]$AutoAccept, [switch]$LogOut, - [switch]$enableglobal + [switch]$EnableGlobalVariable ) - if($ClientId -cnotmatch '([a-f0-9]{4,}-?){4,}'){write-host 'ClientId error' -ForegroundColor red;break} + if($ResourceId -cmatch '^[^,<>/]{2,20}$') + {$ResourceId="https://${ResourceId}-my.sharepoint.com"} + #if($ClientId -cnotmatch '([a-f0-9]{4,}-?){4,}'){write-host 'ClientId error' -ForegroundColor red;break} $optResourceId="" $optOauthVersion="/v2.0" if ($ResourceId -ne "") @@ -84,12 +93,17 @@ function Get-ODAuthentication } else { write-debug("Authentication mode: " +$Type) - $ErrorActionPreference="SilentlyContinue" - $null=[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") - $Verify= $? - $ErrorActionPreference="Continue" - [Reflection.Assembly]::LoadWithPartialName("System.Drawing") | out-null - [Reflection.Assembly]::LoadWithPartialName("System.Web") | out-null + try{ + new-object System.Windows.Forms|out-null + }catch{ + Write-Warning $_.Exception.Message + $Verify=1 + } + if($Verify -ne 1){ + [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") + [Reflection.Assembly]::LoadWithPartialName("System.Drawing") + [Reflection.Assembly]::LoadWithPartialName("System.Web") + } if ($Logout) { $URIGetAccessToken="https://login.live.com/logout.srf" @@ -107,7 +121,7 @@ function Get-ODAuthentication $URIGetAccessToken="https://login.live.com/oauth20_authorize.srf?client_id="+$ClientId+"&scope="+$Scope+"&response_type="+$Type+"&redirect_URI="+$RedirectURI } } - if($Verify){ + if($Verify -ne 1){ $form = New-Object Windows.Forms.Form $form.text = "Authenticate to OneDrive" $form.size = New-Object Drawing.size @(700,600) @@ -188,10 +202,24 @@ function Get-ODAuthentication if ($appkey){ $Authentication | add-member Noteproperty "appkey" ($appkey) } - if($enableglobal){ + if($EnableGlobalVariable){ $Global:Authentication=$Authentication } <# +function jwt-decode { +PAram([Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$data) +if (-not($data)){Write-Error "没有输入值,例如:JWTxxxxxxxx.....";break;} +[array]$data=$data -split '\.' +function frombase64 { +param([Parameter(Position = 0, ValueFromPipeline = $True)] +[string]$a) +$c=$a.Length +if((4 -lt $c) -and(0 -ne $c%4)){$b=4-$c%4}elseif($c -lt 4){$b=4-$c}else{$b=0} +[System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($a+("="*$b)))} +$base=@() +for($i=0;$I -lt ($data.length -1);$i++){ +frombase64 $data[$i]|convertfrom-json}} + $URL=$Key -replace '[^#]+#' -split '&' -replace '^[^=]+$' -split '=' $format=@() for(($i=0),($j=1);$I -lt $URL.length;($i+=2),($j+=2)){ @@ -258,7 +286,7 @@ function Get-ODWebContent $ODRootURI=Get-ODRootUri -ResourceId $ResourceId function splash{$string=@() - $string=@{ enableglobal=$true} + $string=@{ EnableGlobalVariable=$true} if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} @@ -828,7 +856,7 @@ function Add-ODItem ) $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId function splash{$string=@() - $string=@{ enableglobal=$true} + $string=@{ EnableGlobalVariable=$true} if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} @@ -913,7 +941,7 @@ function Add-ODItemLarge { $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId function splash{$string=@() - $string=@{ enableglobal=$true} + $string=@{ EnableGlobalVariable=$true} if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} From 757e6cad8bfe5e0c9be305d3d90803d6c26228cc Mon Sep 17 00:00:00 2001 From: he852100 Date: Fri, 21 Feb 2020 13:26:20 +0000 Subject: [PATCH 16/18] fix add-itemlarge (powershell core) --- Sources/OneDrive.psm1 | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 249b09a..19f7670 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -977,7 +977,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} $rURI1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/createUploadSession").Replace("/root/","/root:/") # Initialize upload session - $webRequest=Invoke-WebRequest -Method PUT -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -UseBasicParsing -ErrorAction SilentlyContinue + $webRequest=Invoke-WebRequest -Method PUT -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -UseBasicParsing # Parse the response JSON (into a holder variable) $convertResponse = ($webRequest.Content | ConvertFrom-Json) @@ -990,7 +990,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} # echo "Total file size (bytes): $totalLength" # Set the upload chunk size (Recommended: 5MB) - $uploadLength = 5 * 1024 * 1024; # == 5242880 byte == 5MB. + $uploadLength = 1 * 1024 * 1024; # == 5242880 byte == 5MB. # echo "Size of upload fragments (bytes): $uploadLength" # == 5242880 # Set the starting byte index of the upload (i. e.: the index of the first byte of the file to upload) @@ -1037,12 +1037,14 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} # The (default) length of an upload session is about 15 minutes! # Set the headers for the actual file chunk's PUT request (by means of the above preset variables) + if($PSVersionTable.PSEdition -eq 'core'){ + $actHeaders=@{"Content-Range"="bytes $startingIndex-$endingIndex/$totalLength"}; + }else{ $actHeaders=@{"Content-Length"="$uploadLength"; "Content-Range"="bytes $startingIndex-$endingIndex/$totalLength"}; - + } # Execute the PUT request (upload file chunk) write-debug("Uploading chunk of bytes. Progress: "+$endingIndex/$totalLength*100+" %") - $uploadResponse=Invoke-WebRequest -Method PUT -Uri $uURL -Headers $actHeaders -Body $buf -UseBasicParsing -ErrorAction SilentlyContinue - + $uploadResponse=Invoke-WebRequest -Method PUT -Uri $uURL -Headers $actHeaders -Body $buf -UseBasicParsing # startingIndex should be incremented (with the size of the actually uploaded file chunk) for the next iteration. # (Since the new value for startingIndex was preset above, as newStartingIndex, here we just have to overwrite startingIndex with it!) $startingIndex = $newStartingIndex @@ -1057,6 +1059,7 @@ if (-not($AccessToken)){$AccessToken=$Authentication.access_token} write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) #return -1 $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} + $_.ErrorDetails.Message if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} From 410e89219120b4bea6a77b4c138e443917a3f286 Mon Sep 17 00:00:00 2001 From: he852100 Date: Thu, 12 Mar 2020 14:41:48 +0000 Subject: [PATCH 17/18] =?UTF-8?q?=E6=96=AD=E7=82=B9=E7=BB=AD=E4=BC=A0?= =?UTF-8?q?=EF=BC=8Cget-oditem=20=E6=B7=BB=E5=8A=A0=E7=AE=A1=E9=81=93?= =?UTF-8?q?=E8=BE=93=E5=85=A5,=E6=B7=BB=E5=8A=A0=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/OneDrive.psd1 | Bin 8454 -> 4949 bytes Sources/OneDrive.psm1 | 721 ++++++++++++++++++++++-------------------- 2 files changed, 376 insertions(+), 345 deletions(-) diff --git a/Sources/OneDrive.psd1 b/Sources/OneDrive.psd1 index 058afc476dc5765630a30e39caacd1734da676c0..5cd9ca89d171e680a716ad742bd74e86f5e0fe67 100644 GIT binary patch literal 4949 zcmd5=Yj4{&6#cGWK_CO14zb*%S=JRO&>&9I0C^!v_W<^Vmac3r5~-0?5@XnZ-?^kL z%TArO12!x`3rHf*eVzOARNc~g_6s?XI8j>K z`Qk;PppkUWWGcveRDLG>Ou0_YG`TUxx4OR3+C*+tjtOZ0Yswajra28~~3@RZFiXB`sfz_u|9$D;9S)7LCId zZ$zWj?+ul6p>on*74yF2eLMW__5Sz6eJb+d+sQ#Te3Q}l2a~=o(tT6Ae}#lX%Ae=idd-_NO4+CKDPJkxmDAd z7tSLV73>KViO~qIOpeUr3;?#XSBUuT!4Uubu!$uBdQ2|RfMXPFBT+OuV{gk+`MIdA zd4LC*Zz~S$UxdW#c+7RTIRrAx$T_iKg{VOW#uZZMVqZ)er!*f3)Vem0WN&9wmZ|u~ zG$NB)lnTj^D@&O-R*~BgQvzej%UpWN3NuSxz$;9dlid-SCHM&b;YZxasifs|JQ}DC z9XQV%a_61+RF_8P;cIRlb$AHaskjTAkJ$)vu{0sU24+Z(V>rS_6l5p5Q`+lKWFf`hzwFtIrwh60}tJk zu%wwet-jYKNk`(*DwvJe5(%qHp$ajFTMGrd0~%RttYcEPpJwubPg_FXIG+Z7Tqv!o zrUGwc9=9A>8X!nd5yfx|fqKT1EwMb?%kuyp`2HMmW)OAO;_vW2;@~1@zEIn*!d}<+ zGtRhBnKjN7UZj`DcjCk%5Rb;*Z_>Y|Q;mAf20D%rO6miWEz%Jo?|Doh&F;Oa1;q*| zj4tOX3ffcuRsI=>9qH1u300q&= zX7EMkk&R;e(rDTdKfgWL5r_ea=MMi|Yb;u-%!qI?O6F9tTJB!k& zQtX&%X(p&kq#u+uIuzL2D(Hpp@iek6CT8r*5PZ`zH1;sJY(j_5Q8g)1uU5r!Q9*)y zF>nv3YjADTj%9BfeRlU%6v9OU;S@>-gR)Rp2JS0NVp>IbcV}9!E{(dI*KLInLF`ji zLb73Zwst+DB5rgRU;iBJiLn(T)3fI*fg`}@pcirJLWpTbpx^LF5rc^0$MXoPWUTJ4 zrc4zI-{HmOY%_{Tom1ea%K)>G&_(B@ZJh|b5%k0?6NNPugz(%Hr0j&QgI?jeAEEdV0P+z4$vk1yzlWu8f!$HvxvX!{tei_T-`JK-pL5mhz%w6s=Y)(Q5sJwuyb$LJJF zlTOP!a~yRNXVT43i5eR0h{0i=53j~&7&lg*&ZV95fkdqS4Nie@HRg$E*%|q2 ze19~9QHQ)?aTW=(d5Wz z50&}dg?XT*)z3`4q(^)`38MuczoBa7!r+#;khKUdRG_0O#{lxbVMMmBPMWkD_Sx`l zQ2j?~mBgg|lJZG+sDFQr1w5J`mI`CZOHlu5W}xA&s*@(IhJ8DtAI7&wXpYV_*tT9W z09KA&cC$Fy18UckbDn2Wb5NYS5>(6V9=$k^Q*f_P04)}naI32^eT-N(UqU#+sJnXq z8p|XP$YFv;Rj9G!ak={XI=C2(QFmnN45kb1B`T-H#x~~poa>2a0!7Lvfr(N>5;B5d{9RGpP;?vFf!gHm{NJ9v36n)t}l=FDxlU2Oq zA;BWhGbl{!T0GJu%!VCaZOv~OkNRq%81kzZ0nr~6;sW|&q(&He<*j;tJVk@#{he mV7`jMKMqXASs2xa(NSUuasWRpK=CwwIbkXBeVbQ*Cdps+@N&ig literal 8454 zcmdU!TTfh76vy|oiQnO5cxjDH3$3&@F)3vz5KC>KR84&0GQh|%;9N>u?GGa}F~=3sw!8+u3`s^mW<(kOM)aoSG3)JglPod#*B zwf*#a>g#h)D}&13A~n)tdZ%-J?OspMN_5&(5=_9Sq& z3?K4>6W+&Td{w<5_kmVVgnQ2<8|qh)Hq(*Gcq$2J^&8D1Z;_seVlVxw@5lBOeWO** zb%YND8(KNhlWY-aex+AKJAO#t7^jwTc&&3yX=WgLb7OtirFdn$2cnOr2YQXP`*@5f z%UHGSz_64tROtkwdDCk19QU=<5@Pp^!ldh&7Dke+V_NHJ{cElC^!Lto?50CQ*VB4g z`;(BZq^;yUTr=B3FfUKNr#~z_o4$~(@23a)c3;%@#eG)KcjO1V`gYGe?SX#nn1?(} zkM!(rO^1up)lhnK?+oTn^>HM)pQZKzt&xH@VVasxq6=_9lJ88A1ku4!Q)R`UQN7Q4rp+!kwe&03k z9tkTp%$Z}d?vNHtr$R$kI51j)=ay*S78Q@$1zF9%J<_x5==OJCY^vMx1(9 zDr?g-K;+0`EI+4*=FQm-*aJ&FHL6Ei_sHWZ^0vm@k(UhNt0D6X>ET3Kv18GKr|lb^ z-O^4xvXJd|^@k+vs%M2lwDF#S_V%>5YbS`oLh%6pk=DpYLE%ilhSGnLUg*r3o!&HC z<6TWX|6b2W`rH*gB<$*hR|v9*`+`S{Tl;hEAwQDm@w1`MdA8fulM_jXbRE$F0}?sD zeXWrf!4HjHqwQIe6M1!D>+FOEny;^ysXC|f6OZhHqyjzFVoQ4KiUUaV&OJRj6S};T zaif`+(i6Hs&hQbipyMnX^vEZ~57FH*O=b^34*U|&Aiki--oQqj4TWzYq<8dppnXsq zX?IiSi0wO-$XM5Dm#wdrNp@WkrpO*|6=CQ7Xi+>0wfFn zfrk6tf!PipIx-5J$5Z2U_yziXVfLl_fY+I6$gSXuX|&5;bfxl&-6}I{JmnvK<&5i_<|~_=5(ori2XKiz;5*4? zNZ+ZaUeF44npyBzIcz~4MnjVMJcDe`CAt;3Eb2v$b1rl@UZ=vY&rN?ZLuL9chIQgZ|*y?3jB-tlHH& zJUQu|Q~WxX529JtLW&LjqMCTmv{%Z~Uh~PmkEL(-jW`umW^qi9?!2oi7d?<`hR*f6 z8o0hhRg4~eZrSN_m8a%B6T41t$%8gE*UhSXj%k^d+vEQ4=421+<13S_9o3F`Z(nDh?(jY``?+Jpr{7<`r{>4>bi@C+lx3tJB5BS(?TR;(aquei?$at0 zA2R^?#=GD0SGxamN(8Z8Zk#BXj-f$JNxLv;-oo51R7tkBg+G zTC}8EL>>38iQa|oCg;AER(8ibm_vPi8qV`o@tI`x7@@AjgkHX<$ETxOd4;V<1vlo* z*2BL&Hb-ze3jF>Uo{BI29`vX2505@IPkb#5<8|!Qz5(jrW27_iCS`d+?1npIv$sFTfVj``3IK$ ziOIO}^$CW&Oa2?^?scedUGeez12Dy1=A;_}R_R{oQT%>BbeuhfDJ9?BxtzRn`-5Nj z3D55I`5n=8TLt>CaQ-h#Azb{GWt_e%cF*WUL%jr()Ii_pt%xko@92_7{UTw;h*uxzT_i$Z1&n>q{Avb4e9-AJCBRXStz(0E9 zStull&l#N#c|!hj-yi$pll{wM9(1Q0ilY2q79xsCj{m1zKK;7If^vMq0Xm+|$hBK$ zQ%Bb*RlqnApBH1pe@Cj#L-VyAS;!~9X*hji{LysDjT;$1IK?L%^FAv0^|9s%q{G-$ zm(83-7vpoL`_?2M;~8@R@j$-52=$uu%l*Ln;3bzqxh+1}g$Ws69tkm*WUu#bB6Jm> z=xiFD={EjFr#QJR%pPsLGa;2Dcv_aicDyd4GAVCdMh`@*!qJsqtqB=-sIwLoYg+N> zMN`#m;CiW_BbGSjH=qB;O?$Ps+>~wo{~>tQo+RumyK|TQMkwQE>xrae{ya3lDBpx! z-UpuVmFxX`Q=G`*=/]{2,20}$') - {$ResourceId="https://${ResourceId}-my.sharepoint.com"} + {$ResourceId="https://${ResourceId}-my.sharepoint.com/"} #if($ClientId -cnotmatch '([a-f0-9]{4,}-?){4,}'){write-host 'ClientId error' -ForegroundColor red;break} $optResourceId="" $optOauthVersion="/v2.0" @@ -77,10 +131,10 @@ function Get-ODAuthentication } $Authentication="" if ($AppKey -eq "") - { + { $Type="token" - } else - { + } else + { $Type="code" } if ($RefreshToken -ne "") @@ -152,7 +206,7 @@ function Get-ODAuthentication $regex= 'access_token=[^&]+|\?code=[^&]+' do { $key=read-host -prompt 'URL' - if (-not($key -match $regex)){write-host "`rERROR" -ForegroundColor DarkCyan|out-host} + if (-not($key -match $regex)){write-host "`rERROR,Enter 'exit' to exit read-host" -ForegroundColor DarkCyan|out-host} }until($key -match $regex) $Global:ODAccessToken=($key|select-string -pattern '(?<=token=)[^&]+' ).matches.value $Global:odtokentime=get-date @@ -165,7 +219,7 @@ function Get-ODAuthentication { write-debug("Getting code to redeem token") $Authentication = New-Object PSObject - ForEach ($element in $ReturnURI.Split("?")[1].Split("&")) + ForEach ($element in $ReturnURI.Split("?")[1].Split("&")) { $Authentication | add-member Noteproperty $element.split("=")[0] $element.split("=")[1] } @@ -181,7 +235,7 @@ function Get-ODAuthentication } else { $Authentication = New-Object PSObject - ForEach ($element in $ReturnURI.Split("?")[1].Split("&")) + ForEach ($element in $ReturnURI.Split("?")[1].Split("&")) { $Authentication | add-member Noteproperty $element.split("=")[0] $element.split("=")[1] } @@ -206,20 +260,6 @@ function Get-ODAuthentication $Global:Authentication=$Authentication } <# -function jwt-decode { -PAram([Parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$data) -if (-not($data)){Write-Error "没有输入值,例如:JWTxxxxxxxx.....";break;} -[array]$data=$data -split '\.' -function frombase64 { -param([Parameter(Position = 0, ValueFromPipeline = $True)] -[string]$a) -$c=$a.Length -if((4 -lt $c) -and(0 -ne $c%4)){$b=4-$c%4}elseif($c -lt 4){$b=4-$c}else{$b=0} -[System.Text.Encoding]::Utf8.GetString([System.Convert]::FromBase64String($a+("="*$b)))} -$base=@() -for($i=0;$I -lt ($data.length -1);$i++){ -frombase64 $data[$i]|convertfrom-json}} - $URL=$Key -replace '[^#]+#' -split '&' -replace '^[^=]+$' -split '=' $format=@() for(($i=0),($j=1);$I -lt $URL.length;($i+=2),($j+=2)){ @@ -227,15 +267,30 @@ $format+=@{$URL[$i]=$URL[$j]}} $access_token=jwt-decode $format.access_token $global:authen=jwt-decode $format.authentication_token $global:authentication_token= -(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($authen.exp[1])) +(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($authen.exp[1])) #> - return $Authentication + return $Authentication } -function Get-ODRootUri +function Get-ODRootUri { PARAM( + [ValidateScript( + { + if ($_ -cmatch '^h(\w)\1ps:\/\/[^,<>/]+?-my.sharepoint.com\/?$|^[^,/]{2,20}$' -or $_ -eq '') + { + $true + } + else + { + Throw 'Accepted value: "" or "https://-my.sharepoint.com/"' + } + })] [String]$ResourceId="" ) + if($ResourceId -cmatch '^[^,<>/]{2,20}$') + {$ResourceId="https://${ResourceId}-my.sharepoint.com"} + if($ResourceId -cmatch 'https:\/\/[^,<>/]{2,20}-my.sharepoint.com$') + {$ResourceId=$($ResourceId -replace '(\w$)','$1/')} if ($ResourceId -ne "") { return $ResourceId+"_api/v2.0" @@ -246,7 +301,7 @@ function Get-ODRootUri } } -function Get-ODWebContent +function Get-ODWebContent { <# .DESCRIPTION @@ -271,79 +326,19 @@ function Get-ODWebContent [string]$AccessToken, [String]$ResourceId="", [string]$rURI = "", - [ValidateSet("PUT","GET","POST","PATCH","DELETE")] + [ValidateSet("PUT","GET","POST","PATCH","DELETE")] [String]$Method="GET", [String]$Body, [switch]$BinaryMode ) - if ($Body -eq "") + if ($Body -eq "") { $xBody=$null } else { $xBody=$Body } - - $ODRootURI=Get-ODRootUri -ResourceId $ResourceId - function splash{$string=@() - $string=@{ EnableGlobalVariable=$true} - if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ - if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} - if($Authentication.refresh_token){$string+=@{RefreshToken=$Authentication.refresh_token}} - if($Authentication.appkey){$string+=@{appkey=$Authentication.appkey}}} - $string} - $string= splash - if (!($Authentication)){$Global:Authentication = New-Object PSObject} - if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ - switch ($Authentication.ResourceId -eq $null) { - true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} - false {$Authentication.access_token=$AccessToken}}} - if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - switch ($Authentication.ResourceId -eq $null) { - false {$Authentication.ResourceId=$ResourceId} - true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} - $code=@('WWW-Authenticate') -do{ -if($mess){ -$null=Get-ODAuthentication @string -if(!($?)){break} -remove-variable mess -force -$string=splash -if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} -if (-not($AccessToken)){$AccessToken=$Authentication.access_token} - try { - $webRequest=Invoke-WebRequest -Method $Method -Uri ($ODRootURI+$rURI) -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $xBody -UseBasicParsing - } - catch - { - $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} - if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` - -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| - ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} - } -}until($code -notcontains $mess.key) - switch ($webRequest.StatusCode) - { - 200 - { - if (!$BinaryMode) {$responseObject = ConvertFrom-Json $webRequest.Content} - return $responseObject - } - 201 - { - write-debug("Success: "+$webRequest.StatusCode+" - "+$webRequest.StatusDescription) - if (!$BinaryMode) {$responseObject = ConvertFrom-Json $webRequest.Content} - return $responseObject - } - 204 - { - write-debug("Success: "+$webRequest.StatusCode+" - "+$webRequest.StatusDescription+" (item deleted)") - $responseObject = "0" - return $responseObject - } - #default {write-warning("Cannot access the api. Webrequest return code is: "+$webRequest.StatusCode+"`n"+$webRequest.StatusDescription)} - } + getweb -Method $Method -Body $xBody -accesstoken $accesstoken -ResourceId $ResourceId } function Get-ODDrives @@ -368,7 +363,7 @@ function Get-ODDrives [String]$ResourceId="" ) $ProgressPreference="SilentlyContinue" - $ResponseObject=Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method GET -rURI "/drives" + $ResponseObject=Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method GET -rURI "/drives" return $ResponseObject.Value } @@ -426,8 +421,8 @@ function Format-ODPathorIdString # Use ElementId parameters if (!$Path -eq "") {write-debug("Warning: Path and ElementId parameters are set. Only ElementId is used!")} $drive="/drive" - if ($DriveId -ne "") - { + if ($DriveId -ne "") + { # Named drive $drive="/drives/"+$DriveId } @@ -449,11 +444,11 @@ function Format-ODPathorIdString $tmpString="" foreach ($Sub in $Path.Split("/")) {$tmpString+=$Sub+"/"} $Path=$tmpString - # remove last "/" if exist + # remove last "/" if exist $Path=$Path.TrimEnd("/") # insert drive part of URL - if ($DriveId -eq "") - { + if ($DriveId -eq "") + { # Default drive $Path="/drive/root:"+$Path+":" } @@ -489,7 +484,7 @@ function Get-ODItemProperty Get the default set of metadata for a file or folder (name, size, lastModifiedDateTime, id) Get-ODItemProperty -AccessToken $AuthToken -ElementId 8BADCFF017EAA324!12169 -SelectProperties "" - Get all metadata of a file or folder by element id ("" select all properties) + Get all metadata of a file or folder by element id ("" select all properties) .NOTES Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> @@ -552,10 +547,10 @@ function Get-ODChildItems $ProgressPreference="SilentlyContinue" $ODRootURI=Get-ODRootUri -ResourceId $ResourceId if ($Path.Contains('$skiptoken=') -or $Loop) - { + { # Recursive mode of odata.nextLink detection write-debug("Recursive call") - $rURI=$Path + $rURI=$Path } else { @@ -577,7 +572,7 @@ function Get-ODChildItems } else { - if (!$SearchText -eq "") + if (!$SearchText -eq "") { # Search mode $opt="/view.search?q="+$SearchText+"&select="+$SelectProperties @@ -592,7 +587,7 @@ function Get-ODChildItems } write-debug("Accessing API with GET to "+$rURI) $ResponseObject=Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method GET -rURI $rURI - if ($ResponseObject.PSobject.Properties.name -match "@odata.nextLink") + if ($ResponseObject.PSobject.Properties.name -match "@odata.nextLink") { write-debug("Getting more elements form service (@odata.nextLink is present)") write-debug("LAST: "+$ResponseObject.value.count) @@ -631,7 +626,7 @@ function Search-ODItems .PARAMETER DriveId Specifies the OneDrive drive id. If not set, the default drive is used. .EXAMPLE - Search-ODItems -AccessToken $AuthToken -Path "/My pictures" -SearchText "FolderA" + Search-ODItems -AccessToken $AuthToken -Path "/My pictures" -SearchText "FolderA" Search-ODItems Search-ODItems Search-ODItems @@ -735,14 +730,16 @@ function Remove-ODItem [string]$DriveId="" ) $ProgressPreference="SilentlyContinue" - if (($ElementId+$Path) -eq "") + if (($ElementId+$Path) -eq "") { write-error("Path nor ElementId is set") } else { $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId - return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method DELETE -rURI $rURI + $delete=Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method DELETE -rURI $rURI + if($delete -eq 0){"deleted file: $Path$ElementId"|out-host} + #return } } @@ -771,6 +768,7 @@ function Get-ODItem .NOTES Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> + [CmdletBinding()] PARAM( [Parameter(Mandatory=$false)] [string]$AccessToken, @@ -783,7 +781,7 @@ function Get-ODItem [string]$LocalPath="", [string]$LocalFileName ) - if (($ElementId+$Path) -eq "") + if (($ElementId+$Path) -eq "") { write-error("Path nor ElementId is set") } @@ -791,32 +789,35 @@ function Get-ODItem { $Download=Get-ODItemProperty -AccessToken $AccessToken -ResourceId $ResourceId -Path $Path -ElementId $ElementId -DriveId $DriveId -SelectProperties "name,@content.downloadUrl,lastModifiedDateTime" + if($Download){ if ($LocalPath -eq "") {$LocalPath=Get-Location} $LocalPath=resolve-Path ($LocalPath.TrimEnd("\")+"\") + write-verbose "Downloadlink: $($Download.'@content.downloadUrl')" if ($LocalFileName -eq "") { $SaveTo=$LocalPath+$Download.name } else { - $SaveTo=$LocalPath+$LocalFileName + $SaveTo=$LocalPath+$LocalFileName } try { - [System.Net.WebClient]::WebClient + $client = New-Object System.Net.WebClient $client.DownloadFile($Download."@content.downloadUrl",$SaveTo) $file = Get-Item $saveTo $file.LastWriteTime = $Download.lastModifiedDateTime write-verbose("Download complete") - return 0 + + return (Get-Item $saveTo) } catch { write-error("Download error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) return -1 - } - } + }} + } } function Add-ODItem { @@ -836,7 +837,7 @@ function Add-ODItem .PARAMETER LocalFile Path and file of the local file to be uploaded (C:\data\data.csv). .EXAMPLE - Add-ODItem -AccessToken $AuthToken -Path "/Data/documents/2016" -LocalFile "AzureML with PowerShell.docx" + Add-ODItem -AccessToken $AuthToken -Path "/Data/documents/2016" -LocalFile "AzureML with PowerShell.docx" Upload a file to OneDrive "/data/documents/2016" .NOTES Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer @@ -845,61 +846,26 @@ function Add-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", - [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="/", - [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="", - [Parameter(Mandatory=$true,ParameterSetName="path")] - [Parameter(Mandatory=$true,ParameterSetName="id")] + [ValidateScript( + { + if (test-path $_ -PathType Leaf ) + { + $true + } + else + { + Throw "file does not exist" + } + })] + [Parameter(Mandatory=$true)] [string]$LocalFile="" ) + if($ElementId -and $Path){throw '"-ElementId" and "-Path"Cannot coexist';break} $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId - function splash{$string=@() - $string=@{ EnableGlobalVariable=$true} - if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ - if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} - if($Authentication.refresh_token){$string+=@{RefreshToken=$Authentication.refresh_token}} - if($Authentication.appkey){$string+=@{appkey=$Authentication.appkey}}} - $string} - $string= splash - if (!($Authentication)){$Global:Authentication = New-Object PSObject} - if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ - switch ($Authentication.ResourceId -eq $null) { - true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} - false {$Authentication.access_token=$AccessToken}}} - if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - switch ($Authentication.ResourceId -eq $null) { - false {$Authentication.ResourceId=$ResourceId} - true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} - $code=@('WWW-Authenticate') -do{ -if($mess){ -$null=Get-ODAuthentication @string -if(!($?)){break} -remove-variable mess -force -$string=splash -if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} -if (-not($AccessToken)){$AccessToken=$Authentication.access_token} - try - { - $spacer="" - if ($ElementId -ne "") {$spacer=":"} - $ODRootURI=Get-ODRootUri -ResourceId $ResourceId - $ruri1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/content").Replace("/root/","/root:/") - return $webRequest=Invoke-WebRequest -Method PUT -InFile $LocalFile -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "multipart/form-data" -UseBasicParsing -ErrorAction SilentlyContinue|%{$_.content}|convertfrom-json - } - catch - { - write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) - #return -1 - $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} - if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` - -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| - ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} - } -}until($code -notcontains $mess.key) + getweb -method put -accesstoken $accesstoken -ResourceId $ResourceId -localfile $LocalFile -additem } function Add-ODItemLarge { <# @@ -919,152 +885,135 @@ function Add-ODItemLarge { .PARAMETER LocalFile Path and file of the local file to be uploaded (C:\data\data.csv). .EXAMPLE - Add-ODItem -AccessToken $AuthToken -Path "/Data/documents/2016" -LocalFile "AzureML with PowerShell.docx" + Add-ODItem -AccessToken $AuthToken -Path "/Data/documents/2016" -LocalFile "AzureML with PowerShell.docx" Upload a file to OneDrive "/data/documents/2016" .NOTES Author: Benke Tamás - (funkeninduktor@gmail.com) #> - + [CmdletBinding()] PARAM( [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", - [Parameter(Mandatory=$true,ParameterSetName="path")] [string]$Path="/", - [Parameter(Mandatory=$true,ParameterSetName="id")] [string]$ElementId="", [string]$DriveId="", - [Parameter(Mandatory=$true,ParameterSetName="path")] - [Parameter(Mandatory=$true,ParameterSetName="id")] - [string]$LocalFile="" + [ValidateScript( + { + if (test-path $_ -PathType Leaf ) + { + $true + } + else + { + Throw "file does not exist" + } + })] + [Parameter(Mandatory=$true)] + [string]$LocalFile="", + [int64]$uploadLength=5mb ) - + if($ElementId -and $Path){throw '"-ElementId" and "-Path"Cannot coexist';break} + $LocalFile=Resolve-Path $LocalFile + if($uploadLength -lt 320kb*2){$uploadLength = 5 * 1024 * 1024} + $br=$true + @("$($env:USERNAME)\appdata\local\Temp\","/tmp/")|ForEach-Object{ + if($br -and (test-path $_)){$tmp="${_}one.tmp";$br=$false}} + if(test-path $tmp){$schedule = get-content -path $tmp -raw + + if(test-json $schedule){ + $schedule = $schedule|convertfrom-json + if($schedule."expirationDateTime" -is [datetime]){$time=(new-timespan (get-date) $schedule."expirationDateTime").TotalSeconds + }}} + $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId - function splash{$string=@() - $string=@{ EnableGlobalVariable=$true} - if($ResourceId -cmatch '.{10,}'){$string+=@{ResourceId=$ResourceId}}else{ - if($Authentication.ClientId){$string+=@{ClientId = $Authentication.ClientId}} - if($Authentication.ResourceId){$string+=@{ResourceId=$Authentication.ResourceId}} - if($Authentication.refresh_token){$string+=@{RefreshToken=$Authentication.refresh_token}} - if($Authentication.appkey){$string+=@{appkey=$Authentication.appkey}}} - $string} - $string= splash - if (!($Authentication)){$Global:Authentication = New-Object PSObject} - if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ - switch ($Authentication.ResourceId -eq $null) { - true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} - false {$Authentication.access_token=$AccessToken}}} - if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ - switch ($Authentication.ResourceId -eq $null) { - false {$Authentication.ResourceId=$ResourceId} - true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} - $code=@('WWW-Authenticate') -do{ -if($mess){ -$null=Get-ODAuthentication @string -if(!($?)){break} -remove-variable mess -force -$string=splash -if($accesstoken){get-variable accesstoken|clear-variable|remove-variable}} -if (-not($AccessToken)){$AccessToken=$Authentication.access_token} - Try { + write-verbose 'Calculating file hash' + $hash=get-hashvalue -file $LocalFile + + # Begin to construct the real (full) URI $spacer="" if ($ElementId -ne "") {$spacer=":"} - $ODRootURI=Get-ODRootUri -ResourceId $ResourceId - - # Construct the real (full) URI - $rURI1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($LocalFile)+":/createUploadSession").Replace("/root/","/root:/") - - # Initialize upload session - $webRequest=Invoke-WebRequest -Method PUT -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -UseBasicParsing + + if($null -eq $time -or $time -lt 20){ + if(test-path $tmp){remove-item $tmp -force + $delete=getweb -Method Delete -uri $schedule.uploadUrl -accesstoken $accesstoken -ResourceId $ResourceId + if($delete -eq 0){write-verbose "deleted $($schedule.uploadUrl)"} + }; $time = $null + } + $fd=[IO.FileStream]::new($localfile, [IO.FileMode]::Open) + $totalLength=$fd.length + $ci=[math]::Ceiling($totalLength/$uploadLength) + + if(($schedule.hash -eq $hash.hash -and $schedule.filelength -eq $hash.filelength) -and $time -gt 20){ + $uURL=$schedule.uploadUrl + $getdata=getweb -method get -accesstoken $accesstoken -ResourceId $ResourceId -uri $uurl + write-verbose "getdata: $($getdata.nextExpectedRanges)" + [int64]$startingIndex =if($getdata){$getdata.nextExpectedRanges.split('-')[0]}else{remove-item $tmp -force ;return '获取在线进度出错,删除记录'} + $convertResponse=$schedule + + }else{ + # Initialize upload session + $convertResponse=getweb -method PUT -accesstoken $accesstoken -ResourceId $ResourceId -largelocalfile $localfile -additem # Parse the response JSON (into a holder variable) - $convertResponse = ($webRequest.Content | ConvertFrom-Json) + # Get the uploadUrl from the response (holder variable) $uURL = $convertResponse.uploadUrl - # echo "HERE COMES THE CORRECT uploadUrl: $uURL" - - # Get the full size of the file to upload (bytes) - $totalLength = (Get-Item $LocalFile).length - # echo "Total file size (bytes): $totalLength" - - # Set the upload chunk size (Recommended: 5MB) - $uploadLength = 1 * 1024 * 1024; # == 5242880 byte == 5MB. - # echo "Size of upload fragments (bytes): $uploadLength" # == 5242880 - + $convertResponse|add-member @{LocalFile=$LocalFile;hash=$hash.hash;filelength=$hash.filelength} + if($ci -gt 1){$convertResponse |convertto-json|set-content -path $tmp} # Set the starting byte index of the upload (i. e.: the index of the first byte of the file to upload) $startingIndex = 0 - - # Start an endless cycle to run until the last chunk of the file is uploaded (after that, BREAK out of the cycle) - while($True){ - # If startingIndex (= the index of the starting byte) is greater than, or equal to totalLength (= the total length of the file), stop execution, so BREAK out of the cycle - if( $startingIndex -ge $totalLength ){ - break - } - - # Otherwise: set the suitable indices (variables) - - # (startingIndex remains as it was!) - - # Set the size of the chunk to upload - # The remaining length of the file (to be uploaded) - $remainingLength = $($totalLength-$startingIndex) - # If remainingLength is smaller than the normal upload length (defined above as uploadLength), then the new uploadLength will be the remainingLength (self-evidently, only for the last upload chunk) - if( $remainingLength -lt $uploadLength ){ - $uploadLength = $remainingLength - } - # Set the new starting index (just for the next iteration!) - $newStartingIndex = $($startingIndex+$uploadLength) - # Get the ending index (by means of newStartingIndex) - $endingIndex = $($newStartingIndex-1) - - # Get the bytes to upload into a byte array (using properly re-initialized variables) - $buf = new-object byte[] $uploadLength - $fs = new-object IO.FileStream($LocalFile, [IO.FileMode]::Open) - $reader = new-object IO.BinaryReader($fs) - $reader.BaseStream.Seek($startingIndex,"Begin") | out-null - $reader.Read($buf, 0, $uploadLength)| out-null - $reader.Close() - # echo "Chunk size is: $($buf.count)" - - # Upoad the actual file chunk (byte array) to the actual upload session. - # Some aspects of the chunk upload: - # We don't have to authenticate for the chunk uploads, since the uploadUrl contains the upload session's authentication data as well. - # We above calculated the length, and starting and ending byte indices of the actual chunk, and the total size of the (entire) file. These should be set into the upload's PUT request headers. - # If the upload session is alive, every file chunk (including the last one) should be uploaded with the same command syntax. - # If the last chunk was uploaded, the file is automatically created (and the upload session is closed). - # The (default) length of an upload session is about 15 minutes! - - # Set the headers for the actual file chunk's PUT request (by means of the above preset variables) - if($PSVersionTable.PSEdition -eq 'core'){ - $actHeaders=@{"Content-Range"="bytes $startingIndex-$endingIndex/$totalLength"}; - }else{ - $actHeaders=@{"Content-Length"="$uploadLength"; "Content-Range"="bytes $startingIndex-$endingIndex/$totalLength"}; - } - # Execute the PUT request (upload file chunk) - write-debug("Uploading chunk of bytes. Progress: "+$endingIndex/$totalLength*100+" %") - $uploadResponse=Invoke-WebRequest -Method PUT -Uri $uURL -Headers $actHeaders -Body $buf -UseBasicParsing - # startingIndex should be incremented (with the size of the actually uploaded file chunk) for the next iteration. - # (Since the new value for startingIndex was preset above, as newStartingIndex, here we just have to overwrite startingIndex with it!) - $startingIndex = $newStartingIndex } - # The upload is done! - + +$wc=New-Object System.Net.WebClient +$start=get-date +while(![String]::IsNullOrEmpty($startingIndex)){ +$seek=$fd.seek($startingIndex,'begin') +$uploadLength=[math]::Min($uploadLength,$totalLength-$startingIndex ) +$buf=[byte[]]::new($uploadLength) +$read=$fd.Read($buf,0,$uploadLength) + +$endingIndex=$startingIndex+$uploadLength-1 +$object=[PScustomobject]@{ +'start'=yunsuan $startingIndex +'end'=yunsuan ($endingIndex+1) +'totalLength'=yunsuan $totalLength +'length'=yunsuan $uploadLength +#'seek'=yunsuan $seek +ExpectedRanges=$uploadresponse.nextExpectedRanges +#read=$read +次数=$_ +#buf=$buf.length #[$uploadLength] +#localfile=$localfile +} + +Write-Verbose ($object | Format-Table | Out-String) +$info="$([int64](($totalLength-$startingIndex)/1024))k/$([int64]($totalLength/1024))k:" +write-debug $info + +$progress=[int64]($startingIndex/$totalLength*100) + +Write-Progress -Activity "File uploading:$LocalFile" -Status "$progress% Complete $info" -PercentComplete $progress +$wc.headers.set("Content-Length",$uploadLength) +$wc.headers.set("Content-Range","bytes $startingIndex-$endingIndex/$totalLength") +try{ +[System.Text.Encoding]::ASCII.GetString($wc.UploadData($uurl,'PUT',$buf)) |convertfrom-json|set-variable uploadresponse -PassThru |ForEach-Object{$json=$_.value;'nextExpectedRanges','expirationDateTime'|ForEach-Object{$convertResponse.$_=$json.$_};$convertResponse}|convertto-json|ForEach-Object{if($ci -gt 1){set-content -value $_ -path $tmp}} +}catch{ +write-warning $_.Exception.Message +write-warning 'Will try again' +} +try{ +$startingIndex = [int64]$uploadResponse.nextExpectedRanges.split('-')[0] +}catch{ +remove-variable startingIndex -force +} + +} +$fd.Dispose() # At the end of the upload, write out the last response, which should be a confirmation message: "HTTP/1.1 201 Created" write-debug("Upload complete") - return ($uploadResponse.Content | ConvertFrom-Json) - } - Catch { - write-error("Upload error: "+$_.Exception.Response.StatusCode+"`n"+$_.Exception.Response.StatusDescription) - #return -1 - $mess=$_.Exception.response.Headers|?{$_.key -like 'WWW-Authenticate'} - $_.ErrorDetails.Message - if($mess){$mess.value -replace '(^[^=]+?)=','"$1":' ` - -replace ', *([^ =]+?)=',',"$1":' -replace '^','{' -replace '$','}'| - ConvertFrom-Json|out-host}else{Write-warning ($_.Exception.Message)} - } -}until($code -notcontains $mess.key) + return $uploadResponse } function Move-ODItem { @@ -1090,8 +1039,10 @@ function Move-ODItem Moves and renames a file in one step Move-ODItem -AccessToken $at -path "/Notes.txt" -NewName "_Notes.txt" # Rename a file - - Move-ODItem -AccessToken $at -path "/Notes.txt" -TargetPath "/x" # Move a file + + Move-ODItem -AccessToken $at -path "/Notes.txt" -TargetPath "/x" -verbose # Move a file + Move-ODItem -path /qq/gh.json -TargetPath :: -verbose + Move to the root directory .NOTES Author: Marcel Meurer, marcel.meurer@sepago.de, Twitter: MarcelMeurer #> @@ -1099,16 +1050,15 @@ function Move-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", - [Parameter(Mandatory=$true,ParameterSetName="path")] + [Parameter(parametersetname='path')] [string]$Path="", - [Parameter(Mandatory=$true,ParameterSetName="id")] + [Parameter(parametersetname='ElementId')] [string]$ElementId="", [string]$DriveId="", [string]$TargetPath="", [string]$NewName="" ) - $ProgressPreference="SilentlyContinue" - if (($ElementId+$Path) -eq "") + if (($ElementId+$Path) -eq "") { write-error("Path nor ElementId is set") } @@ -1119,9 +1069,9 @@ function Move-ODItem write-error("TargetPath nor NewName is set") } else - { + { $body='{' - if (!$NewName -eq "") + if (!$NewName -eq "") { $body=$body+'"name": "'+$NewName+'"' If (!$TargetPath -eq "") @@ -1129,25 +1079,26 @@ function Move-ODItem $body=$body+',' } } - if (!$TargetPath -eq "") + if (!$TargetPath -eq "") { $rTURI=Format-ODPathorIdString -path $TargetPath -DriveId $DriveId + $rTURI=$rTURI -replace ':$' $body=$body+'"parentReference" : {"path": "'+$rTURI+'"}' } $body=$body+'}' - $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId + $rURI=(Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId).TrimEnd(':') return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method PATCH -rURI $rURI -Body $body } } } -function get-ODShareLinkDownload +function Get-ODShareLinkDownload <# .DESCRIPTION Download a shared file .PARAMETER URL onedrive.live.com Share links .PARAMETER path - + .EXAMPLE get-ODShareLinkDownload -URL https://1drv.ms/f/s!AtftJLuuzIqngqg598UpNi1x5YJ8bQ Download a file @@ -1162,51 +1113,12 @@ function get-ODShareLinkDownload [Parameter(Mandatory=$true,Position=0)] [string]$uri, [Parameter(Mandatory=$false,Position=1)] - [string]$path='./') + [string]$path='./') if(-not(Test-Path $path)){write-host -ForegroundColor DarkCyan 'Tips:error path';break} if($path -match '[^/]$'){ $path= (resolve-path -path $path).path+"/"} $ProgressPreference= "SilentlyContinue" -function Runspace0{ -param($ScriptBlock) -$throttleLimit = 8 -$SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault() -$Pool = [runspacefactory]::CreateRunspacePool(1, $throttleLimit, $SessionState, $Host) -$Pool.Open() -if ($ScriptBlock -is [string]){[array]$ScriptBlock=$ScriptBlock} -$threads = @() -$handles = for ($x = 0; $x -lt $ScriptBlock.length; $x++) { -$fg=$ScriptBlock[$x] -$scriptblock1=@" -param(`$id) -`$ErrorActionPreference='SilentlyContinue'; -`$WarningPreference='SilentlyContinue'; -`$ProgressPreference='SilentlyContinue'; -`$code=($fg) -[PScustomobject]@{id=`$id;code=`$code} -"@ - $powershell = [powershell]::Create().AddScript($scriptblock1).AddArgument($x) - $powershell.RunspacePool = $Pool - $powershell.BeginInvoke() - $threads += $powershell} -if ($handles -is [string]){[array]$handles=$handles} -$ss=@() -do { -$done = $true -# ($handles -ne $null).length -for ($x=0;$X -lt $handles.length;$x++){ -$bi=$handles[$x].IsCompleted -like 'true' -if ($bi){ -$ss=$ss += $threads[$x].EndInvoke($handles[$x]) -$threads[$x].Dispose() -$handles[$x]=$null -$threads[$x]=$null}} -if ($handles.IsCompleted -ne $null){$done = $false} -if (-not $done) { Start-Sleep -Milliseconds 900 } -} until ($done) -($ss |sort-object -Property id).code} - function Folder-downloads { PAram([string]$URL,[string]$path='./') [array]$URL=$URL @@ -1216,7 +1128,7 @@ $data=@() $yuan='https://storage.live.com/items/' $folderID=@() do { -if ($folderID[0] -ne $null -and $folderID[0] -ne $replace){ +if ($null -ne $folderID[0] -and $folderID[0] -ne $replace){ [string]$replace=$folderID[0] $url=@() [array]$folder=$path1|select-object -Skip $folder.length @@ -1226,10 +1138,10 @@ for ($x=0;$X -lt $folderName.length;$x++) { $path1+=$folder[$i]+$folderName[$x]+'/' $itempath=$folder[$i]+$folderName[$x]+"/" $null=New-Item -path "$itempath" -itemtype Directory -force}} -$folderID|%{$url+="$yuan$_$key"} +$folderID|ForEach-Object{$url+="$yuan$_$key"} Remove-variable folderName,folderID -force} for ($x=0;$x -lt $URL.length;$x++){ -$xml=irm $URL[$x] +$xml=Invoke-RestMethod $URL[$x] $dd= [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::GetEncoding(28591).GetBytes($xml)) $key='?'+ ($URL[$x] |select-string -pattern 'authkey.*$').matches.value $dd=$([XML]$($dd -replace '^[^<]+')).Folder.Items @@ -1243,7 +1155,7 @@ path= $path1[$x]+$RelationshipName[$i] url=($yuan+$ResourceID[$i]+$key)}} [array]$folderID=$dd.folder.ResourceID [array]$folderName=$dd.folder.RelationshipName} -} until ($folderID -eq $null) +} until ($null -eq $folderID) $script=@() For ( $x=0; $x -lt $data.length;$x++){ $path=$data.path[$x] @@ -1251,15 +1163,15 @@ $URL=$data.url[$x] $script+="iwr '$URL' -o '$path'"} if ($script -is [array] -and $script.length -gt 5){ runspace0 $script -}elseif($script -is [string]){iex $script}else{ +}elseif($script -is [string]){Invoke-Expression $script}else{ for ($x=0;$x -lt $script.length;$x++){ -iex $script[$x]}} +Invoke-Expression $script[$x]}} write-host "文件数量:"$ResourceID.count -ForegroundColor Blue|out-host $data} if ($uri -notmatch 'onedrive|skydrive|storage'){ - $link=iwr $uri -MaximumRedirection 0 -SkipHttpErrorCheck -ErrorAction Ignore - $link=$link.headers.location + $link=Invoke-WebRequest $uri -MaximumRedirection 0 -SkipHttpErrorCheck -ErrorAction Ignore + $link=$link.headers.location }else{$link=$uri} if ($link -match 'ithint\=folder'){ $link= $link -replace '^(.*?)(?:onedrive|skydrive)(\..*)?(?:redir|download)\?resid\=(.*?\d)(\&a.*)$','$1storage$2items/$3?$4' @@ -1271,11 +1183,130 @@ if ($link -match 'ithint\=folder'){ $link= $link -replace '^(.*?)(?:onedrive|skydrive)(\..*)?(?:redir|download)(.*)$','$1skydrive$2download$3' #$link=iwr $uri -MaximumRedirection 0 -SkipHttpErrorCheck -ErrorAction Ignore [PScustomobject]@{链接地址=$link}|format-table -wrap - $data=iwr "$link" + $data=Invoke-WebRequest "$link" $replace=$data.headers.'Content-Disposition' -replace '^.*?(?=[^ ''"]+$)' $name=[System.Web.HttpUtility]::UrlDecode($replace) set-content -value $data -path "$path$name" [PScustomobject]@{ name=$name path=$path - URL=$link}}} \ No newline at end of file + URL=$link +}}} + +function Runspace0{ +param($ScriptBlock) +$throttleLimit = 8 +$SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault() +$Pool = [runspacefactory]::CreateRunspacePool(1, $throttleLimit, $SessionState, $Host) +$Pool.Open() +if ($ScriptBlock -is [string]){[array]$ScriptBlock=$ScriptBlock} +$threads = @() +$handles = for ($x = 0; $x -lt $ScriptBlock.length; $x++) { +$fg=$ScriptBlock[$x] +$scriptblock1=@" +param(`$id) +`$ErrorActionPreference='SilentlyContinue'; +`$WarningPreference='SilentlyContinue'; +`$ProgressPreference='SilentlyContinue'; +`$code=($fg) +[PScustomobject]@{id=`$id;code=`$code} +"@ + $powershell = [powershell]::Create().AddScript($scriptblock1).AddArgument($x) + $powershell.RunspacePool = $Pool + $powershell.BeginInvoke() + $threads += $powershell} +if ($handles -is [string]){[array]$handles=$handles} +$ss=@() +do { +$done = $true +# ($handles -ne $null).length +for ($x=0;$X -lt $handles.length;$x++){ +$bi=$handles[$x].IsCompleted -like 'true' +if ($bi){ +$ss=$ss += $threads[$x].EndInvoke($handles[$x]) +$threads[$x].Dispose() +$handles[$x]=$null +$threads[$x]=$null}} +if ($null -ne $handles.IsCompleted){$done = $false} +if (-not $done) { Start-Sleep -Milliseconds 900 } +} until ($done) +($ss |sort-object -Property id).code +} + + + +function getweb { +[CmdletBinding()] +param($method,$uri,$body,$accesstoken,$ResourceId,$LocalFile,$largelocalfile,[switch]$additem) +if($LocalFile -and $largelocalfile){write-error '-LocalFile and -largelocalfile 不能共存';break} +if($largelocalfile){$file=@($largeLocalFile,":/createUploadSession")}elseif($localfile){$file=@($LocalFile,":/content")} +if (!($Authentication)){$Global:Authentication = New-Object PSObject} + if($AccessToken -and ($AccessToken -ne $Authentication.access_token)){ + switch ($null -eq $Authentication.ResourceId) { + true {$Authentication | add-member Noteproperty 'access_token' ($AccessToken)} + false {$Authentication.access_token=$AccessToken}}} + if($ResourceId -and ($ResourceId -ne $Authentication.ResourceId)){ + switch ($null -eq $Authentication.ResourceId) { + false {$Authentication.ResourceId=$ResourceId} + true {$Authentication | add-member Noteproperty 'ResourceId' ($ResourceId)}}} + + $code=@('invalid_token',"The caller is not authenticated.","Authentication failed") + do{ + $ODRootURI=Get-ODRootUri -ResourceId $ResourceId + if($uri -match '^http') {$ruri1=$uri}elseif($additem){ + $rURI1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($File[0])+$File[1]).Replace("/root/","/root:/") + }else{$ruri1=($ODRootURI+$rURI)} + if($messq){remove-variable messq -force} + Try{ + if($LocalFile){ + $webRequest=Invoke-WebRequest -Method $Method -InFile $LocalFile -Uri $rURI1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "multipart/form-data" -UseBasicParsing + }else{ + $webRequest=Invoke-WebRequest -Method $Method -Uri $ruri1 -Header @{ Authorization = "BEARER "+$AccessToken} -ContentType "application/json" -Body $Body -UseBasicParsing + } + } + Catch { + #write-verbose ("Upload error: "+$_.Exception.Response.StatusCode+"`n"+ $_.Exception.Response.StatusDescription) + #return -1 + $mess=($_.Exception.response.Headers|Where-Object{$_.key -like 'WWW-Authenticate'}).value + if($mess){$mess=$mess -replace '(^|,)[ ]*([^=]+)=("[^"]+")','$1"$2":$3' -replace '^(.*)$','{$1}' |convertfrom-json;write-verbose ($mess|format-table |out-string)} + if($_.ErrorDetails.Message){ $messq=($_.ErrorDetails.Message|convertfrom-json).error.message;write-verbose ($messq|format-table|out-string)} + if($_.Exception.Message){write-verbose $_.Exception.Message} + if($code -contains $messq){#$mess.error + splash + $AccessToken=$Authentication.access_token + $ResourceId=$Authentication.resourceid + }} + }until($code -notcontains $messq) #$mess.error + switch ($webRequest.StatusCode) + { + 200 + { + if (!$BinaryMode) {$responseObject = ConvertFrom-Json $webRequest.Content} + return $responseObject + } + 201 + { + write-debug("Success: "+$webRequest.StatusCode+" - "+$webRequest.StatusDescription) + if (!$BinaryMode) {$responseObject = ConvertFrom-Json $webRequest.Content} + return $responseObject + } + 204 + { + write-debug("Success: "+$webRequest.StatusCode+" - "+$webRequest.StatusDescription+" (item deleted)") + $responseObject = "0" + return $responseObject + } + #default {write-warning("Cannot access the api. Webrequest return code is: "+$webRequest.StatusCode+"`n"+$webRequest.StatusDescription)} + } +} + +function yunsuan {param($data) +if ($data -ge 1GB) +{'{0:F0}GB' -f ($data / 1GB)} +elseif ($data -ge 1MB) +{'{0:F0}MB' -f ($data / 1MB)} +elseif ($data -ge 1KB) +{'{0:F0}KB' -f ($data / 1KB)} +else +{'{0}bytes' -f $data} +} From 51df07929d37d6ef88666a026909fd44774f30a6 Mon Sep 17 00:00:00 2001 From: he852100 Date: Wed, 1 Apr 2020 22:39:41 +0000 Subject: [PATCH 18/18] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=EF=BC=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/OneDrive.psm1 | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Sources/OneDrive.psm1 b/Sources/OneDrive.psm1 index 9dc7cc7..1238c69 100644 --- a/Sources/OneDrive.psm1 +++ b/Sources/OneDrive.psm1 @@ -54,6 +54,7 @@ function splash{ function Get-ODAuthentication { +# .ExternalHelp OneDrive-help.xml <# .DESCRIPTION Connect to OneDrive for authentication with a given client id (get your free client id on https://apps.dev.microsoft.com) For a step-by-step guide: https://github.com/MarcelMeurer/PowerShellGallery-OneDrive @@ -695,7 +696,8 @@ function New-ODFolder $ProgressPreference="SilentlyContinue" $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId $rURI=$rURI+"/children" - return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method POST -rURI $rURI -Body ('{"name": "'+$FolderName+'","folder": { },"@name.conflictBehavior": "fail"}') + $body=@{name=$FolderName;folder=@{};"@name.conflictBehavior"="fail"}|convertto-json -EscapeHandling EscapeNonAscii + return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method POST -rURI $rURI -Body $body } function Remove-ODItem @@ -846,7 +848,7 @@ function Add-ODItem [Parameter(Mandatory=$false)] [string]$AccessToken, [String]$ResourceId="", - [string]$Path="/", + [string]$Path="", [string]$ElementId="", [string]$DriveId="", [ValidateScript( @@ -863,7 +865,7 @@ function Add-ODItem [Parameter(Mandatory=$true)] [string]$LocalFile="" ) - if($ElementId -and $Path){throw '"-ElementId" and "-Path"Cannot coexist';break} + if($ElementId -and $Path){throw '"-ElementId" and "-Path"Cannot coexist';break}elseif(!$ElementId){$path='/'} $rURI=Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId getweb -method put -accesstoken $accesstoken -ResourceId $ResourceId -localfile $LocalFile -additem } @@ -1056,6 +1058,7 @@ function Move-ODItem [string]$ElementId="", [string]$DriveId="", [string]$TargetPath="", + [string]$Targetid="", [string]$NewName="" ) if (($ElementId+$Path) -eq "") @@ -1064,7 +1067,7 @@ function Move-ODItem } else { - if (($TargetPath+$NewName) -eq "") + if (($TargetPath+$NewName+$Targetid) -eq "") { write-error("TargetPath nor NewName is set") } @@ -1081,11 +1084,16 @@ function Move-ODItem } if (!$TargetPath -eq "") { - $rTURI=Format-ODPathorIdString -path $TargetPath -DriveId $DriveId + $rTURI=Format-ODPathorIdString -path $TargetPath -DriveId $DriveId #[System.Web.HttpUtility]::UrlEncode( $rTURI=$rTURI -replace ':$' $body=$body+'"parentReference" : {"path": "'+$rTURI+'"}' } + if (!$Targetid -eq "") + { + $body=$body+'"parentReference" : {"id": "'+$Targetid+'"}' + } $body=$body+'}' + $body $rURI=(Format-ODPathorIdString -path $Path -ElementId $ElementId -DriveId $DriveId).TrimEnd(':') return Get-ODWebContent -AccessToken $AccessToken -ResourceId $ResourceId -Method PATCH -rURI $rURI -Body $body } @@ -1254,6 +1262,8 @@ if (!($Authentication)){$Global:Authentication = New-Object PSObject} do{ $ODRootURI=Get-ODRootUri -ResourceId $ResourceId if($uri -match '^http') {$ruri1=$uri}elseif($additem){ + $spacer="" + if ($ElementId -ne "") {$spacer=":"} $rURI1=(($ODRootURI+$rURI).TrimEnd(":")+$spacer+"/"+[System.IO.Path]::GetFileName($File[0])+$File[1]).Replace("/root/","/root:/") }else{$ruri1=($ODRootURI+$rURI)} if($messq){remove-variable messq -force}