onedriveShareLinkDownload.psm1
function Save-odShareItem{ <# .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 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 #> PAram( [Parameter(Mandatory=$true,Position=0,helpmessage="Personal onedrive share link.Example:'https://1drv.ms/u/s!xxx' or 'https://onedrive.live.com/redir?xxx'")] [string]$uri, [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" 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}} $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} } 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 }}} function Runspace0 { [CmdletBinding()] param( [Parameter(ValueFromPipeline = $true)] [string[]]$ScriptBlock, [switch]$info,[int]$throttleLimit = 8) #线程限制 begin{ $SessionState = [system.management.automation.runspaces.initialsessionstate]::CreateDefault() $Pool = [runspacefactory]::CreateRunspacePool(1, $throttleLimit, $SessionState, $Host) $Pool.Open() $x=0 $start=@' param($id) $ErrorActionPreference='SilentlyContinue'; $WarningPreference='SilentlyContinue'; $ProgressPreference='SilentlyContinue'; '@ $end=@' ; [PScustomobject]@{id=$id;data=$code} '@ $handles=@() $threads=@() } process{ foreach($scriptblocks in $scriptblock){ $ScriptBlocks=$ScriptBlocks -replace '(?s)([^\n]+)$','$code=$1' $sc=[scriptblock]::create(($start+$scriptblocks+$end)) $powershell = [powershell]::Create().AddScript($sc).AddArgument($x) $powershell.RunspacePool = $Pool $powershell|add-member 'async' ($powershell.BeginInvoke()) $handles +=$powershell $x++ } } end{ return $handles|%{$_.EndInvoke($_.async)} $handles.runspacepool.Dispose() } } #Export-ModuleMember -function Save-odshareitem |