WebAppStorage.psm1
#region Functions #region Get-WebAppItem function Get-WebAppItem { param ( [Parameter()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL ) begin { # Set the User Agent string $userAgent = "powershell/1.0" # Extract the plain text value of the password [pscredential]$creds = New-Object System.Management.Automation.PSCredential ($userName, $Password) $pass = $creds.GetNetworkCredential().Password # Create the Base64 value for authentication $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $pass))) # Sanize DeploymentURL - Remove trailing / if($DeploymentURL.EndsWith("/")) { $DeploymentURL = $DeploymentURL.Substring(0, $DeploymentURL.Length - 1) } } process { # Set the URI $uri = $DeploymentURL + "/api/vfs/" + $Path # If the user has requested a directory, remove the trailing / if($uri.EndsWith('/')) { $uri = $uri.Substring(0, $uri.Length - 1) } # Transform the uri in order to get the items of the parent directory $index = $uri.LastIndexOf('/') $name = $uri.Substring($index + 1, $uri.Length - $index - 1) $uri = $uri.Substring(0, $index + 1) # Submit the request try { $data = Invoke-RestMethod -Uri $uri ` -Headers @{Authorization=("Basic {0}" -f $base64)} ` -UserAgent $userAgent ` -Method Get ` -ErrorAction Stop } catch { Write-Error ("Failed to get the item from WebApp. " + $_.Exception.Message) } $data | ForEach-Object{ $relPath = $_.href.replace($DeploymentURL, "") $relPath = $relPath.Substring(8, $relPath.Length - 8) if($relPath.StartsWith("/")) { $relPath = $relPath.Substring(1, $relPath.Length - 1) } $_ | Add-Member -MemberType NoteProperty -Name RelPath -Value $relPath } Write-Output $data | Where-Object {$_.Name -eq $name} } end {} } #endregion #region Get-WebAppChildItem function Get-WebAppChildItem { param ( [Parameter()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL ) begin { # Set the User Agent string $userAgent = "powershell/1.0" # Extract the plain text value of the password [pscredential]$creds = New-Object System.Management.Automation.PSCredential ($userName, $Password) $pass = $creds.GetNetworkCredential().Password # Create the Base64 value for authentication $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $pass))) # Sanize DeploymentURL - Remove trailing / if($DeploymentURL.EndsWith("/")) { $DeploymentURL = $DeploymentURL.Substring(0, $DeploymentURL.Length - 1) } } process { # Set the URI $uri = $DeploymentURL + "/api/vfs/" + $Path # Add the trailing / to the Path if(-not $uri.EndsWith('/')) { $uri += "/" } # Get the item to remove try { $item = Get-WebAppItem -Username $Username ` -Password $Password ` -Path $Path ` -DeploymentURL $DeploymentURL ` -ErrorAction Stop } catch { Write-Error "Failed to locate the item to be listed." return } # Check if the item is a directory or not if($item.mime -ne "inode/directory") { Write-Output $item return } # Submit the request try { $data = Invoke-RestMethod -Uri $uri ` -Headers @{Authorization=("Basic {0}" -f $base64)} ` -UserAgent $userAgent ` -Method Get ` -ErrorAction Stop } catch { Write-Error ("Failed to get the list of files/folders from WebApp. " + $_.Exception.Message) } $data | ForEach-Object{ $relPath = $_.href.replace($DeploymentURL, "") $relPath = $relPath.Substring(8, $relPath.Length - 8) if($relPath.StartsWith("/")) { $relPath = $relPath.Substring(1, $relPath.Length - 1) } $_ | Add-Member -MemberType NoteProperty -Name RelPath -Value $relPath } Write-Output $data } end {} } #endregion #region Download-WebAppFile function Download-WebAppFile { param ( [Parameter()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL, [Parameter(Mandatory = $false)] [string]$DestinationPath ) begin { # Set the User Agent string $userAgent = "powershell/1.0" # Extract the plain text value of the password [pscredential]$creds = New-Object System.Management.Automation.PSCredential ($userName, $Password) $pass = $creds.GetNetworkCredential().Password # Create the Base64 value for authentication $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $pass))) # Validate if DestinationPath exists try { $dpath = Resolve-Path -Path $DestinationPath -ErrorAction Stop #TODO: Check if the path resolves to a file } catch { throw "Could not resolve the DestinationPath." } # Sanize DeploymentURL - Remove trailing / if($DeploymentURL.EndsWith("/")) { $DeploymentURL = $DeploymentURL.Substring(0, $DeploymentURL.Length - 1) } } process { # Set the URI $uri = $DeploymentURL + "/api/vfs/" + $Path # Try to get the file try { $file = Get-WebAppChildItem -Username $Username ` -Password $Password ` -Path $Path ` -DeploymentURL $DeploymentURL ` -ErrorAction Stop } catch { Write-Error ("Failed to get the file from WebApp. " + $_.Exception.Message) return } # Check if the file is a directory if($file.mime -eq "inode/directory") { Write-Error ("The provided path resolves to a directory.") return } # Submit the request try { $data = Invoke-RestMethod -Uri $uri ` -Headers @{Authorization=("Basic {0}" -f $base64)} ` -UserAgent $userAgent ` -Method Get } catch { Write-Error ("Failed to download the file from WebApp. " + $_.Exception.Message) } Write-Output $data } end {} } #endregion #region Upload-WebAppFile function Upload-WebAppFile { param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DestinationPath ) begin { # Set the User Agent string $userAgent = "powershell/1.0" # Extract the plain text value of the password [pscredential]$creds = New-Object System.Management.Automation.PSCredential ($userName, $Password) $pass = $creds.GetNetworkCredential().Password # Create the Base64 value for authentication $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $pass))) # Sanize DeploymentURL - Remove trailing / if($DeploymentURL.EndsWith("/")) { $DeploymentURL = $DeploymentURL.Substring(0, $DeploymentURL.Length - 1) } } process { # Set the URI $uri = $DeploymentURL + "/api/vfs/" + $DestinationPath # Verify that the source file exists try { $spath = (Resolve-Path -Path $Path -ErrorAction Stop).Path } catch { Write-Error "Failed to locate the file to upload." return } # Check if destination path is a directory or not if($DestinationPath.EndsWith('/')) { # We need to add the name of the file to the uri $fpath = (Resolve-Path $Path).Path $fitem = Get-Item -Path $fpath $uri += $fitem.Name } else { # Check if we are uploading to a folder and we're missing the trailing / try { $dpath2 = Get-WebAppItem -Username $Username ` -Password $Password ` -DeploymentURL $DeploymentURL ` -Path $DestinationPath ` -ErrorAction Stop if($dpath2.mime -eq "inode/directory") { # We need to add the name of the file to the uri $fpath = (Resolve-Path $Path).Path $fitem = Get-Item -Path $fpath $uri = $uri + "/" + $fitem.Name } } catch { # There is no directory with that name, continue upload } } # Create the request headers $headers = @{ 'Authorization' = "Basic {0}" -f $base64 'If-Match' = "*" } # Submit the request try { $data = Invoke-RestMethod -Uri $uri ` -Headers $headers ` -UserAgent $userAgent ` -Method Put ` -InFile $spath ` -ErrorAction Stop } catch { Write-Error ("Failed to upload the file to the WebApp. " + $_.Exception.Message) } $data } end {} } #endregion #region Upload-WebAppDirectory function Upload-WebAppDirectory { [cmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DestinationPath ) # Test if Path exists try { $p = (Resolve-Path -Path $Path -ErrorAction Stop).Path } catch { Write-Error "Failed to located directory $Path" return } # Check if Path is a directory # TODO # Create a list of items to upload $items = Get-ChildItem -Path $p -Force # Create the directory structure $items | ForEach-Object{ # Get the full path to the directory $fpath = $_.FullName # Get the relative path to the root directory $rpath = $_.FullName.Substring($p.Length + 1, $_.FullName.Length - $p.Length - 1) # Form the destination path $drpath = $rpath.Replace('\', '/') # Get the path on the website if($drpath.Contains('/')) { $wdpath = $drpath.Substring(0, $drpath.LastIndexOf('/')) } else { $wdpath = $drpath } # Add the parent path from the function if($DestinationPath.EndsWith('/')) { $wdpath = $DestinationPath + $wdpath } else { $wdpath = $DestinationPath + '/' + $wdpath } if($_.PSIsContainer -eq $false) { # Processing files Write-Verbose "Processing file $rpath" # Form the path to the destination directory $wddpath = $wdpath.Substring(0, $wdpath.LastIndexOf('/')) if(-Not $wddpath.EndsWith('/')) { $wddpath += "/" } # Upload the file Upload-WebAppFile -Username $Username ` -Password $Password ` -DeploymentURL $DeploymentUrl ` -Path $_.FullName ` -DestinationPath $wddpath } else { # Processing directories Write-Verbose "Processing directory $rpath" # Add the trailing / $drpath += "/" # Create the directory on the website # No need to create the directory since it is created automatically if needed <# New-WebAppDirectory -Username $Username ` -Password $Password ` -DeploymentURL $DeploymentUrl ` -Name $_.Name ` -Path $wdpath #> # Process the contents of the directory Upload-WebAppDirectory -Path $_.FullName -DestinationPath $wdpath } } } #endregion #region Remove-WebAppItem function Remove-WebAppItem { param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL, [Parameter(Mandatory = $false)] [switch]$Recurse = $false ) begin { # Set the User Agent string $userAgent = "powershell/1.0" # Extract the plain text value of the password [pscredential]$creds = New-Object System.Management.Automation.PSCredential ($userName, $Password) $pass = $creds.GetNetworkCredential().Password # Create the Base64 value for authentication $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $pass))) # Sanize DeploymentURL - Remove trailing / if($DeploymentURL.EndsWith("/")) { $DeploymentURL = $DeploymentURL.Substring(0, $DeploymentURL.Length - 1) } } process { # Set the URI $uri = $DeploymentURL + "/api/vfs/" + $Path # Create the request headers $headers = @{ 'Authorization' = "Basic {0}" -f $base64 'If-Match' = "*" } # Get the item to remove try { $item = Get-WebAppItem -Username $Username ` -Password $Password ` -Path $Path ` -DeploymentURL $DeploymentURL ` -ErrorAction Stop } catch { Write-Error "Failed to locate the item to be removed." return } # Check if the item is a directory if($item.mime -eq "inode/directory") { # Get the number of items in it $initems = @(Get-WebAppChildItem -Username $Username ` -Password $Password ` -DeploymentURL $DeploymentURL ` -Path $item.RelPath) if($initems.Count -gt 0) { if($Recurse -eq $false) { Write-Error "Directory not empty." return } else { # Remove the files and folders foreach($i in $initems) { # Remove the file if($i.mime -ne "inode/directory") { try { Remove-WebAppItem -Username $Username ` -Password $Password ` -DeploymentURL $DeploymentURL ` -Path ("/" + $i.RelPath) ` -ErrorAction Stop } catch { Write-Error "Failed to remove item $($i.RelPath)." } } else { # Recursively remove the subdirectory try { Remove-WebAppItem -Username $Username ` -Password $Password ` -DeploymentURL $DeploymentURL ` -Path ("/" + $i.RelPath) ` -Recurse ` -ErrorAction Stop } catch { Write-Error "Failed to remove item $($i.RelPath)." } } } } } } # Submit the request try { $data = Invoke-RestMethod -Uri $uri ` -Headers $headers ` -UserAgent $userAgent ` -Method Delete ` -ErrorAction Stop } catch { Write-Error ("Failed to delete the file from the WebApp. " + $_.Exception.Message) } } end {} } #endregion #region New-WebAppDirectory function New-WebAppDirectory { param ( [Parameter()] [ValidateNotNullOrEmpty()] [string]$Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Username, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [securestring]$Password, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$DeploymentURL, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$Name ) begin { # Set the User Agent string $userAgent = "powershell/1.0" # Extract the plain text value of the password [pscredential]$creds = New-Object System.Management.Automation.PSCredential ($userName, $Password) $pass = $creds.GetNetworkCredential().Password # Create the Base64 value for authentication $base64 = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username, $pass))) # Sanize DeploymentURL - Remove trailing / if($DeploymentURL.EndsWith("/")) { $DeploymentURL = $DeploymentURL.Substring(0, $DeploymentURL.Length - 1) } } process { # Set the URI $uri = $DeploymentURL + "/api/vfs/" + $Path + "/" + $Name + "/" # Verify that the path to create the directory in exists and is a directory #TODO # Create the request headers $headers = @{ 'Authorization' = "Basic {0}" -f $base64 'If-Match' = "*" } # Submit the request try { $data = Invoke-RestMethod -Uri $uri ` -Headers $headers ` -UserAgent $userAgent ` -Method Put ` -ErrorAction Stop } catch { Write-Error ("Failed to create the directory in the WebApp. " + $_.Exception.Message) } } end {} } #endregion #endregion #region Exports Export-ModuleMember -Function "Get-WebAppItem" Export-ModuleMember -Function "Get-WebAppChildItem" Export-ModuleMember -Function "Download-WebAppFile" Export-ModuleMember -Function "Upload-WebAppFile" Export-ModuleMember -Function "Upload-WebAppDirectory" Export-ModuleMember -Function "Remove-WebAppItem" Export-ModuleMember -Function "New-WebAppDirectory" #endregion |