11<#
22. SYNOPSIS
3- Uploads a file to Google Drive in a specified folder.
3+ Uploads a file to Google Drive in a specified folder.
44
55. DESCRIPTION
6- Uploads a file to Google Drive, places it in the "Open Live Writer" subfolder,
7- preserves the original filename.
6+ Uploads a file to Google Drive, places it in the "Open Live Writer" subfolder,
7+ preserves the original filename.
88
99. PARAMETER FilePath
10- The local path to the file to upload.
10+ The local path to the file to upload.
1111
1212. PARAMETER FileName
13- Optional custom name for the file. If not specified, uses the original filename.
13+ Optional custom name for the file. If not specified, uses the original filename.
1414
1515. PARAMETER Force
16- If specified, will overwrite an existing file with the same name in the target folder.
17- If not specified and the file already exists, it will return the existing file's metadata.
16+ If specified, will overwrite an existing file with the same name in the target folder.
17+ If not specified and the file already exists, it will return the existing file's metadata.
1818
1919. EXAMPLE
20- Add-GoogleDriveFile -FilePath "C:\images\photo.jpg"
20+ Add-GoogleDriveFile -FilePath "C:\images\photo.jpg"
2121#>
2222function Add-GoogleDriveFile {
23- [CmdletBinding ()]
24- param (
25- [Parameter (Mandatory = $true )]
26- [ValidateScript ({ Test-Path - Path $_ - PathType Leaf })]
27- [string ]$FilePath ,
23+ [CmdletBinding ()]
24+ param (
25+ [Parameter (Mandatory = $true )]
26+ [ValidateScript ({ Test-Path - Path $_ - PathType Leaf })]
27+ [string ]$FilePath ,
2828
29- [Parameter ()]
30- [string ]$FileName ,
29+ [Parameter ()]
30+ [string ]$FileName ,
3131
32- [Parameter ()]
33- [string ]$TargetFolderName = " Open Live Writer" ,
32+ [Parameter ()]
33+ [string ]$TargetFolderName = " Open Live Writer" ,
3434
35- [Parameter ()]
36- [switch ]$Force
37- )
35+ [Parameter ()]
36+ [switch ]$Force
37+ )
3838
39- $sourceItem = Get-Item (Resolve-Path $FilePath )
40- Write-Verbose " Add-GoogleDriveFile: Uploading file: $ ( $sourceItem.FullName ) to Google Drive"
39+ $sourceItem = Get-Item (Resolve-Path $FilePath )
40+ Write-Verbose " Add-GoogleDriveFile: Uploading file: $ ( $sourceItem.FullName ) to Google Drive"
4141
42- if (-not $FileName ) {
43- $FileName = $sourceItem.Name
42+ if (-not $FileName ) {
43+ $FileName = $sourceItem.Name
44+ }
45+
46+ # First, find or create the upload folder in Google Drive
47+ Write-Verbose " Add-GoogleDriveFile: Verifying target folder: $TargetFolderName "
48+ $folder = Get-GoogleDriveItems - ResultType " Folders" - Title $TargetFolderName
49+
50+ if (-not $folder ) {
51+ # Create the folder if it doesn't exist
52+ Write-Verbose " Add-GoogleDriveFile: Folder '$TargetFolderName ' not found. Creating new folder."
53+ $folder = Add-GoogleDriveFolder - Name $TargetFolderName
54+ }
55+ else {
56+ # Get the first folder if multiple exist
57+ Write-Verbose " Add-GoogleDriveFile: Folder '$TargetFolderName ' found."
58+ $folder = $folder | Select-Object - First 1
59+ }
60+
61+ # Determine if the file already exists in the target folder
62+ Write-Verbose " Add-GoogleDriveFile: Checking if file '$FileName ' already exists in folder '$TargetFolderName '"
63+ $existingFile = Get-GoogleDriveItems - ResultType " Files" - Title $FileName - ParentId $folder.id
64+ if ($existingFile ) {
65+ if (-not $Force ) {
66+ # use existing file
67+ return New-GoogleDriveMetadata - id $existingFile.id - name $existingFile.name
4468 }
69+ # address multiple file issue
70+ # todo: evaluate additional meta-data of the file to ensure it's not deleted
71+ $existingFile = $existingFile | Select-Object - First 1
72+ }
4573
46- # First, find or create the upload folder in Google Drive
47- Write-Verbose " Add-GoogleDriveFile: Verifying target folder: $TargetFolderName "
48- $folder = Get-GoogleDriveItems - ResultType " Folders" - Title $TargetFolderName
49-
50- if (-not $folder ) {
51- # Create the folder if it doesn't exist
52- Write-Verbose " Add-GoogleDriveFile: Folder '$TargetFolderName ' not found. Creating new folder."
53- $folder = Add-GoogleDriveFolder - Name $TargetFolderName
54- } else {
55- # Get the first folder if multiple exist
56- Write-Verbose " Add-GoogleDriveFile: Folder '$TargetFolderName ' found."
57- $folder = $folder | Select-Object - First 1
58- }
59-
60- # Determine if the file already exists in the target folder
61- Write-Verbose " Add-GoogleDriveFile: Checking if file '$FileName ' already exists in folder '$TargetFolderName '"
62- $existingFile = Get-GoogleDriveItems - ResultType " Files" - Title $FileName - ParentId $folder.id
74+ $sourceMime = Get-ImageMimeType - Extension $sourceItem.Extension
75+
76+ # Prepare metadata for the file
77+ $metadata = @ {
78+ name = $FileName
79+ parents = @ ($folder.id )
80+ } | ConvertTo-Json - Compress
81+
82+ $fileContent = [System.IO.File ]::ReadAllBytes($sourceItem.FullName )
83+ $fileContentBase64 = [Convert ]::ToBase64String($fileContent )
84+
85+ # Create multipart body
86+ $boundary = " boundary_" + [System.Guid ]::NewGuid().ToString()
87+
88+ $body = @ (
89+
90+ # Metadata part
91+ " --$boundary "
92+ " Content-Type: application/json; charset=UTF-8"
93+ " "
94+ $metadata
95+ " --$boundary "
96+
97+ # File content part
98+ " Content-Type: $sourceMime "
99+ " Content-Transfer-Encoding: base64"
100+ " "
101+ $fileContentBase64
102+ " --$boundary --"
103+ ) -join " `r`n "
104+
105+ $additionalHeaders = @ {
106+ " Content-Type" = " multipart/related; boundary=$boundary "
107+ }
108+
109+ try {
110+
63111 if ($existingFile ) {
64- if (-not $Force ) {
65- # use existing file
66- return New-GoogleDriveMetadata - id $existingFile.id - name $existingFile.name
67- }
68- # address multiple file issue
69- # todo: evaluate additional meta-data of the file to ensure it's not deleted
70- $existingFile = $existingFile | Select-Object - First 1
71- }
112+ # If the file exists and Force is specified, update it
113+ $uri = " https://www.googleapis.com/upload/drive/v3/files/$ ( $existingFile.id ) ?uploadType=media"
114+ $method = " PATCH"
72115
73- $sourceMime = Get-ImageMimeType - Extension $sourceItem.Extension
74-
75- # Prepare metadata for the file
76- $metadata = @ {
77- name = $FileName
78- parents = @ ($folder.id )
79- } | ConvertTo-Json - Compress
80-
81- $fileContent = [System.IO.File ]::ReadAllBytes($sourceItem.FullName )
82- $fileContentBase64 = [Convert ]::ToBase64String($fileContent )
83-
84- # Create multipart body
85- $boundary = " boundary_" + [System.Guid ]::NewGuid().ToString()
86-
87- $body = @ (
88-
89- # Metadata part
90- " --$boundary "
91- " Content-Type: application/json; charset=UTF-8"
92- " "
93- $metadata
94- " --$boundary "
95-
96- # File content part
97- " Content-Type: $sourceMime "
98- " Content-Transfer-Encoding: base64"
99- " "
100- $fileContentBase64
101- " --$boundary --"
102- ) -join " `r`n "
103-
104- $additionalHeaders = @ {
105- " Content-Type" = " multipart/related; boundary=$boundary "
106- }
116+ " Add-GoogleDriveFile: $Method $uri " | Write-Verbose
107117
108- try {
109-
110- if ($existingFile ) {
111- # If the file exists and Force is specified, update it
112- $uri = " https://www.googleapis.com/upload/drive/v3/files/$ ( $existingFile.id ) ?uploadType=media"
113- $method = " PATCH"
114-
115- " Add-GoogleDriveFile: $Method $uri " | Write-Verbose
116-
117- $uploadResult = Invoke-GApi - uri $uri - InFile $sourceItem.FullName - method $method - ContentType $sourceMime - Verbose:$false
118- }
119- else {
120- $uri = " https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
121- $method = " POST"
122- " Add-GoogleDriveFile: $Method $uri " | Write-Verbose
123-
124- $uploadResult = Invoke-GApi - uri $uri - body $body - method $method - ContentType " multipart/related; boundary=$boundary " - AdditionalHeaders $additionalHeaders - Verbose:$false
125- }
126-
127- # Return the file information with public URL
128- return New-GoogleDriveMetadata - id $uploadResult.id - name $uploadResult.name
118+ $uploadResult = Invoke-GApi - uri $uri - InFile $sourceItem.FullName - method $method - ContentType $sourceMime - Verbose:$false
129119 }
130- catch {
131- Write-Error " Failed to upload file to Google Drive: $ ( $_.Exception.Message ) . $ ( $_.ErrorDetails | ConvertTo-Json - Depth 10 ) " - ErrorAction Stop
120+ else {
121+ $uri = " https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"
122+ $method = " POST"
123+ " Add-GoogleDriveFile: $Method $uri " | Write-Verbose
124+
125+ $uploadResult = Invoke-GApi - uri $uri - body $body - method $method - ContentType " multipart/related; boundary=$boundary " - AdditionalHeaders $additionalHeaders - Verbose:$false
132126 }
127+
128+ # Return the file information with public URL
129+ return New-GoogleDriveMetadata - id $uploadResult.id - name $uploadResult.name
130+ }
131+ catch {
132+ Write-Error " Failed to upload file to Google Drive: $ ( $_.Exception.Message ) . $ ( $_.ErrorDetails | ConvertTo-Json - Depth 10 ) " - ErrorAction Stop
133+ }
133134}
134135
135136<#
@@ -146,45 +147,46 @@ The file extension (including the dot).
146147Get-ImageMimeType -Extension ".jpg"
147148#>
148149function Get-ImageMimeType {
149- [CmdletBinding ()]
150- param (
151- [Parameter (Mandatory = $true )]
152- [string ]$Extension
153- )
154-
155- $mimeTypes = @ {
156- ' .jpg' = ' image/jpeg'
157- ' .jpeg' = ' image/jpeg'
158- ' .png' = ' image/png'
159- ' .gif' = ' image/gif'
160- ' .bmp' = ' image/bmp'
161- ' .webp' = ' image/webp'
162- ' .svg' = ' image/svg+xml'
163- ' .ico' = ' image/x-icon'
164- ' .tiff' = ' image/tiff'
165- ' .tif' = ' image/tiff'
166- }
167-
168- $normalizedExtension = $Extension.ToLower ()
150+ [CmdletBinding ()]
151+ param (
152+ [Parameter (Mandatory = $true )]
153+ [string ]$Extension
154+ )
155+
156+ $mimeTypes = @ {
157+ ' .jpg' = ' image/jpeg'
158+ ' .jpeg' = ' image/jpeg'
159+ ' .png' = ' image/png'
160+ ' .gif' = ' image/gif'
161+ ' .bmp' = ' image/bmp'
162+ ' .webp' = ' image/webp'
163+ ' .svg' = ' image/svg+xml'
164+ ' .ico' = ' image/x-icon'
165+ ' .tiff' = ' image/tiff'
166+ ' .tif' = ' image/tiff'
167+ }
168+
169+ $normalizedExtension = $Extension.ToLower ()
169170
170- if ($mimeTypes.ContainsKey ($normalizedExtension )) {
171- return $mimeTypes [$normalizedExtension ]
172- } else {
173- return ' application/octet-stream'
174- }
171+ if ($mimeTypes.ContainsKey ($normalizedExtension )) {
172+ return $mimeTypes [$normalizedExtension ]
173+ }
174+ else {
175+ return ' application/octet-stream'
176+ }
175177}
176178
177179function New-GoogleDriveMetadata {
178- param (
179- [string ]$id ,
180- [string ]$name
181- )
182- $publicUrl = " https://lh3.googleusercontent.com/d/$id "
180+ param (
181+ [string ]$id ,
182+ [string ]$name
183+ )
184+ $publicUrl = " https://lh3.googleusercontent.com/d/$id "
183185
184- return [PSCustomObject ]@ {
185- Id = $id
186- Name = $name
187- PublicUrl = $publicUrl
188- DriveUrl = " https://drive.google.com/file/d/$id /view"
189- }
186+ return [PSCustomObject ]@ {
187+ Id = $id
188+ Name = $name
189+ PublicUrl = $publicUrl
190+ DriveUrl = " https://drive.google.com/file/d/$id /view"
191+ }
190192}
0 commit comments