Public/Get-VBNextcloudFiles.ps1
|
# ============================================================ # FUNCTION : Get-VBNextcloudFiles # MODULE : VB.NextCloud # VERSION : 1.3.0 # CHANGED : 14-04-2026 -- Standards compliance fixes # AUTHOR : Vibhu Bhatnagar # PURPOSE : Lists files and folders in a Nextcloud directory via WebDAV PROPFIND # ENCODING : UTF-8 with BOM # ============================================================ function Get-VBNextcloudFiles { <# .SYNOPSIS Lists files and folders in a Nextcloud directory via WebDAV PROPFIND. .DESCRIPTION Get-VBNextcloudFiles queries a Nextcloud server using the WebDAV PROPFIND method to retrieve metadata for all items in a specified folder. Returns structured objects for each item including name, path, type, size, and last modified date. TLS 1.2 is enforced. The folder itself is excluded from the results so only its direct children are returned. .PARAMETER BaseUrl Base URL of the Nextcloud instance, e.g. 'https://cloud.example.com'. .PARAMETER Credential PSCredential object containing the Nextcloud username and password. .PARAMETER FolderPath Remote folder path to list, e.g. 'Vibhu/Reports'. Defaults to the WebDAV root. .PARAMETER WebDAVPath WebDAV endpoint path appended to BaseUrl. Defaults to 'remote.php/webdav'. .EXAMPLE Get-VBNextcloudFiles -BaseUrl 'https://cloud.example.com' -Credential (Get-Credential) Lists all items in the WebDAV root folder. .EXAMPLE Get-VBNextcloudFiles -BaseUrl 'https://cloud.example.com' ` -Credential $cred -FolderPath 'Vibhu/Reports' Lists all items in the Vibhu/Reports folder. .EXAMPLE Get-VBNextcloudFiles -BaseUrl 'https://cloud.example.com' -Credential $cred ` -FolderPath 'Vibhu/Reports' | Where-Object { -not $_.IsFolder } | Select-Object Name, Size, LastModified Returns only files (not subfolders) from the specified path. .OUTPUTS PSCustomObject Returns an object per item with: - Name : Display name of the item - Path : Full WebDAV href path - IsFolder : Boolean -- $true if the item is a folder - Size : File size in bytes ($null for folders) - LastModified : Last modified date string from the server - Status : 'Success' or 'Failed' - Error : Error message (only present on failure) .NOTES Version : 1.3.0 Module : VB.NextCloud Author : Vibhu Bhatnagar Requirements: - PowerShell 5.1 or higher - Network access to the Nextcloud instance - Valid Nextcloud credentials with read access to the target folder #> [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$BaseUrl, [Parameter(Mandatory)] [PSCredential]$Credential, [string]$FolderPath = '', [ValidateNotNullOrEmpty()] [string]$WebDAVPath = 'remote.php/webdav' ) process { try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $webDavUrl = '{0}/{1}' -f $BaseUrl.TrimEnd('/'), $WebDAVPath.Trim('/') $targetPath = $FolderPath.Trim('/').Replace('\', '/') $listUrl = if ($targetPath) { '{0}/{1}' -f $webDavUrl, $targetPath } else { $webDavUrl } Write-Verbose "Listing Nextcloud folder: $listUrl" $propfindBody = @' <?xml version="1.0"?> <d:propfind xmlns:d="DAV:"> <d:prop> <d:displayname/> <d:getcontentlength/> <d:getlastmodified/> <d:resourcetype/> </d:prop> </d:propfind> '@ $headers = @{ 'Content-Type' = 'application/xml' 'Depth' = '1' } $response = Invoke-WebRequest -Uri $listUrl -Method 'PROPFIND' -Body $propfindBody ` -Headers $headers -Credential $Credential -UseBasicParsing -ErrorAction Stop $xml = [xml]$response.Content $collectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') foreach ($item in $xml.multistatus.response) { # Normalise the href for comparison -- strip trailing slash $itemHref = $item.href.TrimEnd('/') # Build the expected self-href for the requested folder to skip it $selfHref = if ($targetPath) { ('/{0}/{1}' -f $WebDAVPath.Trim('/'), $targetPath).TrimEnd('/') } else { ('/{0}' -f $WebDAVPath.Trim('/')).TrimEnd('/') } if ($itemHref -eq $selfHref) { continue } $isFolder = $null -ne $item.propstat.prop.resourcetype.collection Write-Debug "Found item: $($item.propstat.prop.displayname) (IsFolder=$isFolder)" [PSCustomObject]@{ ComputerName = $env:COMPUTERNAME Name = $item.propstat.prop.displayname Path = $item.href IsFolder = $isFolder Size = if ($isFolder) { $null } else { [long]$item.propstat.prop.getcontentlength } LastModified = $item.propstat.prop.getlastmodified CollectionTime = $collectionTime Status = 'Success' } } } catch { Write-Error -Message $_.Exception.Message -ErrorAction Continue [PSCustomObject]@{ ComputerName = $env:COMPUTERNAME Name = $null Path = $FolderPath IsFolder = $null Size = $null LastModified = $null Error = $_.Exception.Message Status = 'Failed' CollectionTime = (Get-Date).ToString('dd-MM-yyyy HH:mm:ss') } } } } |